diff --git a/packages/react-test-renderer/src/ReactTestRendererScheduling.js b/packages/react-test-renderer/src/ReactTestRendererScheduling.js index 8638c0e760..b37f8c6b48 100644 --- a/packages/react-test-renderer/src/ReactTestRendererScheduling.js +++ b/packages/react-test-renderer/src/ReactTestRendererScheduling.js @@ -80,7 +80,22 @@ export function flushThrough(expectedValues: Array): Array { } if (yieldedValues === null) { // Always return an array. - return []; + yieldedValues = []; + } + for (let i = 0; i < expectedValues.length; i++) { + const expectedValue = `"${(expectedValues[i]: any)}"`; + const yieldedValue = + i < yieldedValues.length ? `"${(yieldedValues[i]: any)}"` : 'nothing'; + if (yieldedValue !== expectedValue) { + const error = new Error( + `flushThrough expected to yield ${(expectedValue: any)}, but ${(yieldedValue: any)} was yielded`, + ); + // Attach expected and yielded arrays, + // So the caller could pretty print the diff (if desired). + (error: any).expectedValues = expectedValues; + (error: any).actualValues = yieldedValues; + throw error; + } } return yieldedValues; } diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js index 26a3de6746..e44bf0cb17 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js @@ -10,10 +10,16 @@ 'use strict'; -const React = require('react'); -const ReactTestRenderer = require('react-test-renderer'); +let React; +let ReactTestRenderer; describe('ReactTestRendererAsync', () => { + beforeEach(() => { + jest.resetModules(); + React = require('react'); + ReactTestRenderer = require('react-test-renderer'); + }); + it('flushAll flushes all work', () => { function Foo(props) { return props.children; @@ -134,4 +140,56 @@ describe('ReactTestRendererAsync', () => { // Only the higher priority properties have been committed expect(renderer.toJSON()).toEqual(['A:2', 'B:2']); }); + + it('should error if flushThrough params dont match yielded values', () => { + const Yield = ({id}) => { + renderer.unstable_yield(id); + return id; + }; + + const renderer = ReactTestRenderer.create( +
+ + + +
, + { + unstable_isAsync: true, + }, + ); + + expect(() => renderer.unstable_flushThrough(['foo', 'baz'])).toThrow( + 'flushThrough expected to yield "baz", but "bar" was yielded', + ); + }); + + it('should error if flushThrough yields the wrong number of values', () => { + const Yield = ({id}) => { + renderer.unstable_yield(id); + return id; + }; + + const renderer = ReactTestRenderer.create( +
+ +
, + { + unstable_isAsync: true, + }, + ); + + expect(() => renderer.unstable_flushThrough(['foo', 'bar'])).toThrow( + 'flushThrough expected to yield "bar", but nothing was yielded', + ); + }); + + it('should error if flushThrough yields no values', () => { + const renderer = ReactTestRenderer.create(null, { + unstable_isAsync: true, + }); + + expect(() => renderer.unstable_flushThrough(['foo'])).toThrow( + 'flushThrough expected to yield "foo", but nothing was yielded', + ); + }); });