From 810f3f8bfee3beef1a4a87f822f6ac1c9cdf8ca1 Mon Sep 17 00:00:00 2001 From: Sukharev Maxim Date: Tue, 16 Feb 2016 15:22:52 +0700 Subject: [PATCH] equals should skip null and undefined nodes fix #151 --- src/Utils.js | 25 ++++++++---- test/Utils-spec.js | 97 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 8 deletions(-) diff --git a/src/Utils.js b/src/Utils.js index 3f3956a8e..cd938d975 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -82,14 +82,11 @@ export function nodeEqual(a, b, lenComp = is) { const right = propsOfNode(b); for (let i = 0; i < leftKeys.length; i++) { const prop = leftKeys[i]; - if (!(prop in right)) return false; + // we will check children later if (prop === 'children') { - if (!childrenEqual( - childrenToArray(left.children), - childrenToArray(right.children), - lenComp)) { - return false; - } + // continue; + } else if (!(prop in right)) { + return false; } else if (right[prop] === left[prop]) { // continue; } else if (typeof right[prop] === typeof left[prop] && typeof left[prop] === 'object') { @@ -99,8 +96,20 @@ export function nodeEqual(a, b, lenComp = is) { } } + const leftHasChildren = 'children' in left; + const rightHasChildren = 'children' in right; + if (leftHasChildren || rightHasChildren) { + if (!childrenEqual( + childrenToArray(left.children), + childrenToArray(right.children), + lenComp)) { + return false; + } + } + if (!isTextualNode(a)) { - return lenComp(leftKeys.length, Object.keys(right).length); + const rightKeys = Object.keys(right); + return lenComp(leftKeys.length - leftHasChildren, rightKeys.length - rightHasChildren); } return false; diff --git a/test/Utils-spec.js b/test/Utils-spec.js index 22a61e71f..3c82a6d5d 100644 --- a/test/Utils-spec.js +++ b/test/Utils-spec.js @@ -124,6 +124,103 @@ describe('Utils', () => { }); + describe('children props', () => { + it('should match equal nodes', () => { + expect(nodeEqual( +
child
, +
child
+ )).to.equal(true); + }); + + it('should not match not equal nodes', () => { + expect(nodeEqual( +
child
, +
+ )).to.equal(false); + + expect(nodeEqual( +
, +
child
+ )).to.equal(false); + }); + + it('should skip null children', () => { + expect(nodeEqual( +
{null}
, +
+ )).to.equal(true); + }); + + it('should skip undefined children', () => { + expect(nodeEqual( +
{undefined}
, +
+ )).to.equal(true); + }); + + it('should skip empty children', () => { + expect(nodeEqual( +
{[]}
, +
+ )).to.equal(true); + }); + + it('should skip array of null children', () => { + expect(nodeEqual( +
{[null, null, null]}
, +
+ )).to.equal(true); + }); + + }); + + describe('basic props and children mixed', () => { + + it('should match equal nodes', () => { + expect(nodeEqual( +
child
, +
child
+ )).to.equal(true); + }); + + it('should not match when basic props are not equal', () => { + expect(nodeEqual( +
child
, +
child
+ )).to.equal(false); + + expect(nodeEqual( +
, +
+ )).to.equal(false); + }); + + it('should not match when children are not equal', () => { + expect(nodeEqual( +
child
, +
other child
+ )).to.equal(false); + + expect(nodeEqual( +
, +
+ )).to.equal(false); + }); + + it('should match nodes when children are different but falsy', () => { + expect(nodeEqual( +
{null}
, +
+ )).to.equal(true); + + expect(nodeEqual( +
, +
+ )).to.equal(true); + }); + + }); + }); describe('propFromEvent', () => {