Skip to content

Commit

Permalink
equals should skip null and undefined nodes fix #151
Browse files Browse the repository at this point in the history
  • Loading branch information
smacker committed Apr 27, 2016
1 parent 91f0f98 commit 7733cba
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 5 deletions.
19 changes: 14 additions & 5 deletions src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ export function nodeEqual(a, b) {
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))) {
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') {
Expand All @@ -94,8 +94,17 @@ export function nodeEqual(a, b) {
}
}

const leftHasChildren = 'children' in left;
const rightHasChildren = 'children' in right;
if (leftHasChildren || rightHasChildren) {
if (!childrenEqual(childrenToArray(left.children), childrenToArray(right.children))) {
return false;
}
}

if (typeof a !== 'string' && typeof a !== 'number') {
return leftKeys.length === Object.keys(right).length;
const rightKeys = Object.keys(right);
return leftKeys.length - leftHasChildren === rightKeys.length - rightHasChildren;
}

return false;
Expand Down
97 changes: 97 additions & 0 deletions test/Utils-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,103 @@ describe('Utils', () => {

});

describe('children props', () => {
it('should match equal nodes', () => {
expect(nodeEqual(
<div>child</div>,
<div>child</div>
)).to.equal(true);
});

it('should not match not equal nodes', () => {
expect(nodeEqual(
<div>child</div>,
<div></div>
)).to.equal(false);

expect(nodeEqual(
<div></div>,
<div>child</div>
)).to.equal(false);
});

it('should skip null children', () => {
expect(nodeEqual(
<div>{null}</div>,
<div></div>
)).to.equal(true);
});

it('should skip undefined children', () => {
expect(nodeEqual(
<div>{undefined}</div>,
<div></div>
)).to.equal(true);
});

it('should skip empty children', () => {
expect(nodeEqual(
<div>{[]}</div>,
<div></div>
)).to.equal(true);
});

it('should skip array of null children', () => {
expect(nodeEqual(
<div>{[null, null, null]}</div>,
<div></div>
)).to.equal(true);
});

});

describe('basic props and children mixed', () => {

it('should match equal nodes', () => {
expect(nodeEqual(
<div className="foo">child</div>,
<div className="foo">child</div>
)).to.equal(true);
});

it('should not match when basic props are not equal', () => {
expect(nodeEqual(
<div className="foo">child</div>,
<div className="bar">child</div>
)).to.equal(false);

expect(nodeEqual(
<div children="child" className="foo" />,
<div children="child" className="bar" />
)).to.equal(false);
});

it('should not match when children are not equal', () => {
expect(nodeEqual(
<div className="foo">child</div>,
<div className="foo">other child</div>
)).to.equal(false);

expect(nodeEqual(
<div children="child" className="foo" />,
<div children="other child" className="foo" />
)).to.equal(false);
});

it('should match nodes when children are different but falsy', () => {
expect(nodeEqual(
<div className="foo">{null}</div>,
<div className="foo" />
)).to.equal(true);

expect(nodeEqual(
<div children={null} className="foo" />,
<div className="foo" />
)).to.equal(true);
});

});

});

describe('propFromEvent', () => {
Expand Down

0 comments on commit 7733cba

Please sign in to comment.