Skip to content

Commit

Permalink
#1 Adds strict comparison as the default behavior.
Browse files Browse the repository at this point in the history
  • Loading branch information
thebearingedge committed Sep 11, 2016
1 parent 617698a commit 4ff72d9
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 5 deletions.
30 changes: 25 additions & 5 deletions src/diff.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { isNull, isUndefined, isPlainObject, isArray } from 'lodash'
import { isNull, isUndefined, isPlainObject, isArray, difference } from 'lodash'
import types from './types'

export default function diff(Shape, obj) {
export default function diff(Shape, obj, options = {}) {

const { strict } = Object.assign({}, { strict: true }, options)

if (isArray(Shape)) {

Expand All @@ -14,14 +16,32 @@ export default function diff(Shape, obj) {
}

for (let i = 0; i < obj.length; i++) {
const result = diff(Shape[0], obj[i])
const result = diff(Shape[0], obj[i], { strict })
if (result) return { [i]: result }
}
}

if (isPlainObject(Shape)) {
for (let key in Shape) {
const result = diff(Shape[key], obj[key])

const shapeKeys = Object.keys(Shape)

if (strict) {
const objKeys = Object.keys(obj)
const extraKeys = difference(objKeys, shapeKeys)
.filter(key => !shapeKeys.includes(key))
if (extraKeys.length) {
return extraKeys.reduce((extra, key) => Object.assign(extra, {
[key]: {
unexpected: getTypeName(obj[key]),
value: obj[key]
}
}), {})
}
}

for (let i = 0, len = shapeKeys.length; i < len; i++) {
const key = shapeKeys[i]
const result = diff(Shape[key], obj[key], { strict })
if (result) return { [key]: result }
}
}
Expand Down
136 changes: 136 additions & 0 deletions src/diff.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ describe('diff(Shape, obj)', () => {
expect(result).to.be.null
})

it('diffs a shallow shape with unexpected properties', () => {
const Shape = { name: String }
const obj = { id: 1, name: 'John Doe' }
const result = diff(Shape, obj)
expect(result).to.deep.equal({
id: {
unexpected: 'Number',
value: 1
}
})
})

it('ignores unexpected properties on a shallow shape', () => {
const Shape = { name: String }
const obj = { id: 1, name: 'John Doe' }
const result = diff(Shape, obj, { strict: false })
expect(result).to.be.null
})

it('diffs an incorrect shallow Shape', () => {
const Shape = { id: Number }
const obj = { id: '1' }
Expand Down Expand Up @@ -81,6 +100,53 @@ describe('diff(Shape, obj)', () => {
})
})

it('diffs a Shape with unexpected nested properties', () => {
const Shape = {
id: Number,
attrs: {
name: String,
isActive: Boolean
}
}
const obj = {
id: 1,
attrs: {
name: 'John Doe',
isActive: true,
isHandsome: true
}
}
const result = diff(Shape, obj)
expect(result).to.deep.equal({
attrs: {
isHandsome: {
unexpected: 'Boolean',
value: true
}
}
})
})

it('ignores unexpected nested properties', () => {
const Shape = {
id: Number,
attrs: {
name: String,
isActive: Boolean
}
}
const obj = {
id: 1,
attrs: {
name: 'John Doe',
isActive: true,
isHandsome: true
}
}
const result = diff(Shape, obj, { strict: false })
expect(result).to.be.null
})

it('diffs a Shape with undefined properties', () => {
const Shape = {
id: Number,
Expand Down Expand Up @@ -160,6 +226,27 @@ describe('diff(Shape, obj)', () => {
})
})

it('diffs an Array of dissimilar Objects with extra keys', () => {
const Shape = [{ id: Number, name: String }]
const obj = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar', color: 'red' }]
const result = diff(Shape, obj)
expect(result).to.deep.equal({
'1': {
color: {
unexpected: 'String',
value: 'red'
}
}
})
})

it('ignores unexpected properties on similar objects in an array', () => {
const Shape = [{ id: Number, name: String }]
const obj = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar', color: 'red' }]
const result = diff(Shape, obj, { strict: false })
expect(result).to.be.null
})

it('diffs a matching complex Object', () => {
const Pet = { name: String, weight: Number }
const Owner = { name: String, pets: [Pet] }
Expand Down Expand Up @@ -224,4 +311,53 @@ describe('diff(Shape, obj)', () => {
})
})

it('diffs a complex structure with unexpected properties', () => {
const Pet = { name: String, weight: Number }
const Owner = { name: String, pets: [Pet] }
const garfield = {
name: 'Garfield',
weight: 40
}
const odie = {
name: 'Odie',
weight: 17,
age: 3
}
const john = {
name: 'John Arbuckle',
pets: [garfield, odie]
}
const result = diff(Owner, john)
expect(result).to.deep.equal({
pets: {
'1': {
age: {
unexpected: 'Number',
value: 3
}
}
}
})
})

it('ignores unexpected properties of a complex structure', () => {
const Pet = { name: String, weight: Number }
const Owner = { name: String, pets: [Pet] }
const garfield = {
name: 'Garfield',
weight: 40
}
const odie = {
name: 'Odie',
weight: 17,
age: 3
}
const john = {
name: 'John Arbuckle',
pets: [garfield, odie]
}
const result = diff(Owner, john, { strict: false })
expect(result).to.be.null
})

})

0 comments on commit 4ff72d9

Please sign in to comment.