-
Notifications
You must be signed in to change notification settings - Fork 51k
Test renderer flushAll method verifies an array of expected yields #13174
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,7 @@ import type {Deadline} from 'react-reconciler/src/ReactFiberScheduler'; | |
| // Current virtual time | ||
| export let nowImplementation = () => 0; | ||
| export let scheduledCallback: ((deadline: Deadline) => mixed) | null = null; | ||
| export let yieldedValues: Array<mixed> | null = null; | ||
| export let yieldedValues: Array<mixed> = []; | ||
|
|
||
| export function scheduleDeferredCallback( | ||
| callback: (deadline: Deadline) => mixed, | ||
|
|
@@ -31,8 +31,39 @@ export function setNowImplementation(implementation: () => number): void { | |
| nowImplementation = implementation; | ||
| } | ||
|
|
||
| export function flushAll(): Array<mixed> { | ||
| yieldedValues = null; | ||
| function verifyExpectedValues(expectedValues: Array<mixed>): void { | ||
| 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( | ||
| `Flush 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; | ||
| } | ||
| } | ||
|
|
||
| if (expectedValues.length !== yieldedValues.length) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normally I would have put this check before the prior one, but that would change the error message in a lot of cases and I suspect the current message might be more helpful. Thoughts?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, I like throwing the more specific error first. |
||
| const error = new Error( | ||
| `Flush expected to yield ${expectedValues.length} values, but yielded ${ | ||
| yieldedValues.length | ||
| }`, | ||
| ); | ||
| // Attach expected and yielded arrays, | ||
| // So the caller could pretty print the diff (if desired). | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we please go ahead and implement this for the React repo? @cyan33 You want to do this?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of Course 👍 |
||
| (error: any).expectedValues = expectedValues; | ||
| (error: any).actualValues = yieldedValues; | ||
| throw error; | ||
| } | ||
| } | ||
|
|
||
| export function flushAll(expectedValues: Array<mixed>): Array<mixed> { | ||
| yieldedValues = []; | ||
| while (scheduledCallback !== null) { | ||
| const cb = scheduledCallback; | ||
| scheduledCallback = null; | ||
|
|
@@ -47,25 +78,19 @@ export function flushAll(): Array<mixed> { | |
| didTimeout: false, | ||
| }); | ||
| } | ||
| if (yieldedValues === null) { | ||
| // Always return an array. | ||
| return []; | ||
| } | ||
| verifyExpectedValues(expectedValues); | ||
| return yieldedValues; | ||
| } | ||
|
|
||
| export function flushThrough(expectedValues: Array<mixed>): Array<mixed> { | ||
| let didStop = false; | ||
| yieldedValues = null; | ||
| yieldedValues = []; | ||
| while (scheduledCallback !== null && !didStop) { | ||
| const cb = scheduledCallback; | ||
| scheduledCallback = null; | ||
| cb({ | ||
| timeRemaining() { | ||
| if ( | ||
| yieldedValues !== null && | ||
| yieldedValues.length >= expectedValues.length | ||
| ) { | ||
| if (yieldedValues.length >= expectedValues.length) { | ||
| // We at least as many values as expected. Stop rendering. | ||
| didStop = true; | ||
| return 0; | ||
|
|
@@ -79,34 +104,12 @@ export function flushThrough(expectedValues: Array<mixed>): Array<mixed> { | |
| didTimeout: false, | ||
| }); | ||
| } | ||
| if (yieldedValues === null) { | ||
| // Always return an array. | ||
| 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; | ||
| } | ||
| } | ||
| verifyExpectedValues(expectedValues); | ||
| return yieldedValues; | ||
| } | ||
|
|
||
| export function yieldValue(value: mixed): void { | ||
| if (yieldedValues === null) { | ||
| yieldedValues = [value]; | ||
| } else { | ||
| yieldedValues.push(value); | ||
| } | ||
| yieldedValues.push(value); | ||
| } | ||
|
|
||
| export function withCleanYields(fn: Function) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transient
nullvalue didn't seem to be buying us anything, and it complicated the logic below– so I ditched it.