Skip to content

Commit

Permalink
[Tests] add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Mar 26, 2019
1 parent d6a6012 commit 5a35fbf
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 28 deletions.
37 changes: 36 additions & 1 deletion packages/enzyme-test-suite/test/Adapter-spec.jsx
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { expect } from 'chai';
import jsdom from 'jsdom';
import { get } from 'enzyme/build/configuration';
import { configure, shallow } from 'enzyme';
import { configure, shallow, EnzymeAdapter } from 'enzyme';
import inspect from 'object-inspect';
import {
Portal,
Expand Down Expand Up @@ -77,6 +77,41 @@ describe('Adapter', () => {
});
});

describe('base class', () => {
it('constructs', () => {
const instance = new EnzymeAdapter();
expect(instance).to.have.property('options');
expect(instance.options).to.be.an('object');
});

it('throws on abstract methods', () => {
expect(() => new EnzymeAdapter().createRenderer()).to.throw(
Error,
'createRenderer is a required method of EnzymeAdapter, but was not implemented.',
);
expect(() => new EnzymeAdapter().nodeToElement()).to.throw(
Error,
'nodeToElement is a required method of EnzymeAdapter, but was not implemented.',
);
expect(() => new EnzymeAdapter().isValidElement()).to.throw(
Error,
'isValidElement is a required method of EnzymeAdapter, but was not implemented.',
);
expect(() => new EnzymeAdapter().createElement()).to.throw(
Error,
'createElement is a required method of EnzymeAdapter, but was not implemented.',
);
});

describe('invokeSetStateCallback', () => {
it('has the right length', () => {
expect(EnzymeAdapter.prototype).to.have.property('invokeSetStateCallback');
expect(EnzymeAdapter.prototype.invokeSetStateCallback).to.be.a('function');
expect(EnzymeAdapter.prototype.invokeSetStateCallback).to.have.lengthOf(2);
});
});
});

describeWithDOM('mounted render', () => {
function hydratedTreeMatchesUnhydrated(element, hydrate = false) {
const markup = renderToString(element);
Expand Down
41 changes: 37 additions & 4 deletions packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
Expand Up @@ -45,6 +45,21 @@ describeWithDOM('mount', () => {
});

describe('top level wrapper', () => {
wrap()
.withGlobal('document', () => null)
.withGlobal('window', () => null)
.it('throws without a global document and window', () => {
expect(() => mount(<div />)).to.throw(
Error,
'It looks like you called `mount()` without a global document being loaded.',
);

expect(() => new ReactWrapper(<div />)).to.throw(
Error,
'It looks like you called `mount()` without a global document being loaded.',
);
});

it('does what i expect', () => {
class Box extends React.Component {
render() {
Expand Down Expand Up @@ -861,18 +876,36 @@ describeWithDOM('mount', () => {
});

describe('.ref(refName)', () => {
class WithoutRef extends React.Component {
render() { return <div />; }
}

class WithRef extends React.Component {
render() { return <div ref="r" />; }
}

class RendersWithRef extends React.Component {
render() { return <WithRef />; }
}

it('throws when called on not the root', () => {
const wrapper = mount(<RendersWithRef />);
const found = wrapper.find(WithRef);
expect(found).to.have.lengthOf(1);
expect(() => found.ref('ref')).to.throw(
Error,
'ReactWrapper::ref(refname) can only be called on the root',
);
});

it('unavailable ref should return undefined', () => {
class WithoutRef extends React.Component {
render() { return <div />; }
}
const wrapper = mount(<WithoutRef />);
const ref = wrapper.ref('not-a-ref');

expect(ref).to.equal(undefined);
});

it('gets a wrapper of the node matching the provided refName', () => {

class Foo extends React.Component {
render() {
return (
Expand Down
Expand Up @@ -27,7 +27,7 @@ export default function describeIterator({
}
}
const wrapper = Wrap(<Foo />);
const [a, b, c, d] = wrapper.find('a');
const [a, b, c, d, ...e] = wrapper.find('a');
const a1 = wrapper.find('a').get(0);
const b1 = wrapper.find('a').get(1);
const c1 = wrapper.find('a').get(2);
Expand All @@ -36,6 +36,7 @@ export default function describeIterator({
expect(b1).to.deep.equal(b);
expect(c1).to.deep.equal(c);
expect(d1).to.deep.equal(d);
expect(e).to.eql([]);
});

it('returns an iterable iterator', () => {
Expand Down
77 changes: 77 additions & 0 deletions packages/enzyme-test-suite/test/shared/methods/context.jsx
@@ -0,0 +1,77 @@
import React from 'react';
import PropTypes from 'prop-types';
import { expect } from 'chai';

import {
itIf,
} from '../../_helpers';
import {
is,
} from '../../_helpers/version';

import {
createClass,
} from '../../_helpers/react-compat';

export default function describeContext({
Wrap,
WrapperName,
}) {
describe('.context()', () => {
const contextTypes = {
name: PropTypes.string,
};
const SimpleComponent = createClass({
contextTypes,
render() {
const { name } = this.context;
return <div>{name}</div>;
},
});

function SimpleComponentSFC(props, { name }) {
return <div>{name}</div>;
}
SimpleComponentSFC.contextTypes = contextTypes;

it('throws when not called on the root', () => {
const context = { name: <main /> };
const wrapper = Wrap(<SimpleComponent />, { context });
const main = wrapper.find('main');
expect(main).to.have.lengthOf(1);
expect(() => main.context()).to.throw(
Error,
`${WrapperName}::context() can only be called on the root`,
);
});

it('throws if it is called when wrapper didn’t include context', () => {
const wrapper = Wrap(<SimpleComponent />);
expect(() => wrapper.context()).to.throw(
Error,
`${WrapperName}::context() can only be called on a wrapper that was originally passed a context option`,
);
});

itIf(is('>= 16'), 'throws on SFCs that lack an instance', () => {
const context = { name: 'bob' };
const wrapper = Wrap(<SimpleComponentSFC />, { context });
expect(() => wrapper.context()).to.throw(
Error,
`${WrapperName}::context() can only be called on wrapped nodes that have a non-null instance`,
);
});

it('works with no arguments', () => {
const context = { name: {} };
const wrapper = Wrap(<SimpleComponentSFC />, { context });
expect(wrapper.context()).to.eql(context);
});

it('works with a key name', () => {
const context = { name: {} };
const wrapper = Wrap(<SimpleComponentSFC />, { context });
expect(wrapper.context('name')).to.equal(context.name);
});
});
}
37 changes: 15 additions & 22 deletions packages/enzyme-test-suite/test/shared/methods/renderProp.jsx
Expand Up @@ -17,19 +17,24 @@ export default function describeRenderProp({
wrap()
.withConsoleThrows()
.describe('.renderProp()', () => {
it('returns a wrapper around the node returned from the render prop', () => {
class Foo extends React.Component {
render() {
return <div className="in-foo" />;
}
class Foo extends React.Component {
render() {
return <div className="in-foo" />;
}
class Bar extends React.Component {
render() {
const { render: r } = this.props;
return <div className="in-bar">{r()}</div>;
}
}
class Bar extends React.Component {
render() {
const { render: r } = this.props;
return <div className="in-bar">{r()}</div>;
}
}
class RendersBar extends React.Component {
render() {
return <Bar {...this.props} />;
}
}

it('returns a wrapper around the node returned from the render prop', () => {
const wrapperA = Wrap(<div><Bar render={() => <div><Foo /></div>} /></div>);
const renderPropWrapperA = wrapperA.find(Bar).renderProp('render')();
expect(renderPropWrapperA.find(Foo)).to.have.lengthOf(1);
Expand Down Expand Up @@ -61,18 +66,6 @@ export default function describeRenderProp({
wrap()
.withOverride(() => getAdapter(), 'wrap', () => undefined)
.it('throws with a react adapter that lacks a `.wrap`', () => {
class Foo extends React.Component {
render() {
return <div className="in-foo" />;
}
}
class Bar extends React.Component {
render() {
const { render: r } = this.props;
return <div className="in-bar">{r()}</div>;
}
}

const wrapper = Wrap(<div><Bar render={() => <div><Foo /></div>} /></div>);
expect(() => wrapper.find(Bar).renderProp('render')).to.throw(RangeError);
});
Expand Down
11 changes: 11 additions & 0 deletions packages/enzyme-test-suite/test/shared/methods/setContext.jsx
Expand Up @@ -44,6 +44,17 @@ export default function describeSetContext({
);
});

it('throws when not called on the root', () => {
const context = { name: <main /> };
const wrapper = Wrap(<SimpleComponent />, { context });
const main = wrapper.find('main');
expect(main).to.have.lengthOf(1);
expect(() => main.setContext()).to.throw(
Error,
`${WrapperName}::setContext() can only be called on the root`,
);
});

describeIf(is('> 0.13'), 'stateless functional components', () => {
const SFC = (props, { name }) => (
<div>{name}</div>
Expand Down
21 changes: 21 additions & 0 deletions packages/enzyme-test-suite/test/shared/methods/setProps.jsx
Expand Up @@ -15,6 +15,7 @@ import { is } from '../../_helpers/version';

export default function describeSetProps({
Wrap,
WrapperName,
isShallow,
}) {
describe('.setProps(newProps[, callback)', () => {
Expand Down Expand Up @@ -43,6 +44,16 @@ export default function describeSetProps({
);
}

class RendersFoo extends React.Component {
render() {
return (
<main>
<Foo {...this.props} />
</main>
);
}
}

it('throws on a non-function callback', () => {
const wrapper = Wrap(<RendersNull />);

Expand All @@ -54,6 +65,16 @@ export default function describeSetProps({
expect(() => wrapper.setProps({}, {})).to.throw();
});

it('throws when not called on the root', () => {
const wrapper = Wrap(<RendersFoo id="a" foo="b" />);
const child = wrapper.find(Foo);
expect(child).to.have.lengthOf(1);
expect(() => child.setProps({})).to.throw(
Error,
`${WrapperName}::setProps() can only be called on the root`,
);
});

it('sets props for a component multiple times', () => {
const wrapper = Wrap(<Foo id="foo" />);
expect(wrapper.find('.foo')).to.have.lengthOf(1);
Expand Down

0 comments on commit 5a35fbf

Please sign in to comment.