forked from ampproject/amphtml
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bento unit tests: flush all hooks/renders after each test run (amppro…
…ject#36261) * test-amp-iframe: use act() to flush effects * generic solution * clean up * address feedback * clean up, address feedback * fixes + new bug? * improve flush() * cleanup * address jridgewell feedback * fix bad merge conflict * missed an await
- Loading branch information
Showing
4 changed files
with
72 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import * as preact from /*OK*/ 'preact'; | ||
|
||
/** | ||
* This file introduces a helper for draining Preact's queue of renders and effects. | ||
* We use this as part of the afterEach() cleanup in unit tests, to ensure no effects are run | ||
* in subsequent tests. | ||
* | ||
* There is still a test isolation issue in that an effect can asynchronously schedule work | ||
* which cannot be guarded from at this layer. For that we'd likely need to refresh the window | ||
* in between each test run. | ||
* | ||
* We should be able to remove this file if this feature lands in Preact. | ||
* @fileoverview | ||
*/ | ||
|
||
const rafs = []; | ||
/** | ||
* @param {(ts: (DOMHighResTimeStamp) => number)} cb | ||
* @return {number} | ||
*/ | ||
function flushableRaf(cb) { | ||
rafs.push(cb); | ||
return requestAnimationFrame(flushRaf); | ||
} | ||
|
||
function flushRaf(ts = performance.now()) { | ||
for (const raf of rafs) { | ||
raf(ts); | ||
} | ||
rafs.length = 0; | ||
} | ||
|
||
let pendingRender; | ||
|
||
/** | ||
* @param {() => void} process | ||
* @return {Promise<void>} | ||
*/ | ||
async function flushableRender(process) { | ||
pendingRender = () => { | ||
pendingRender = null; | ||
return process(); | ||
}; | ||
await Promise.resolve().then(pendingRender); | ||
} | ||
|
||
/** | ||
* Flushes Preact renders and effects. | ||
* | ||
* Effects may queue up further rerenders, etc. etc, | ||
* so this function will loop until everything to resolves. | ||
* | ||
* @return {Promise<void>} | ||
*/ | ||
export async function flush() { | ||
flushRaf(); | ||
while (pendingRender) { | ||
await pendingRender(); | ||
flushRaf(); | ||
} | ||
} | ||
|
||
preact.options.requestAnimationFrame = flushableRaf; | ||
preact.options.debounceRendering = flushableRender; |