diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt index c08b2f74e42a..f642283bdbb9 100644 --- a/scripts/fiber/tests-passing.txt +++ b/scripts/fiber/tests-passing.txt @@ -1955,6 +1955,9 @@ src/renderers/dom/test/__tests__/ReactTestUtils-test.js * can setState in componentWillMount when shallow rendering * can setState in componentWillReceiveProps when shallow rendering * can setState with an updater function +* can setState with a callback +* can replaceState with a callback +* can forceUpdate with a callback * can pass context when shallowly rendering * should track context across updates * can fail context when shallowly rendering diff --git a/src/renderers/dom/test/__tests__/ReactTestUtils-test.js b/src/renderers/dom/test/__tests__/ReactTestUtils-test.js index 624bc9c9fed7..b86f3fa0a278 100644 --- a/src/renderers/dom/test/__tests__/ReactTestUtils-test.js +++ b/src/renderers/dom/test/__tests__/ReactTestUtils-test.js @@ -405,6 +405,108 @@ describe('ReactTestUtils', () => { expect(result.props.children).toEqual(2); }); + it('can setState with a callback', () => { + let instance; + + class SimpleComponent extends React.Component { + state = { + counter: 0, + }; + render() { + instance = this; + return ( +

+ {this.state.counter} +

+ ); + } + } + + const shallowRenderer = createRenderer(); + const result = shallowRenderer.render(); + expect(result.props.children).toBe(0); + + const callback = jest.fn(function() { + expect(this).toBe(instance); + }); + + instance.setState({counter: 1}, callback); + + const updated = shallowRenderer.getRenderOutput(); + expect(updated.props.children).toBe(1); + expect(callback).toHaveBeenCalled(); + }); + + it('can replaceState with a callback', () => { + let instance; + + class SimpleComponent extends React.Component { + state = { + counter: 0, + }; + render() { + instance = this; + return ( +

+ {this.state.counter} +

+ ); + } + } + + const shallowRenderer = createRenderer(); + const result = shallowRenderer.render(); + expect(result.props.children).toBe(0); + + const callback = jest.fn(function() { + expect(this).toBe(instance); + }); + + // No longer a public API, but we can test that it works internally by + // reaching into the updater. + shallowRenderer._updater.enqueueReplaceState( + instance, + {counter: 1}, + callback, + ); + + const updated = shallowRenderer.getRenderOutput(); + expect(updated.props.children).toBe(1); + expect(callback).toHaveBeenCalled(); + }); + + it('can forceUpdate with a callback', () => { + let instance; + + class SimpleComponent extends React.Component { + state = { + counter: 0, + }; + render() { + instance = this; + return ( +

+ {this.state.counter} +

+ ); + } + } + + const shallowRenderer = createRenderer(); + const result = shallowRenderer.render(); + expect(result.props.children).toBe(0); + + const callback = jest.fn(function() { + expect(this).toBe(instance); + }); + + instance.forceUpdate(callback); + + const updated = shallowRenderer.getRenderOutput(); + expect(updated.props.children).toBe(0); + expect(callback).toHaveBeenCalled(); + }); + it('can pass context when shallowly rendering', () => { class SimpleComponent extends React.Component { static contextTypes = { diff --git a/src/renderers/testing/ReactShallowRendererEntry.js b/src/renderers/testing/ReactShallowRendererEntry.js index 640b0b253daa..ac610f1caf05 100644 --- a/src/renderers/testing/ReactShallowRendererEntry.js +++ b/src/renderers/testing/ReactShallowRendererEntry.js @@ -201,11 +201,19 @@ class Updater { enqueueForceUpdate(publicInstance, callback, callerName) { this._renderer.render(this._renderer._element, this._renderer._context); + + if (typeof callback === 'function') { + callback.call(publicInstance); + } } enqueueReplaceState(publicInstance, completeState, callback, callerName) { this._renderer._newState = completeState; this._renderer.render(this._renderer._element, this._renderer._context); + + if (typeof callback === 'function') { + callback.call(publicInstance); + } } enqueueSetState(publicInstance, partialState, callback, callerName) { @@ -219,6 +227,10 @@ class Updater { }; this._renderer.render(this._renderer._element, this._renderer._context); + + if (typeof callback === 'function') { + callback.call(publicInstance); + } } }