2017-04-27 20:13:03 +08:00
|
|
|
/**
|
2018-09-08 06:11:23 +08:00
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
2017-04-27 20:13:03 +08:00
|
|
|
*
|
2017-09-25 04:48:13 +08:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2017-04-27 20:13:03 +08:00
|
|
|
*
|
|
|
|
|
* @emails react-core
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
2017-09-28 00:14:27 +08:00
|
|
|
describe('ReactDOMFrameScheduling', () => {
|
Add new mock build of Scheduler with flush, yield API (#14964)
* Add new mock build of Scheduler with flush, yield API
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.
* Mock Scheduler in bundle tests, too
* Remove special case by making regex more restrictive
2019-02-27 12:51:17 +08:00
|
|
|
beforeEach(() => {
|
|
|
|
|
jest.resetModules();
|
|
|
|
|
|
|
|
|
|
// Un-mock scheduler
|
|
|
|
|
jest.mock('scheduler', () => require.requireActual('scheduler'));
|
|
|
|
|
});
|
|
|
|
|
|
2017-08-03 01:55:18 +08:00
|
|
|
it('warns when requestAnimationFrame is not polyfilled in the browser', () => {
|
2017-04-27 20:13:03 +08:00
|
|
|
const previousRAF = global.requestAnimationFrame;
|
2018-11-15 06:33:35 +08:00
|
|
|
const previousMessageChannel = global.MessageChannel;
|
2017-04-27 20:13:03 +08:00
|
|
|
try {
|
2018-11-15 06:33:35 +08:00
|
|
|
delete global.requestAnimationFrame;
|
|
|
|
|
global.MessageChannel = function MessageChannel() {
|
|
|
|
|
return {
|
|
|
|
|
port1: {},
|
|
|
|
|
port2: {},
|
|
|
|
|
};
|
|
|
|
|
};
|
[schedule] Refactor Schedule, remove React-isms (#13582)
* Refactor Schedule, remove React-isms
Once the API stabilizes, we will move Schedule this into a separate
repo. To promote adoption, especially by projects outside the React
ecosystem, we'll remove all React-isms from the source and keep it as
simple as possible:
- No build step.
- No static types.
- Everything is in a single file.
If we end up needing to support multiple targets, like CommonJS and ESM,
we can still avoid a build step by maintaining two copies of the same
file, but with different exports.
This commit also refactors the implementation to split out the DOM-
specific parts (essentially a requestIdleCallback polyfill). Aside from
the architectural benefits, this also makes it possible to write host-
agnostic tests. If/when we publish a version of Schedule that targets
other environments, like React Native, we can run these same tests
across all implementations.
* Edits in response to Dan's PR feedback
2018-09-15 05:05:55 +08:00
|
|
|
spyOnDevAndProd(console, 'error');
|
|
|
|
|
require('react-dom');
|
2019-05-11 04:51:39 +08:00
|
|
|
expect(console.error.calls.count()).toEqual(1);
|
[schedule] Refactor Schedule, remove React-isms (#13582)
* Refactor Schedule, remove React-isms
Once the API stabilizes, we will move Schedule this into a separate
repo. To promote adoption, especially by projects outside the React
ecosystem, we'll remove all React-isms from the source and keep it as
simple as possible:
- No build step.
- No static types.
- Everything is in a single file.
If we end up needing to support multiple targets, like CommonJS and ESM,
we can still avoid a build step by maintaining two copies of the same
file, but with different exports.
This commit also refactors the implementation to split out the DOM-
specific parts (essentially a requestIdleCallback polyfill). Aside from
the architectural benefits, this also makes it possible to write host-
agnostic tests. If/when we publish a version of Schedule that targets
other environments, like React Native, we can run these same tests
across all implementations.
* Edits in response to Dan's PR feedback
2018-09-15 05:05:55 +08:00
|
|
|
expect(console.error.calls.argsFor(0)[0]).toMatch(
|
2018-06-14 01:57:35 +08:00
|
|
|
"This browser doesn't support requestAnimationFrame.",
|
2018-01-04 05:55:37 +08:00
|
|
|
);
|
2017-04-27 20:13:03 +08:00
|
|
|
} finally {
|
2018-11-15 06:33:35 +08:00
|
|
|
global.MessageChannel = previousMessageChannel;
|
2017-04-27 20:13:03 +08:00
|
|
|
global.requestAnimationFrame = previousRAF;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// We're just testing importing, not using it.
|
|
|
|
|
// It is important because even isomorphic components may import it.
|
2020-11-03 01:46:58 +08:00
|
|
|
// @gate !source
|
2017-04-27 20:13:03 +08:00
|
|
|
it('can import findDOMNode in Node environment', () => {
|
|
|
|
|
const previousRAF = global.requestAnimationFrame;
|
|
|
|
|
const previousRIC = global.requestIdleCallback;
|
|
|
|
|
const prevWindow = global.window;
|
|
|
|
|
try {
|
|
|
|
|
global.requestAnimationFrame = undefined;
|
|
|
|
|
global.requestIdleCallback = undefined;
|
|
|
|
|
// Simulate the Node environment:
|
|
|
|
|
delete global.window;
|
|
|
|
|
jest.resetModules();
|
|
|
|
|
expect(() => {
|
2017-06-15 05:10:33 +08:00
|
|
|
require('react-dom');
|
2017-04-27 20:13:03 +08:00
|
|
|
}).not.toThrow();
|
|
|
|
|
} finally {
|
|
|
|
|
global.requestAnimationFrame = previousRAF;
|
|
|
|
|
global.requestIdleCallback = previousRIC;
|
|
|
|
|
global.window = prevWindow;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|