@samitouri / QOS-React / commits / 6a0c56cffc

ReactNoop.flush methods return an array of yielded values

Allows us to make assertions on the values that are yielded when performing work. In our existing tests, we do this manually by pushing into an array. ReactNoop.flushThrough extends this concept. It accepts an array of expected values and flushes until those values are yielded.

Andrew Clark committed Jun 14, 2017 at 14:32 UTC 6a0c56cffcaff62b666cdd5fbc1c02d1d3dc6402
5 files changed +102 -32
package.json
+1
@@ -67,6 +67,7 @@
67 "jest": "^19.0.1",
68 "jest-config": "^19.0.1",
69 "jest-jasmine2": "^19.0.1",
70 + "jest-matchers": "^20.0.3",
71 "jest-runtime": "^19.0.1",
72 "loose-envify": "^1.1.0",
73 "merge-stream": "^1.0.0",
scripts/rollup/bundles.js
+1 -1
@@ -338,7 +338,7 @@ const bundles = [
338 sourceMap: false,
339 },
340 entry: 'src/renderers/noop/ReactNoopEntry',
341 - externals: ['prop-types/checkPropTypes'],
341 + externals: ['prop-types/checkPropTypes', 'jest-matchers'],
342 isRenderer: true,
343 label: 'noop-fiber',
344 manglePropertiesOnProd: false,
scripts/rollup/results.json
+2 -2
@@ -145,8 +145,8 @@
145 "gzip": 2234
146 },
147 "react-noop-renderer.development.js (NODE_DEV)": {
148 - "size": 269722,
149 - "gzip": 56481
148 + "size": 272256,
149 + "gzip": 56994
150 }
151 }
152 }
\ No newline at end of file
src/renderers/noop/ReactNoopEntry.js
+52 -27
@@ -28,6 +28,8 @@ var ReactInstanceMap = require('ReactInstanceMap');
28 var {AnimationPriority} = require('ReactPriorityLevel');
29 var emptyObject = require('fbjs/lib/emptyObject');
30
31 +var expect = require('jest-matchers');
32 +
33 const UPDATE_SIGNAL = {};
34
35 var scheduledAnimationCallback = null;
@@ -219,22 +221,20 @@ var rootContainers = new Map();
221 var roots = new Map();
222 var DEFAULT_ROOT_ID = '<default>';
223
222 -let yieldBeforeNextUnitOfWork = false;
223 -let yieldValue = null;
224 +let yieldedValues = null;
225
225 -function* flushUnitsOfWork(n: number): Generator<mixed, void, void> {
226 +function* flushUnitsOfWork(
227 + n: number = Infinity,
228 +): Generator<Array<mixed>, void, void> {
229 var didStop = false;
230 while (!didStop && scheduledDeferredCallback !== null) {
231 var cb = scheduledDeferredCallback;
232 scheduledDeferredCallback = null;
230 - yieldBeforeNextUnitOfWork = false;
231 - yieldValue = null;
233 + yieldedValues = null;
234 var unitsRemaining = n;
233 - var didYield = false;
235 cb({
236 timeRemaining() {
236 - if (yieldBeforeNextUnitOfWork) {
237 - didYield = true;
237 + if (yieldedValues !== null) {
238 return 0;
239 }
240 if (unitsRemaining-- > 0) {
@@ -245,10 +245,10 @@ function* flushUnitsOfWork(n: number): Generator<mixed, void, void> {
245 },
246 });
247
248 - if (didYield) {
249 - const valueToYield = yieldValue;
250 - yieldValue = null;
251 - yield valueToYield;
248 + if (yieldedValues !== null) {
249 + const values = yieldedValues;
250 + yieldedValues = null;
251 + yield values;
252 }
253 }
254 }
@@ -308,6 +308,7 @@ var ReactNoop = {
308 return inst ? NoopRenderer.findHostInstance(inst) : null;
309 },
310
311 + // TODO: Remove this method
312 flushAnimationPri() {
313 var cb = scheduledAnimationCallback;
314 if (cb === null) {
@@ -317,47 +318,71 @@ var ReactNoop = {
318 cb();
319 },
320
320 - flushDeferredPri(timeout: number = Infinity) {
321 + flushDeferredPri(timeout: number = Infinity): Array<mixed> {
322 // The legacy version of this function decremented the timeout before
323 // returning the new time.
324 // TODO: Convert tests to use flushUnitsOfWork or flushAndYield instead.
325 const n = timeout / 5 - 1;
325 - const iterator = flushUnitsOfWork(n);
326 - let value = iterator.next();
327 - while (!value.done) {
328 - value = iterator.next();
326 +
327 + let values = [];
328 + for (const value of flushUnitsOfWork(n)) {
329 + values.push(...value);
330 }
331 // Don't flush animation priority in this legacy function. Some tests may
332 // still rely on this behavior.
333 + return values;
334 },
335
334 - flush() {
336 + flush(): Array<mixed> {
337 ReactNoop.flushAnimationPri();
336 - ReactNoop.flushDeferredPri();
338 + return ReactNoop.flushDeferredPri();
339 },
340
339 - *flushAndYield(unitsOfWork: number = Infinity): Generator<mixed, void, void> {
341 + *flushAndYield(
342 + unitsOfWork: number = Infinity,
343 + ): Generator<Array<mixed>, void, void> {
344 for (const value of flushUnitsOfWork(unitsOfWork)) {
345 yield value;
346 }
347 ReactNoop.flushAnimationPri();
348 },
349
346 - flushUnitsOfWork(n: number) {
347 - const iterator = flushUnitsOfWork(n);
348 - let value = iterator.next();
349 - while (!value.done) {
350 - value = iterator.next();
350 + flushUnitsOfWork(n: number): Array<mixed> {
351 + let values = [];
352 + for (const value of flushUnitsOfWork(n)) {
353 + values.push(...value);
354 }
355 // TODO: We should always flush animation priority after flushing normal/low
356 // priority. Move this to flushUnitsOfWork generator once tests
357 // are converted.
358 ReactNoop.flushAnimationPri();
359 + return values;
360 + },
361 +
362 + flushThrough(expected: Array<mixed>): void {
363 + let actual = [];
364 + if (expected.length !== 0) {
365 + for (const value of flushUnitsOfWork()) {
366 + actual.push(...value);
367 + if (actual.length >= expected.length) {
368 + break;
369 + }
370 + }
371 + }
372 + ReactNoop.flushAnimationPri();
373 + expect(actual).toEqual(expected);
374 },
375
376 yield(value: mixed) {
359 - yieldBeforeNextUnitOfWork = true;
360 - yieldValue = value;
377 + if (yieldedValues === null) {
378 + yieldedValues = [value];
379 + } else {
380 + yieldedValues.push(value);
381 + }
382 + },
383 +
384 + hasScheduledDeferredCallback() {
385 + return !!scheduledDeferredCallback;
386 },
387
388 performAnimationWork(fn: Function) {
yarn.lock
+46 -2
@@ -90,7 +90,7 @@ ansi-escapes@^1.1.0, ansi-escapes@^1.4.0:
90 version "1.4.0"
91 resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
92
93 -ansi-regex@^2.0.0:
93 +ansi-regex@^2.0.0, ansi-regex@^2.1.1:
94 version "2.1.1"
95 resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
96
@@ -1745,7 +1745,7 @@ devtools-timeline-model@1.1.6:
1745 chrome-devtools-frontend "1.0.401423"
1746 resolve "1.1.7"
1747
1748 -diff@^3.0.0:
1748 +diff@^3.0.0, diff@^3.2.0:
1749 version "3.2.0"
1750 resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
1751
@@ -3199,6 +3199,15 @@ jest-diff@^19.0.0:
3199 jest-matcher-utils "^19.0.0"
3200 pretty-format "^19.0.0"
3201
3202 +jest-diff@^20.0.3:
3203 + version "20.0.3"
3204 + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-20.0.3.tgz#81f288fd9e675f0fb23c75f1c2b19445fe586617"
3205 + dependencies:
3206 + chalk "^1.1.3"
3207 + diff "^3.2.0"
3208 + jest-matcher-utils "^20.0.3"
3209 + pretty-format "^20.0.3"
3210 +
3211 jest-environment-jsdom@^19.0.2:
3212 version "19.0.2"
3213 resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-19.0.2.tgz#ceda859c4a4b94ab35e4de7dab54b926f293e4a3"
@@ -3245,6 +3254,13 @@ jest-matcher-utils@^19.0.0:
3254 chalk "^1.1.3"
3255 pretty-format "^19.0.0"
3256
3257 +jest-matcher-utils@^20.0.3:
3258 + version "20.0.3"
3259 + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz#b3a6b8e37ca577803b0832a98b164f44b7815612"
3260 + dependencies:
3261 + chalk "^1.1.3"
3262 + pretty-format "^20.0.3"
3263 +
3264 jest-matchers@^19.0.0:
3265 version "19.0.0"
3266 resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-19.0.0.tgz#c74ecc6ebfec06f384767ba4d6fa4a42d6755754"
@@ -3254,6 +3270,15 @@ jest-matchers@^19.0.0:
3270 jest-message-util "^19.0.0"
3271 jest-regex-util "^19.0.0"
3272
3273 +jest-matchers@^20.0.3:
3274 + version "20.0.3"
3275 + resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-20.0.3.tgz#ca69db1c32db5a6f707fa5e0401abb55700dfd60"
3276 + dependencies:
3277 + jest-diff "^20.0.3"
3278 + jest-matcher-utils "^20.0.3"
3279 + jest-message-util "^20.0.3"
3280 + jest-regex-util "^20.0.3"
3281 +
3282 jest-message-util@^19.0.0:
3283 version "19.0.0"
3284 resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-19.0.0.tgz#721796b89c0e4d761606f9ba8cb828a3b6246416"
@@ -3261,6 +3286,14 @@ jest-message-util@^19.0.0:
3286 chalk "^1.1.1"
3287 micromatch "^2.3.11"
3288
3289 +jest-message-util@^20.0.3:
3290 + version "20.0.3"
3291 + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-20.0.3.tgz#6aec2844306fcb0e6e74d5796c1006d96fdd831c"
3292 + dependencies:
3293 + chalk "^1.1.3"
3294 + micromatch "^2.3.11"
3295 + slash "^1.0.0"
3296 +
3297 jest-mock@^19.0.0:
3298 version "19.0.0"
3299 resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-19.0.0.tgz#67038641e9607ab2ce08ec4a8cb83aabbc899d01"
@@ -3269,6 +3302,10 @@ jest-regex-util@^19.0.0:
3302 version "19.0.0"
3303 resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-19.0.0.tgz#b7754587112aede1456510bb1f6afe74ef598691"
3304
3305 +jest-regex-util@^20.0.3:
3306 + version "20.0.3"
3307 + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-20.0.3.tgz#85bbab5d133e44625b19faf8c6aa5122d085d762"
3308 +
3309 jest-resolve-dependencies@^19.0.0:
3310 version "19.0.0"
3311 resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-19.0.0.tgz#a741ad1fa094140e64ecf2642a504f834ece22ee"
@@ -4319,6 +4356,13 @@ pretty-format@^19.0.0:
4356 dependencies:
4357 ansi-styles "^3.0.0"
4358
4359 +pretty-format@^20.0.3:
4360 + version "20.0.3"
4361 + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-20.0.3.tgz#020e350a560a1fe1a98dc3beb6ccffb386de8b14"
4362 + dependencies:
4363 + ansi-regex "^2.1.1"
4364 + ansi-styles "^3.0.0"
4365 +
4366 private@^0.1.6, private@~0.1.5:
4367 version "0.1.7"
4368 resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"