From 6b396e7c4a073af639c55cd0b7dbfd8dd99a39a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Pablo=20Caballero?= Date: Fri, 23 Jul 2021 17:04:39 -0300 Subject: [PATCH 1/2] Fixed issue #473. Enum works properly now --- src/js/Node.js | 7 +- test/Node.test.js | 187 ++++++++++++++++++++++++++++++++++++++++++ test/test_enum.html | 62 ++++++++++++++ test/test_enum_2.html | 123 +++++++++++++++++++++++++++ 4 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 test/test_enum.html create mode 100644 test/test_enum_2.html diff --git a/src/js/Node.js b/src/js/Node.js index aabf1ee01..73957e59e 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -4482,7 +4482,12 @@ Node._findSchema = (topLevelSchema, schemaRefs, path, currentSchema = topLevelSc if (schemaUrl in schemaRefs) { const referencedSchema = schemaRefs[schemaUrl] const reference = { $ref: '#/'.concat(relativePath) } - return Node._findSchema(referencedSchema, schemaRefs, nextPath, reference) + let auxNextPath = [] + auxNextPath.push(nextKey) + if(nextPath.length > 0) { + auxNextPath.push(...nextPath) + } + return Node._findSchema(referencedSchema, schemaRefs, auxNextPath, reference) } else { throw Error(`Unable to resolve reference ${ref}`) } diff --git a/test/Node.test.js b/test/Node.test.js index 70b43298f..26957a233 100644 --- a/test/Node.test.js +++ b/test/Node.test.js @@ -77,6 +77,69 @@ describe('Node', () => { ) }) + it('should find referenced schema within multi-level object properties', () => { + const schema = { + type: 'object', + properties: { + aProperty: { + "$ref": "second_schema#/definitions/some_def" + } + } + } + const schemaRefs = { + second_schema: { + definitions: { + some_def: { + type: 'object', + properties: { + enumProp: { + enum: [1, 2, 3] + } + } + } + } + } + } + let path = ['aProperty', 'enumProp'] + let expected_schema = { + enum: [1, 2, 3] + } + assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expected_schema) + }) + + it('should find array referenced schema within multi-level object properties', () => { + const schema = { + type: 'object', + properties: { + aProperty: { + type: "array", + items: { + "$ref": "second_schema#/definitions/some_def" + } + } + } + } + const schemaRefs = { + "second_schema": { + "definitions": { + "some_def": { + type: 'object', + properties: { + enumProp: { + enum: [1, 2, 3] + } + } + } + } + } + } + let path = ['aProperty', 0, 'enumProp'] + let expected_schema = { + enum: [1, 2, 3] + } + assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expected_schema) + }) + it('should return null for path that has no schema', () => { const schema = { type: 'object', @@ -152,6 +215,121 @@ describe('Node', () => { const path = ['foo'] assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema) }) + + it('should find a referenced schema property', () => { + const schema = { + type: 'object', + properties: { + foo: { + $ref: 'foo' + } + } + } + const fooSchema = { + type: 'object', + properties: { + levelTwo: { + type: 'string' + } + } + } + const path = ['foo', 'levelTwo'] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.properties.levelTwo) + }) + + it('should find a referenced schema definition', () => { + const schema = { + type: 'object', + properties: { + foo: { + type: "array", + items: { + "$ref": "foo#/definitions/some_def" + } + } + } + } + const fooSchema = { + "definitions": { + "some_def": { + type: 'object', + properties: { + propA: { + type: 'string' + }, + propB: { + type: 'string' + } + } + } + } + } + const path = ['foo', 0] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.definitions.some_def) + }) + + it('should find a referenced schema definition 2', () => { + const schema = { + type: 'object', + properties: { + foo: { + type: "array", + items: { + "$ref": "foo#/definitions/some_def" + } + } + } + } + const fooSchema = { + definitions: { + some_def: { + type: 'object', + properties: { + propA: { + type: 'string' + }, + propB: { + type: 'string' + } + } + } + } + } + const path = ['foo', 0, 'propA'] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.definitions.some_def.properties.propA) + }) + + it('should find a referenced schema definition 3', () => { + const schema = { + type: 'object', + properties: { + foo: { + type: "array", + items: { + "$ref": "foo#/definitions/some_def" + } + } + } + } + const fooSchema = { + "definitions": { + "some_def": { + type: 'object', + properties: { + propA: { + type: 'object', + properties: { + propA1: { type: 'boolean' } + } + }, + propB: { type: 'string' } + } + } + } + } + const path = ['foo', 0, 'propA', 'propA1'] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.definitions.some_def.properties.propA.properties.propA1) + }) }) describe('with $ref to internal definition', () => { @@ -423,4 +601,13 @@ describe('Node', () => { }) }) }) + describe('_findEnum', () => { + it('should find enum', () => { + const schema = { + type: 'object', + enum: [1, 2, 3] + } + assert.strictEqual(Node._findEnum(schema), schema.enum) + }) + }) }) diff --git a/test/test_enum.html b/test/test_enum.html new file mode 100644 index 000000000..399f88d3b --- /dev/null +++ b/test/test_enum.html @@ -0,0 +1,62 @@ + + + + JSONEditor | template + enums + + + + + + + + +
+ + + + diff --git a/test/test_enum_2.html b/test/test_enum_2.html new file mode 100644 index 000000000..6f27f033f --- /dev/null +++ b/test/test_enum_2.html @@ -0,0 +1,123 @@ + + + + JSONEditor | template + enums + + + + + + + +

Demonstrates a template with JSON schema validation. To use: click the context menu of the first or second employee, click insert or append, click "Employee".

+

See github issue #473

+ +
+ + + + From 9b8a002cd5a9f8b7054aaa9637a84252850d768c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Pablo=20Caballero?= Date: Fri, 23 Jul 2021 17:14:52 -0300 Subject: [PATCH 2/2] Fixed issues with lint rules --- src/js/Node.js | 4 ++-- test/Node.test.js | 46 +++++++++++++++++++++++----------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/js/Node.js b/src/js/Node.js index 73957e59e..a8e82297a 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -4482,9 +4482,9 @@ Node._findSchema = (topLevelSchema, schemaRefs, path, currentSchema = topLevelSc if (schemaUrl in schemaRefs) { const referencedSchema = schemaRefs[schemaUrl] const reference = { $ref: '#/'.concat(relativePath) } - let auxNextPath = [] + const auxNextPath = [] auxNextPath.push(nextKey) - if(nextPath.length > 0) { + if (nextPath.length > 0) { auxNextPath.push(...nextPath) } return Node._findSchema(referencedSchema, schemaRefs, auxNextPath, reference) diff --git a/test/Node.test.js b/test/Node.test.js index 26957a233..181b6fbd9 100644 --- a/test/Node.test.js +++ b/test/Node.test.js @@ -82,7 +82,7 @@ describe('Node', () => { type: 'object', properties: { aProperty: { - "$ref": "second_schema#/definitions/some_def" + $ref: 'second_schema#/definitions/some_def' } } } @@ -100,11 +100,11 @@ describe('Node', () => { } } } - let path = ['aProperty', 'enumProp'] - let expected_schema = { + const path = ['aProperty', 'enumProp'] + const expectedSchema = { enum: [1, 2, 3] } - assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expected_schema) + assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expectedSchema) }) it('should find array referenced schema within multi-level object properties', () => { @@ -112,17 +112,17 @@ describe('Node', () => { type: 'object', properties: { aProperty: { - type: "array", + type: 'array', items: { - "$ref": "second_schema#/definitions/some_def" + $ref: 'second_schema#/definitions/some_def' } } } } const schemaRefs = { - "second_schema": { - "definitions": { - "some_def": { + second_schema: { + definitions: { + some_def: { type: 'object', properties: { enumProp: { @@ -133,11 +133,11 @@ describe('Node', () => { } } } - let path = ['aProperty', 0, 'enumProp'] - let expected_schema = { - enum: [1, 2, 3] + const path = ['aProperty', 0, 'enumProp'] + const expectedSchema = { + enum: [1, 2, 3] } - assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expected_schema) + assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expectedSchema) }) it('should return null for path that has no schema', () => { @@ -242,16 +242,16 @@ describe('Node', () => { type: 'object', properties: { foo: { - type: "array", + type: 'array', items: { - "$ref": "foo#/definitions/some_def" + $ref: 'foo#/definitions/some_def' } } } } const fooSchema = { - "definitions": { - "some_def": { + definitions: { + some_def: { type: 'object', properties: { propA: { @@ -273,9 +273,9 @@ describe('Node', () => { type: 'object', properties: { foo: { - type: "array", + type: 'array', items: { - "$ref": "foo#/definitions/some_def" + $ref: 'foo#/definitions/some_def' } } } @@ -304,16 +304,16 @@ describe('Node', () => { type: 'object', properties: { foo: { - type: "array", + type: 'array', items: { - "$ref": "foo#/definitions/some_def" + $ref: 'foo#/definitions/some_def' } } } } const fooSchema = { - "definitions": { - "some_def": { + definitions: { + some_def: { type: 'object', properties: { propA: {