Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft 2019 09 #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var compare = require('json-schema-compare')
var isEqual = compare({
title: 'title 1',
type: ['object'],
uniqueItems: false,
uniqueItems: false, // false is same as undefined
dependencies: {
name: ['age', 'lastName']
},
Expand All @@ -37,6 +37,16 @@ var isEqual = compare({
console.log(isEqual) // => true
```

In the example above the name with `minLength: 0`, it is the same as all the all the following:
```json
{ properties: { name : { minLength: undefined } } }
{ properties: { name: {} } }
{ properties: { name: true } }
{ properties: { name: undefined } }
{ properties: {} }
{ }
```

Compare json schemas correctly.

- Ignores sort for arrays where sort does not matter, like required, enum, type, anyOf, oneOf, anyOf, dependencies (if array)
Expand Down
31 changes: 14 additions & 17 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ var keys = obj => isPlainObject(obj) || Array.isArray(obj) ? Object.keys(obj) :
var has = (obj, key) => obj.hasOwnProperty(key)
var stringArray = arr => sortBy(uniq(arr))
var undefEmpty = val => undef(val) || (Array.isArray(val) && val.length === 0)
var keyValEqual = (a, b, key, compare) => b && has(b, key) && a && has(a, key) && compare(a[key], b[key])
var undefAndZero = (a, b) => (undef(a) && b === 0) || (undef(b) && a === 0) || isEqual(a, b)
var falseUndefined = (a, b) => (undef(a) && b === false) || (undef(b) && a === false) || isEqual(a, b)
var emptySchema = schema => undef(schema) || isEqual(schema, {}) || schema === true
var emptyObjUndef = schema => undef(schema) || isEqual(schema, {})
var isSchema = val => undef(val) || isPlainObject(val) || val === true || val === false
var propOrFake = (a, key) => undef(a) ? undefined : a[key]

function undefArrayEqual(a, b) {
if (undefEmpty(a) && undefEmpty(b)) {
Expand All @@ -37,25 +36,24 @@ function unsortedNormalizedArray(a, b) {

function schemaGroup(a, b, key, compare) {
var allProps = uniq(keys(a).concat(keys(b)))
if (emptyObjUndef(a) && emptyObjUndef(b)) {
if (emptySchema(a) && emptySchema(b)) {
return true
} else if (emptyObjUndef(a) && keys(b).length) {
return false
} else if (emptyObjUndef(b) && keys(a).length) {
return false
}

return allProps.every(function(key) {
var aVal = a[key]
var bVal = b[key]
var aVal = propOrFake(a, key)
var bVal = propOrFake(b, key)

// TODO, remove when no longer support dependencies
if (Array.isArray(aVal) && Array.isArray(bVal)) {
return isEqual(stringArray(a), stringArray(b))
} else if (Array.isArray(aVal) && !Array.isArray(bVal)) {
return false
} else if (Array.isArray(bVal) && !Array.isArray(aVal)) {
return false
}
return keyValEqual(a, b, key, compare)

return compare(aVal, bVal)
})
}

Expand Down Expand Up @@ -127,15 +125,14 @@ function compare(a, b, options) {
return a === b
}

if ((a === undefined && b === false) || (b === undefined && a === false)) {
if ((a !== false && b === false) || (b !== false && a === false)) {
return false
}

if ((undef(a) && !undef(b)) || (!undef(a) && undef(b))) {
return false
}
var aKeys = isPlainObject(a) ? Object.keys(a) : []
var bKeys = isPlainObject(b) ? Object.keys(b) : []

var allKeys = uniq(Object.keys(a).concat(Object.keys(b)))
var allKeys = uniq([...aKeys, ...bKeys])

if (options.ignore.length) {
allKeys = allKeys.filter(k => options.ignore.indexOf(k) === -1)
Expand All @@ -150,8 +147,8 @@ function compare(a, b, options) {
}

return allKeys.every(function(key) {
var aValue = a[key]
var bValue = b[key]
var aValue = propOrFake(a, key)
var bValue = propOrFake(b, key)

if (schemaProps.indexOf(key) !== -1) {
return compare(aValue, bValue, options)
Expand Down
164 changes: 163 additions & 1 deletion test/specs/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,23 @@ describe('comparison', function() {
minLength: 0
}
}
}, false, {
}, true, {
ignore: ['title']
})
})

it('compares false and undefined', function() {
compare(undefined, false, false)
})

it('compares required unsorted', function() {
compare({
required: ['test', 'rest']
}, {
required: ['rest', 'test', 'rest']
}, true)
})

it('compares equal required empty array and undefined', function() {
compare({
required: []
Expand All @@ -54,11 +56,13 @@ describe('comparison', function() {
required: ['fds']
}, {}, false)
})

it('compares equal properties empty object and undefined', function() {
compare({
properties: {}
}, {}, true)
})

it('compares properties', function() {
compare({
properties: {
Expand All @@ -74,16 +78,162 @@ describe('comparison', function() {
}
}, true)
})

it('compares schema undefined and true', function() {
compare(true, undefined, true)
})

it('compares schema empty object and true', function() {
compare(true, {}, true)
})

it('compares sub schema with matching sub validators equal to undefined', function() {
compare({
properties: {
name: undefined
}
}, {
properties: {
name: {
minLength: 0
}
}
}, true)
})

it('compares sub schema with matching sub validators equal to missing', function() {
compare({
properties: {
}
}, {
properties: {
name: {
minLength: 0
}
}
}, true)
})

it('compares sub schema with matching sub validators equal to no properties', function() {
compare({}, {
properties: {
name: {
minLength: 0
}
}
}, true)

compare(true, {
properties: {
name: {
minLength: 0
}
}
}, true)

compare(undefined, {
properties: {
name: {
minLength: 0,
minItems: 0
}
}
}, true)
})

it('compares sub schema with matching sub validators equal to no properties', function() {
compare({
properties: {
name: false
}
}, {
properties: {
name: {
minLength: 0
}
}
}, false)
})

it('compares equal patternProperties empty object and undefined', function() {
compare({
patternProperties: {}
}, {}, true)
})

it('compares patternProperties with regular property as false', function() {
compare({
patternProperties: {
'.+': {
minLength: 9
}
}
}, {
properties: {
name: {
minLength: 9
}
}
}, false)
})

it('compares equal patternProperties', function() {
compare({
patternProperties: {
'.+': {
minLength: 9
}
}
}, {
patternProperties: {
'.+': {
minLength: 9
}
}
}, true)
})

it('compares equal patternProperties', function() {
compare({
patternProperties: {
'.+': {
minLength: 0
},
'..+': {
minLength: 0
},
'...+': {
minLength: 0
}
}
}, {
patternProperties: {
'.+': {},
'..+': true
}
}, true)
})

it('compares patternProperties, subschema false', function() {
compare({
patternProperties: {
'.+': false
}
}, {
patternProperties: {
'.+': {
minLength: 0
}
}
}, false)
})

it('compares equal dependencies empty object and undefined', function() {
compare({
dependencies: {}
}, {}, true)
})

it('compares type unsorted', function() {
compare({
type: ['string', 'array']
Expand All @@ -101,12 +251,14 @@ describe('comparison', function() {
type: ['string']
}, true)
})

it('compares equal an empty schema, true and undefined', function() {
compare({}, true, true)
compare({}, undefined, true)
compare(false, false, true)
compare(true, true, true)
})

it('ignores any in ignore list', function() {
compare({
title: 'title'
Expand All @@ -123,6 +275,7 @@ describe('comparison', function() {
type: ['string']
}, false)
})

it('sorts anyOf before comparing', function() {
compare({
anyOf: [
Expand Down Expand Up @@ -203,6 +356,7 @@ describe('comparison', function() {
]
}, true)
})

it('sorts allOf before comparing', function() {
compare({
allOf: [
Expand Down Expand Up @@ -283,6 +437,7 @@ describe('comparison', function() {
]
}, true)
})

it('sorts oneOf before comparing', function() {
compare({
oneOf: [
Expand Down Expand Up @@ -363,13 +518,15 @@ describe('comparison', function() {
]
}, true)
})

it('compares enum unsorted', function() {
compare({
enum: ['abc', '123']
}, {
enum: ['123', 'abc', 'abc']
}, true)
})

it('compares dependencies value if array unsorted', function() {
compare({
dependencies: {
Expand All @@ -381,6 +538,7 @@ describe('comparison', function() {
}
}, true)
})

it('compares items SORTED', function() {
compare({
items: [true, false]
Expand All @@ -394,21 +552,25 @@ describe('comparison', function() {
items: [true, false]
}, true)
})

it('compares equal uniqueItems false and undefined', function() {
compare({
uniqueItems: false
}, {}, true)
})

it('compares equal minLength undefined and 0', function() {
compare({
minLength: 0
}, {}, true)
})

it('compares equal minItems undefined and 0', function() {
compare({
minItems: 0
}, {}, true)
})

it('compares equal minProperties undefined and 0', function() {
compare({
minProperties: 0
Expand Down