Skip to content

Commit

Permalink
Fixed enum on referenced schemas (#1355)
Browse files Browse the repository at this point in the history
* Fixed issue #473. Enum works properly now

* Fixed issues with lint rules
  • Loading branch information
mpccolorado committed Jul 24, 2021
1 parent eab98fe commit 74e40d3
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/js/Node.js
Expand Up @@ -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)
const 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}`)
}
Expand Down
187 changes: 187 additions & 0 deletions test/Node.test.js
Expand Up @@ -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]
}
}
}
}
}
}
const path = ['aProperty', 'enumProp']
const expectedSchema = {
enum: [1, 2, 3]
}
assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expectedSchema)
})

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]
}
}
}
}
}
}
const path = ['aProperty', 0, 'enumProp']
const expectedSchema = {
enum: [1, 2, 3]
}
assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expectedSchema)
})

it('should return null for path that has no schema', () => {
const schema = {
type: 'object',
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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)
})
})
})
62 changes: 62 additions & 0 deletions test/test_enum.html
@@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<html>
<head>
<title>JSONEditor | template + enums</title>

<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
<script src="../dist/jsoneditor.js"></script>

<style type="text/css">
#jsoneditor {
width: 500px;
height: 700px;
background: white;
}

p {
width: 500px;
font-family: sans;
}
</style>
</head>
<body>

<div id="jsoneditor"></div>

<script>
var schema = {
"title": "Example Schema",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"enum": ["a", "b"]
},
"testObj": {
"type": "object",
"additionalProperties": {
"type": "string",
"enum": ["a", "b"]
},
}
},
"required": ["firstName"]
};


var json =
{
firstName: 'a',
testObj: {},
};

var options = {
schema: schema
};

// create the editor
var container = document.getElementById('jsoneditor');
var editor = new JSONEditor(container, options, json);
</script>
</body>
</html>

0 comments on commit 74e40d3

Please sign in to comment.