From d31b829f38fc6deabb7a798c827a2b6ec20aa737 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 20 Aug 2018 20:42:19 -0700 Subject: [PATCH] [Fix] `shallow`: `.parents`: ensure that one `.find` call does not affect another. Fixes #1780. --- .../test/ReactWrapper-spec.jsx | 49 +++++++++++++++++++ .../test/ShallowWrapper-spec.jsx | 49 +++++++++++++++++++ packages/enzyme/src/RSTTraversal.js | 2 +- packages/enzyme/src/ReactWrapper.js | 6 ++- packages/enzyme/src/ShallowWrapper.js | 6 ++- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index fd4f8c5e9..dcb327316 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -3893,6 +3893,55 @@ describeWithDOM('mount', () => { const formUp = input.parents('form'); expect(formUp).to.have.lengthOf(1); }); + + it('works when called sequentially on two sibling nodes', () => { + class Test extends React.Component { + render() { + return ( +
+
+
A child
+
+
+
B child
+
+
+ ); + } + } + + const wrapper = mount(); + + const aChild = wrapper.find({ children: 'A child' }); + expect(aChild.debug()).to.equal(`
+ A child +
`); + expect(aChild).to.have.lengthOf(1); + + const bChild = wrapper.find({ children: 'B child' }); + expect(bChild.debug()).to.equal(`
+ B child +
`); + expect(bChild).to.have.lengthOf(1); + + /* + const bChildParents = bChild.parents('.b'); + expect(bChildParents.debug()).to.equal(`
+
+ B child +
+
`); + expect(bChildParents).to.have.lengthOf(1); + */ + + const aChildParents = aChild.parents('.a'); + expect(aChildParents.debug()).to.equal(`
+
+ A child +
+
`); + expect(aChildParents).to.have.lengthOf(1); + }); }); describe('.parent()', () => { diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 13ce6c5b1..2c395858e 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -3556,6 +3556,55 @@ describe('shallow', () => { expect(parents.at(0).hasClass('foo')).to.equal(true); expect(parents.at(1).hasClass('bax')).to.equal(true); }); + + it('works when called sequentially on two sibling nodes', () => { + class Test extends React.Component { + render() { + return ( +
+
+
A child
+
+
+
B child
+
+
+ ); + } + } + + const wrapper = shallow(); + + const aChild = wrapper.find({ children: 'A child' }); + expect(aChild.debug()).to.equal(`
+ A child +
`); + expect(aChild).to.have.lengthOf(1); + + const bChild = wrapper.find({ children: 'B child' }); + expect(bChild.debug()).to.equal(`
+ B child +
`); + expect(bChild).to.have.lengthOf(1); + + /* + const bChildParents = bChild.parents('.b'); + expect(bChildParents.debug()).to.equal(`
+
+ B child +
+
`); + expect(bChildParents).to.have.lengthOf(1); + */ + + const aChildParents = aChild.parents('.a'); + expect(aChildParents.debug()).to.equal(`
+
+ A child +
+
`); + expect(aChildParents).to.have.lengthOf(1); + }); }); describe('.parent()', () => { diff --git a/packages/enzyme/src/RSTTraversal.js b/packages/enzyme/src/RSTTraversal.js index ad2f7a7ab..f3389902e 100644 --- a/packages/enzyme/src/RSTTraversal.js +++ b/packages/enzyme/src/RSTTraversal.js @@ -106,7 +106,7 @@ export function pathToNode(node, root) { } export function parentsOfNode(node, root) { - return pathToNode(node, root).reverse(); + return (pathToNode(node, root) || []).reverse(); } export function nodeHasId(node, id) { diff --git a/packages/enzyme/src/ReactWrapper.js b/packages/enzyme/src/ReactWrapper.js index e3d577334..910408cb1 100644 --- a/packages/enzyme/src/ReactWrapper.js +++ b/packages/enzyme/src/ReactWrapper.js @@ -736,8 +736,10 @@ class ReactWrapper { * @returns {ReactWrapper} */ parents(selector) { - const allParents = this.wrap(this.single('parents', n => nodeParents(this, n))); - return selector ? allParents.filter(selector) : allParents; + return this.single('parents', (n) => { + const allParents = this.wrap(this.single('parents', n => nodeParents(this, n))); + return selector ? allParents.filter(selector) : allParents; + }); } /** diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js index 18a946cdf..bb853e8b3 100644 --- a/packages/enzyme/src/ShallowWrapper.js +++ b/packages/enzyme/src/ShallowWrapper.js @@ -972,8 +972,10 @@ class ShallowWrapper { * @returns {ShallowWrapper} */ parents(selector) { - const allParents = this.wrap(this.single('parents', n => nodeParents(this, n))); - return selector ? allParents.filter(selector) : allParents; + return this.single('parents', (n) => { + const allParents = this.wrap(this.single('parents', n => nodeParents(this, n))); + return selector ? allParents.filter(selector) : allParents; + }); } /**