Skip to content

Add new mock build of Scheduler with flush, yield API #14964

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

Merged
merged 3 commits into from
Feb 27, 2019

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Feb 27, 2019

Test environments need a way to take control of the Scheduler queue and incrementally flush work. Our current tests accomplish this either using dynamic injection, or by using Jest's fake timers feature. Both of these options are fragile and rely too much on implementation details.

In this new approach, we have a separate build of Scheduler that is specifically designed for test environments. We mock the default implementation like we would any other module; in our case, via Jest. This special build has methods like flushAll and yieldValue that control when work is flushed. These methods are based on equivalent methods we've been using to write incremental React tests. Eventually we may want to migrate the React tests to interact with the mock Scheduler directly, instead of going through the host config like we currently do.

For now, I'm using our custom static injection infrastructure to create the two builds of Scheduler — a default build for DOM (which falls back to a naive timer based implementation), and the new mock build. I did it this way because it allows me to share most of the implementation, which isn't specific to a host environment — e.g. everything related to the priority queue. It may be better to duplicate the shared code instead, especially considering that future environments (like React Native) may have entirely forked implementations. I'd prefer to wait until the implementation stabilizes before worrying about that, but I'm open to changing this now if we decide it's important enough.

@sizebot
Copy link

sizebot commented Feb 27, 2019

React: size: -0.9%, gzip: -1.2%

Details of bundled changes.

Comparing: 4186952...22d197d

react

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react.development.js -0.4% -0.4% 100.06 KB 99.67 KB 25.96 KB 25.85 KB UMD_DEV
react.production.min.js -0.9% -1.2% 12.41 KB 12.29 KB 4.79 KB 4.73 KB UMD_PROD
react.profiling.min.js -0.8% -1.1% 14.57 KB 14.45 KB 5.3 KB 5.25 KB UMD_PROFILING
react.development.js 0.0% -0.0% 62.24 KB 62.24 KB 16.8 KB 16.79 KB NODE_DEV
React-dev.js 0.0% -0.0% 59.38 KB 59.38 KB 15.78 KB 15.78 KB FB_WWW_DEV

scheduler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
scheduler.development.js -1.6% -2.6% 23.34 KB 22.96 KB 6.04 KB 5.89 KB NODE_DEV
scheduler.production.min.js -2.3% -3.5% 4.89 KB 4.78 KB 1.85 KB 1.78 KB NODE_PROD
Scheduler-dev.js -1.6% -2.6% 23.57 KB 23.2 KB 6.08 KB 5.92 KB FB_WWW_DEV
Scheduler-prod.js -2.2% -4.0% 14.01 KB 13.7 KB 2.89 KB 2.77 KB FB_WWW_PROD
scheduler-unstable_mock.development.js n/a n/a 0 B 17.51 KB 0 B 4.04 KB NODE_DEV
scheduler-unstable_mock.production.min.js n/a n/a 0 B 4.08 KB 0 B 1.58 KB NODE_PROD
SchedulerMock-dev.js n/a n/a 0 B 17.74 KB 0 B 4.08 KB FB_WWW_DEV
SchedulerMock-prod.js n/a n/a 0 B 11.8 KB 0 B 2.42 KB FB_WWW_PROD
scheduler-tracing.development.js 0.0% -0.0% 10.49 KB 10.49 KB 2.49 KB 2.49 KB NODE_DEV
scheduler-tracing.profiling.min.js 0.0% -0.2% 3.26 KB 3.26 KB 1002 B 1000 B NODE_PROFILING

Generated by 🚫 dangerJS

Test environments need a way to take control of the Scheduler queue and
incrementally flush work. Our current tests accomplish this either using
dynamic injection, or by using Jest's fake timers feature. Both of these
options are fragile and rely too much on implementation details.

In this new approach, we have a separate build of Scheduler that is
specifically designed for test environments. We mock the default
implementation like we would any other module; in our case, via Jest.
This special build has methods like `flushAll` and `yieldValue` that
control when work is flushed. These methods are based on equivalent
methods we've been using to write incremental React tests. Eventually
we may want to migrate the React tests to interact with the mock
Scheduler directly, instead of going through the host config like we
currently do.

For now, I'm using our custom static injection infrastructure to create
the two builds of Scheduler — a default build for DOM (which falls back
to a naive timer based implementation), and the new mock build. I did it
this way because it allows me to share most of the implementation, which
isn't specific to a host environment — e.g. everything related to the
priority queue. It may be better to duplicate the shared code instead,
especially considering that future environments (like React Native) may
have entirely forked implementations. I'd prefer to wait until the
implementation stabilizes before worrying about that, but I'm open to
changing this now if we decide it's important enough.
// for specific modules.
moduleNameMapper['^scheduler$'] = `<rootDir>/build/node_modules/scheduler`;
moduleNameMapper['^scheduler/tracing$'] =
'<rootDir>/build/node_modules/scheduler/tracing';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this not just the same as below? Can you get rid of this special case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, got it working by changing the regex to only match the top level directory per package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants