diff --git a/package.json b/package.json
index 01dfbffac..10375614f 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"check": "lerna run lint && npm run test:all",
"prebuild": "npm run clean",
"build": "lerna run build",
- "build:watch": "lerna run watch",
+ "build:watch": "lerna run --parallel watch",
"pretest": "lerna run lint",
"test": "npm run test:only",
"pretest:only": "npm run build",
diff --git a/packages/enzyme-test-suite/test/Debug-spec.jsx b/packages/enzyme-test-suite/test/Debug-spec.jsx
index af16a3a6b..f9a33d5ca 100644
--- a/packages/enzyme-test-suite/test/Debug-spec.jsx
+++ b/packages/enzyme-test-suite/test/Debug-spec.jsx
@@ -487,13 +487,15 @@ describe('debug', () => {
}
expect(shallow().debug()).to.eql(
- `
-
-
- From Bar
-
-
-
`,
+ `
+
+
+
+ From Bar
+
+
+
+`,
);
});
});
@@ -511,11 +513,13 @@ describe('debug', () => {
}
expect(debugNodes(shallow().getNodesInternal())).to.eql(
- `
-
- inside Foo
-
-
`,
+ `
+
+
+ inside Foo
+
+
+`,
);
});
@@ -542,7 +546,7 @@ describe('debug', () => {
}
}
- expect(debugNodes(shallow().children().getElements())).to.eql(
+ expect(debugNodes(shallow().rendered().children().getElements())).to.eql(
`
@@ -566,7 +570,7 @@ describe('debug', () => {
}
}
- expect(debugNodes(shallow().children().getNodesInternal())).to.eql(
+ expect(debugNodes(shallow().rendered().children().getNodesInternal())).to.eql(
`
span1 text
@@ -608,21 +612,25 @@ describe('debug', () => {
}
expect(shallow().debug({ ignoreProps: false })).to.eql(
- `
-
-
- span text
-
-
`,
+ `
+
+
+
+ span text
+
+
+`,
);
expect(shallow().debug({ ignoreProps: true })).to.eql(
- `
-
-
- span text
-
-
`,
+ `
+
+
+
+ span text
+
+
+`,
);
});
});
diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
index e518954cf..f97a9d369 100644
--- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
+++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
@@ -37,15 +37,15 @@ describe('shallow', () => {
const wrapper = shallow();
- expect(wrapper.type()).to.equal(Box);
- expect(wrapper.props().bam).to.equal(true);
+ expect(wrapper.type()).to.equal(Foo);
+ expect(wrapper.rendered().type()).to.equal(Box);
+ expect(wrapper.props().bam).to.equal(undefined);
+ expect(wrapper.rendered().props().bam).to.equal(true);
expect(wrapper.instance()).to.be.instanceOf(Foo);
- expect(wrapper.children().at(0).type()).to.equal('div');
+ expect(wrapper.rendered().children().type()).to.equal('div');
expect(wrapper.find(Box).children().props().className).to.equal('div');
expect(wrapper.find(Box).children().at(0).props().className).to.equal('div');
expect(wrapper.find(Box).children().props().className).to.equal('div');
- expect(wrapper.children().type()).to.equal('div');
- expect(wrapper.children().props().bam).to.equal(undefined);
});
});
@@ -155,7 +155,7 @@ describe('shallow', () => {
);
const wrapper = shallow();
- expect(wrapper.type()).to.equal('div');
+ expect(wrapper.rendered().type()).to.equal('div');
expect(wrapper.find('.bar')).to.have.length(1);
expect(wrapper.find('.qoo').text()).to.equal('qux');
});
@@ -955,10 +955,10 @@ describe('shallow', () => {
const context = { x: 'yolo' };
const wrapper = shallow(, { context });
- expect(wrapper.first('div').text()).to.equal('yolo');
+ expect(wrapper.text()).to.equal('yolo');
wrapper.setProps({ x: 5 }); // Just force a re-render
- expect(wrapper.first('div').text()).to.equal('yolo');
+ expect(wrapper.text()).to.equal('yolo');
});
it('should call componentWillReceiveProps, shouldComponentUpdate and componentWillUpdate with merged newProps', () => {
@@ -1045,10 +1045,10 @@ describe('shallow', () => {
const context = { x: 'yolo' };
const wrapper = shallow(, { context });
- expect(wrapper.first('div').text()).to.equal('yolo');
+ expect(wrapper.text()).to.equal('yolo');
wrapper.setProps({ x: 5 }); // Just force a re-render
- expect(wrapper.first('div').text()).to.equal('yolo');
+ expect(wrapper.text()).to.equal('yolo');
});
});
});
@@ -1633,7 +1633,8 @@ describe('shallow', () => {
const wrapper = shallow();
- expect(wrapper.props()).to.eql({ className: 'bye', id: 'hi' });
+ expect(wrapper.props()).to.eql({ foo: 'hi', bar: 'bye' });
+ expect(wrapper.rendered().props()).to.eql({ className: 'bye', id: 'hi' });
});
describeIf(!REACT013, 'stateless function components', () => {
@@ -1644,7 +1645,8 @@ describe('shallow', () => {
const wrapper = shallow();
- expect(wrapper.props()).to.eql({ className: 'bye', id: 'hi' });
+ expect(wrapper.props()).to.eql({ foo: 'hi', bar: 'bye' });
+ expect(wrapper.rendered().props()).to.eql({ className: 'bye', id: 'hi' });
});
});
});
@@ -1689,10 +1691,15 @@ describe('shallow', () => {
const wrapper = shallow();
- expect(wrapper.prop('className')).to.equal('bye');
- expect(wrapper.prop('id')).to.equal('hi');
- expect(wrapper.prop('foo')).to.equal(undefined);
- expect(wrapper.prop('bar')).to.equal(undefined);
+ expect(wrapper.prop('className')).to.equal(undefined);
+ expect(wrapper.prop('id')).to.equal(undefined);
+ expect(wrapper.prop('foo')).to.equal('hi');
+ expect(wrapper.prop('bar')).to.equal('bye');
+
+ expect(wrapper.rendered().prop('className')).to.equal('bye');
+ expect(wrapper.rendered().prop('id')).to.equal('hi');
+ expect(wrapper.rendered().prop('foo')).to.equal(undefined);
+ expect(wrapper.rendered().prop('bar')).to.equal(undefined);
});
describeIf(!REACT013, 'stateless function components', () => {
@@ -1703,10 +1710,15 @@ describe('shallow', () => {
const wrapper = shallow();
- expect(wrapper.prop('className')).to.equal('bye');
- expect(wrapper.prop('id')).to.equal('hi');
- expect(wrapper.prop('foo')).to.equal(undefined);
- expect(wrapper.prop('bar')).to.equal(undefined);
+ expect(wrapper.prop('className')).to.equal(undefined);
+ expect(wrapper.prop('id')).to.equal(undefined);
+ expect(wrapper.prop('foo')).to.equal('hi');
+ expect(wrapper.prop('bar')).to.equal('bye');
+
+ expect(wrapper.rendered().prop('className')).to.equal('bye');
+ expect(wrapper.rendered().prop('id')).to.equal('hi');
+ expect(wrapper.rendered().prop('foo')).to.equal(undefined);
+ expect(wrapper.rendered().prop('bar')).to.equal(undefined);
});
});
});
@@ -1829,10 +1841,10 @@ describe('shallow', () => {
]}
/>,
);
- expect(wrapper.children().length).to.equal(3);
- expect(wrapper.children().at(0).hasClass('foo')).to.equal(true);
- expect(wrapper.children().at(1).hasClass('bar')).to.equal(true);
- expect(wrapper.children().at(2).hasClass('baz')).to.equal(true);
+ expect(wrapper.rendered().children().length).to.equal(3);
+ expect(wrapper.rendered().children().at(0).hasClass('foo')).to.equal(true);
+ expect(wrapper.rendered().children().at(1).hasClass('bar')).to.equal(true);
+ expect(wrapper.rendered().children().at(2).hasClass('baz')).to.equal(true);
});
it('should optionally allow a selector to filter by', () => {
@@ -1866,10 +1878,10 @@ describe('shallow', () => {
]}
/>,
);
- expect(wrapper.children().length).to.equal(3);
- expect(wrapper.children().at(0).hasClass('foo')).to.equal(true);
- expect(wrapper.children().at(1).hasClass('bar')).to.equal(true);
- expect(wrapper.children().at(2).hasClass('baz')).to.equal(true);
+ expect(wrapper.rendered().children().length).to.equal(3);
+ expect(wrapper.rendered().children().at(0).hasClass('foo')).to.equal(true);
+ expect(wrapper.rendered().children().at(1).hasClass('bar')).to.equal(true);
+ expect(wrapper.rendered().children().at(2).hasClass('baz')).to.equal(true);
});
});
@@ -2474,7 +2486,7 @@ describe('shallow', () => {
const context = { name: 'foo' };
const wrapper = shallow();
expect(wrapper.find(Bar)).to.have.length(1);
- expect(wrapper.find(Bar).shallow({ context }).text()).to.equal('foo');
+ expect(wrapper.find(Bar).shallow({ context }).rendered().text()).to.equal('foo');
});
it('should not throw if context is passed in but contextTypes is missing', () => {
@@ -2558,7 +2570,7 @@ describe('shallow', () => {
const context = { name: 'foo' };
const wrapper = shallow();
- expect(wrapper.find(Bar).shallow({ context }).text()).to.equal('foo');
+ expect(wrapper.find(Bar).shallow({ context }).rendered().text()).to.equal('foo');
});
it('should not throw if context is passed in but contextTypes is missing', () => {
@@ -3780,7 +3792,7 @@ describe('shallow', () => {
const wrapper = shallow();
expect(wrapper).to.have.length(1);
expect(wrapper.html()).to.equal(null);
- expect(wrapper.type()).to.equal(null);
+ expect(wrapper.rendered().length).to.equal(0);
const rendered = wrapper.render();
expect(rendered.length).to.equal(0);
expect(rendered.html()).to.equal(null);
@@ -3792,7 +3804,7 @@ describe('shallow', () => {
const wrapper = shallow();
expect(wrapper).to.have.length(1);
expect(wrapper.html()).to.equal(null);
- expect(wrapper.type()).to.equal(null);
+ expect(wrapper.rendered().length).to.equal(0);
const rendered = wrapper.render();
expect(rendered.length).to.equal(0);
expect(rendered.html()).to.equal(null);
@@ -4178,7 +4190,7 @@ describe('shallow', () => {
Foo.displayName = 'CustomWrapper';
const wrapper = shallow();
- expect(wrapper.name()).to.equal('CustomWrapper');
+ expect(wrapper.rendered().name()).to.equal('CustomWrapper');
});
describeIf(!REACT013, 'stateless function components', () => {
@@ -4191,7 +4203,7 @@ describe('shallow', () => {
SFC.displayName = 'CustomWrapper';
const wrapper = shallow();
- expect(wrapper.name()).to.equal('CustomWrapper');
+ expect(wrapper.rendered().name()).to.equal('CustomWrapper');
});
});
@@ -4210,7 +4222,7 @@ describe('shallow', () => {
});
const wrapper = shallow();
- expect(wrapper.name()).to.equal('CustomWrapper');
+ expect(wrapper.rendered().name()).to.equal('CustomWrapper');
});
});
});
@@ -4226,7 +4238,7 @@ describe('shallow', () => {
}
const wrapper = shallow();
- expect(wrapper.name()).to.equal('Foo');
+ expect(wrapper.rendered().name()).to.equal('Foo');
});
describeIf(!REACT013, 'stateless function components', () => {
@@ -4237,7 +4249,7 @@ describe('shallow', () => {
const Wrapper = () => ;
const wrapper = shallow();
- expect(wrapper.name()).to.equal('SFC');
+ expect(wrapper.rendered().name()).to.equal('SFC');
});
});
});
@@ -4291,7 +4303,7 @@ describe('shallow', () => {
it('throws on a DOM node', () => {
const wrapper = shallow();
- expect(wrapper.is('div')).to.equal(true);
+ expect(wrapper.rendered().is('div')).to.equal(true);
expect(() => { wrapper.dive(); }).to.throw(
TypeError,
@@ -4301,7 +4313,7 @@ describe('shallow', () => {
it('throws on a non-component', () => {
const wrapper = shallow();
- expect(wrapper.type()).to.equal(null);
+ expect(wrapper.rendered().length).to.equal(0);
expect(() => { wrapper.dive(); }).to.throw(
TypeError,
@@ -4319,10 +4331,10 @@ describe('shallow', () => {
it('dives + shallow-renders when there is one component child', () => {
const wrapper = shallow();
- expect(wrapper.is(WrapsRendersDOM)).to.equal(true);
+ expect(wrapper.rendered().is(WrapsRendersDOM)).to.equal(true);
const underwater = wrapper.dive();
- expect(underwater.is(RendersDOM)).to.equal(true);
+ expect(underwater.rendered().is(RendersDOM)).to.equal(true);
});
it('should merge and pass options through', () => {
diff --git a/packages/enzyme-test-suite/test/_helpers/index.jsx b/packages/enzyme-test-suite/test/_helpers/index.jsx
index 52274d910..907c87f0c 100644
--- a/packages/enzyme-test-suite/test/_helpers/index.jsx
+++ b/packages/enzyme-test-suite/test/_helpers/index.jsx
@@ -96,7 +96,7 @@ export function generateEmptyRenderData() {
{ message: 'false', value: false, expectResponse: true },
{ message: 'null', value: null, expectResponse: true },
- // Returns false for empty, valid returns
+ // // Returns false for empty, valid returns
{ message: 'React component', value: , expectResponse: false },
{ message: 'React element', value: , expectResponse: false },
{ message: 'React element', value: , expectResponse: false },
diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js
index 3d89215af..59c8b7c9e 100644
--- a/packages/enzyme/src/ShallowWrapper.js
+++ b/packages/enzyme/src/ShallowWrapper.js
@@ -99,11 +99,15 @@ function validateOptions(options) {
}
}
-function getRootNode(node) {
- if (node.nodeType === 'host') {
- return node;
+function getRenderedNode(wrapper) {
+ const node = wrapper[NODE];
+ if (wrapper[ROOT] === wrapper) {
+ if (node.nodeType === 'host') {
+ return node;
+ }
+ return node.rendered;
}
- return node.rendered;
+ return node;
}
/**
@@ -118,7 +122,8 @@ class ShallowWrapper {
const renderer = getAdapter(options).createRenderer({ mode: 'shallow', ...options });
privateSet(this, RENDERER, renderer);
this[RENDERER].render(nodes, options.context);
- const instance = this[RENDERER].getNode().instance;
+ const node = this[RENDERER].getNode();
+ const instance = node.instance;
if (
options.lifecycleExperimental &&
instance &&
@@ -128,7 +133,7 @@ class ShallowWrapper {
instance.componentDidMount();
});
}
- privateSet(this, NODE, getRootNode(this[RENDERER].getNode()));
+ privateSet(this, NODE, node);
privateSet(this, NODES, [this[NODE]]);
this.length = 1;
} else {
@@ -219,7 +224,7 @@ class ShallowWrapper {
if (this[ROOT] !== this) {
throw new Error('ShallowWrapper::instance() can only be called on the root');
}
- return this[RENDERER].getNode().instance;
+ return this[NODE].instance;
}
/**
@@ -235,7 +240,7 @@ class ShallowWrapper {
throw new Error('ShallowWrapper::update() can only be called on the root');
}
this.single('update', () => {
- this[NODE] = getRootNode(this[RENDERER].getNode());
+ this[NODE] = this[RENDERER].getNode();
this[NODES] = [this[NODE]];
});
return this;
@@ -360,7 +365,7 @@ class ShallowWrapper {
if (this[ROOT] !== this) {
throw new Error('ShallowWrapper::setState() can only be called on the root');
}
- if (this.instance() === null || this[RENDERER].getNode().nodeType === 'function') {
+ if (this.instance() === null || this[NODE].nodeType === 'function') {
throw new Error('ShallowWrapper::setState() can only be called on class components');
}
this.single('setState', () => {
@@ -510,7 +515,7 @@ class ShallowWrapper {
* @returns {Boolean}
*/
equals(node) {
- return this.single('equals', () => nodeEqual(this.getNodeInternal(), node));
+ return this.single('equals', () => nodeEqual(getRenderedNode(this), node));
}
/**
@@ -563,7 +568,8 @@ class ShallowWrapper {
* @returns {boolean}
*/
isEmptyRender() {
- return this.type() === null;
+ const rendered = getRenderedNode(this);
+ return rendered === null || rendered === false;
}
/**
@@ -612,7 +618,9 @@ class ShallowWrapper {
* @returns {String}
*/
text() {
- return this.single('text', getTextFromNode);
+ return this.single('text', () => {
+ return getTextFromNode(getRenderedNode(this));
+ });
}
/**
@@ -624,10 +632,10 @@ class ShallowWrapper {
*/
html() {
return this.single('html', (n) => {
- if (this.type() === null) return null;
+ if (this.isEmptyRender()) return null;
const adapter = getAdapter(this[OPTIONS]);
const renderer = adapter.createRenderer({ ...this[OPTIONS], mode: 'string' });
- return renderer.render(adapter.nodeToElement(n));
+ return renderer.render(adapter.nodeToElement(getRenderedNode(this)));
});
}
@@ -661,8 +669,8 @@ class ShallowWrapper {
* @returns {ShallowWrapper}
*/
simulate(event, ...args) {
- return this.single('simulate', (n) => {
- this[RENDERER].simulateEvent(n, event, ...args);
+ return this.single('simulate', () => {
+ this[RENDERER].simulateEvent(getRenderedNode(this), event, ...args);
this[ROOT].update();
});
}
@@ -691,7 +699,7 @@ class ShallowWrapper {
if (this[ROOT] !== this) {
throw new Error('ShallowWrapper::state() can only be called on the root');
}
- if (this.instance() === null || this[RENDERER].getNode().nodeType === 'function') {
+ if (this.instance() === null || this[NODE].nodeType === 'function') {
throw new Error('ShallowWrapper::state() can only be called on class components');
}
const _state = this.single('state', () => this.instance().state);
@@ -744,6 +752,11 @@ class ShallowWrapper {
return selector ? allChildren.filter(selector) : allChildren;
}
+ rendered(selector) {
+ const allChildren = this.flatMap(n => childrenOfNode(n.getNodeInternal()));
+ return selector ? allChildren.filter(selector) : allChildren;
+ }
+
/**
* Returns a new wrapper with a specific child
*
@@ -1138,7 +1151,11 @@ class ShallowWrapper {
dive(options = {}) {
const adapter = getAdapter(this[OPTIONS]);
const name = 'dive';
- return this.single(name, (n) => {
+ return this.single(name, () => {
+ const n = getRenderedNode(this);
+ // if (Array.isArray(n)) {
+ // throw new TypeError('todo: use single error message');
+ // }
if (n && n.nodeType === 'host') {
throw new TypeError(`ShallowWrapper::${name}() can not be called on Host Components`);
}