Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update additional tests to use .toWarnDev() matcher #11957

Merged
merged 8 commits into from
Jan 3, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -277,15 +277,11 @@ describe('ReactBrowserEventEmitter', () => {
putListener(CHILD, ON_CLICK_KEY, recordIDAndReturnFalse.bind(null, CHILD));
putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
spyOnDev(console, 'error');
ReactTestUtils.Simulate.click(CHILD);
expect(idCallOrder.length).toBe(3);
expect(idCallOrder[0]).toBe(CHILD);
expect(idCallOrder[1]).toBe(PARENT);
expect(idCallOrder[2]).toBe(GRANDPARENT);
if (__DEV__) {
expect(console.error.calls.count()).toEqual(0);
}
});

/**
Expand Down
129 changes: 54 additions & 75 deletions packages/react-dom/src/__tests__/ReactComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ describe('ReactComponent', () => {
});

it('should throw (in dev) when children are mutated during render', () => {
spyOnDev(console, 'error');
function Wrapper(props) {
props.children[1] = <p key={1} />; // Mutation is illegal
return <div>{props.children}</div>;
Expand All @@ -73,8 +72,6 @@ describe('ReactComponent', () => {
});

it('should throw (in dev) when children are mutated during update', () => {
spyOnDev(console, 'error');

class Wrapper extends React.Component {
componentDidMount() {
this.props.children[1] = <p key={1} />; // Mutation is illegal
Expand Down Expand Up @@ -355,10 +352,13 @@ describe('ReactComponent', () => {
});

it('throws usefully when rendering badly-typed elements', () => {
spyOnDev(console, 'error');

const X = undefined;
expect(() => ReactTestUtils.renderIntoDocument(<X />)).toThrowError(
expect(() => {
expect(() => ReactTestUtils.renderIntoDocument(<X />)).toWarnDev(
'React.createElement: type is invalid -- expected a string (for built-in components) ' +
'or a class/function (for composite components) but got: undefined.',
);
}).toThrowError(
'Element type is invalid: expected a string (for built-in components) ' +
'or a class/function (for composite components) but got: undefined.' +
(__DEV__
Expand All @@ -368,20 +368,18 @@ describe('ReactComponent', () => {
);

const Y = null;
expect(() => ReactTestUtils.renderIntoDocument(<Y />)).toThrowError(
expect(() => {
expect(() => ReactTestUtils.renderIntoDocument(<Y />)).toWarnDev(
'React.createElement: type is invalid -- expected a string (for built-in components) ' +
'or a class/function (for composite components) but got: null.',
);
}).toThrowError(
'Element type is invalid: expected a string (for built-in components) ' +
'or a class/function (for composite components) but got: null.',
);

if (__DEV__) {
// One warning for each element creation
expect(console.error.calls.count()).toBe(2);
}
});

it('includes owner name in the error about badly-typed elements', () => {
spyOnDev(console, 'error');

const X = undefined;

function Indirection(props) {
Expand All @@ -400,7 +398,12 @@ describe('ReactComponent', () => {
return <Bar />;
}

expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toThrowError(
expect(() => {
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toWarnDev(
'React.createElement: type is invalid -- expected a string (for built-in components) ' +
'or a class/function (for composite components) but got: undefined.',
);
}).toThrowError(
'Element type is invalid: expected a string (for built-in components) ' +
'or a class/function (for composite components) but got: undefined.' +
(__DEV__
Expand All @@ -409,11 +412,6 @@ describe('ReactComponent', () => {
'\n\nCheck the render method of `Bar`.'
: ''),
);

if (__DEV__) {
// One warning for each element creation
expect(console.error.calls.count()).toBe(1);
}
});

it('throws if a plain object is used as a child', () => {
Expand Down Expand Up @@ -530,18 +528,13 @@ describe('ReactComponent', () => {
function Foo() {
return Foo;
}
spyOnDev(console, 'error');
const container = document.createElement('div');
ReactDOM.render(<Foo />, container);
if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in Foo (at **)',
);
}
expect(() => ReactDOM.render(<Foo />, container)).toWarnDev(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in Foo (at **)',
);
});

it('warns on function as a return value from a class', () => {
Expand All @@ -550,18 +543,13 @@ describe('ReactComponent', () => {
return Foo;
}
}
spyOnDev(console, 'error');
const container = document.createElement('div');
ReactDOM.render(<Foo />, container);
if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in Foo (at **)',
);
}
expect(() => ReactDOM.render(<Foo />, container)).toWarnDev(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in Foo (at **)',
);
});

it('warns on function as a child to host component', () => {
Expand All @@ -572,20 +560,15 @@ describe('ReactComponent', () => {
</div>
);
}
spyOnDev(console, 'error');
const container = document.createElement('div');
ReactDOM.render(<Foo />, container);
if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in span (at **)\n' +
' in div (at **)\n' +
' in Foo (at **)',
);
}
expect(() => ReactDOM.render(<Foo />, container)).toWarnDev(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in span (at **)\n' +
' in div (at **)\n' +
' in Foo (at **)',
);
});

it('does not warn for function-as-a-child that gets resolved', () => {
Expand All @@ -601,7 +584,6 @@ describe('ReactComponent', () => {
});

it('deduplicates function type warnings based on component type', () => {
spyOnDev(console, 'error');
class Foo extends React.PureComponent {
constructor() {
super();
Expand All @@ -621,26 +603,23 @@ describe('ReactComponent', () => {
}
}
const container = document.createElement('div');
const component = ReactDOM.render(<Foo />, container);
let component;
expect(() => {
component = ReactDOM.render(<Foo />, container);
}).toWarnDev([
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in div (at **)\n' +
' in Foo (at **)',
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in span (at **)\n' +
' in div (at **)\n' +
' in Foo (at **)',
]);
component.setState({type: 'portobello mushrooms'});
if (__DEV__) {
expect(console.error.calls.count()).toBe(2);
expect(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in div (at **)\n' +
' in Foo (at **)',
);
expect(normalizeCodeLocInfo(console.error.calls.argsFor(1)[0])).toBe(
'Warning: Functions are not valid as a React child. This may happen if ' +
'you return a Component instead of <Component /> from render. ' +
'Or maybe you meant to call this function rather than return it.\n' +
' in span (at **)\n' +
' in div (at **)\n' +
' in Foo (at **)',
);
}
});
});
});
81 changes: 27 additions & 54 deletions packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,6 @@ describe('ReactComponentLifeCycle', () => {
});

it('should not allow update state inside of getInitialState', () => {
spyOnDev(console, 'error');

class StatefulComponent extends React.Component {
constructor(props, context) {
super(props, context);
Expand All @@ -213,26 +211,20 @@ describe('ReactComponentLifeCycle', () => {
}
}

ReactTestUtils.renderIntoDocument(<StatefulComponent />);
if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: setState(...): Can only update a mounted or ' +
'mounting component. This usually means you called setState() on an ' +
'unmounted component. This is a no-op.\n\nPlease check the code for the ' +
'StatefulComponent component.',
);
}
expect(() => {
ReactTestUtils.renderIntoDocument(<StatefulComponent />);
}).toWarnDev(
'Warning: setState(...): Can only update a mounted or ' +
'mounting component. This usually means you called setState() on an ' +
'unmounted component. This is a no-op.\n\nPlease check the code for the ' +
'StatefulComponent component.',
);

// Check deduplication
// Check deduplication; (no extra warnings should be logged).
ReactTestUtils.renderIntoDocument(<StatefulComponent />);
if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
}
});

it('should correctly determine if a component is mounted', () => {
spyOnDev(console, 'error');
class Component extends React.Component {
_isMounted() {
// No longer a public API, but we can test that it works internally by
Expand All @@ -253,19 +245,13 @@ describe('ReactComponentLifeCycle', () => {

const element = <Component />;

const instance = ReactTestUtils.renderIntoDocument(element);
expect(instance._isMounted()).toBeTruthy();

if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toContain(
'Component is accessing isMounted inside its render()',
);
}
expect(() => {
const instance = ReactTestUtils.renderIntoDocument(element);
expect(instance._isMounted()).toBeTruthy();
}).toWarnDev('Component is accessing isMounted inside its render()');
});

it('should correctly determine if a null component is mounted', () => {
spyOnDev(console, 'error');
class Component extends React.Component {
_isMounted() {
// No longer a public API, but we can test that it works internally by
Expand All @@ -286,15 +272,10 @@ describe('ReactComponentLifeCycle', () => {

const element = <Component />;

const instance = ReactTestUtils.renderIntoDocument(element);
expect(instance._isMounted()).toBeTruthy();

if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toContain(
'Component is accessing isMounted inside its render()',
);
}
expect(() => {
const instance = ReactTestUtils.renderIntoDocument(element);
expect(instance._isMounted()).toBeTruthy();
}).toWarnDev('Component is accessing isMounted inside its render()');
});

it('isMounted should return false when unmounted', () => {
Expand All @@ -317,7 +298,6 @@ describe('ReactComponentLifeCycle', () => {
});

it('warns if findDOMNode is used inside render', () => {
spyOnDev(console, 'error');
class Component extends React.Component {
state = {isMounted: false};
componentDidMount() {
Expand All @@ -331,18 +311,12 @@ describe('ReactComponentLifeCycle', () => {
}
}

ReactTestUtils.renderIntoDocument(<Component />);
if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toContain(
'Component is accessing findDOMNode inside its render()',
);
}
expect(() => {
ReactTestUtils.renderIntoDocument(<Component />);
}).toWarnDev('Component is accessing findDOMNode inside its render()');
});

it('should carry through each of the phases of setup', () => {
spyOnDev(console, 'error');

class LifeCycleComponent extends React.Component {
constructor(props, context) {
super(props, context);
Expand Down Expand Up @@ -399,7 +373,13 @@ describe('ReactComponentLifeCycle', () => {
// yet initialized, or rendered.
//
const container = document.createElement('div');
const instance = ReactDOM.render(<LifeCycleComponent />, container);

let instance;
expect(() => {
instance = ReactDOM.render(<LifeCycleComponent />, container);
}).toWarnDev(
'LifeCycleComponent is accessing isMounted inside its render() function',
);

// getInitialState
expect(instance._testJournal.returnedFromGetInitialState).toEqual(
Expand Down Expand Up @@ -449,13 +429,6 @@ describe('ReactComponentLifeCycle', () => {
// But the current lifecycle of the component is unmounted.
expect(getLifeCycleState(instance)).toBe('UNMOUNTED');
expect(instance.state).toEqual(POST_WILL_UNMOUNT_STATE);

if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toContain(
'LifeCycleComponent is accessing isMounted inside its render() function',
);
}
});

it('should not throw when updating an auxiliary component', () => {
Expand Down
Loading