recoil
Version:
Recoil - A state management library for React
85 lines (78 loc) • 2.88 kB
Flow
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+recoil
* @flow strict-local
* @format
*/
;
const {
IS_INTERNAL,
getRecoilTestFn
} = require('../../__test_utils__/Recoil_TestingUtils');
let React, act, gkx, useTransition, useRecoilState, atom, renderElementsInConcurrentRoot, flushPromisesAndTimers;
const testRecoil = getRecoilTestFn(() => {
React = require('react');
({
useTransition
} = React);
({
act
} = require('ReactTestUtils'));
gkx = require('../../util/Recoil_gkx');
({
useRecoilState,
atom
} = require('../../Recoil_index'));
({
renderElementsInConcurrentRoot,
flushPromisesAndTimers
} = require('../../__test_utils__/Recoil_TestingUtils'));
const initialGKValue = gkx('recoil_early_rendering_2021');
gkx.setPass('recoil_early_rendering_2021');
return () => {
initialGKValue || gkx.setFail('recoil_early_rendering_2021');
};
});
let nextID = 0;
testRecoil('Works with useTransition', async () => {
if (!IS_INTERNAL) {
return; // FIXME: these tests do not work in OSS, possibly due to differing ReactDOM in OSS and internal
}
const indexAtom = atom({
key: `index${nextID++}`,
default: 0
}); // Basic implementation of a cache that suspends:
const cache = new Map();
const resolvers = [];
declare function getItem(index: any): any;
declare function ItemContents(arg0: any): any;
declare function Item(arg0: any): any;
let incrementIndex;
declare function Main(): any;
const c = renderElementsInConcurrentRoot(<Main />); // Initial load:
expect(c.textContent).toEqual('Index: 0 - Suspended');
act(() => resolvers[0]());
await flushPromisesAndTimers();
expect(c.textContent).toEqual('Index: 0 - Item 0 = v0'); // Increment index a single time; see previous item in transition, then once
// the new item resolves, see the new item:
act(() => incrementIndex());
expect(c.textContent).toEqual('Index: 0 - In transition - Item 0 = v0');
act(() => resolvers[1]());
await flushPromisesAndTimers();
expect(c.textContent).toEqual('Index: 1 - Item 1 = v1'); // Increment index a second time during transition; see previous item in
// transition, then once the new _second_ item resolves, see that new item:
act(() => incrementIndex());
expect(c.textContent).toEqual('Index: 1 - In transition - Item 1 = v1');
act(() => incrementIndex());
expect(c.textContent).toEqual('Index: 1 - In transition - Item 1 = v1');
act(() => resolvers[2]());
await flushPromisesAndTimers();
expect(c.textContent).toEqual('Index: 1 - In transition - Item 1 = v1');
act(() => resolvers[3]());
await flushPromisesAndTimers();
expect(c.textContent).toEqual('Index: 3 - Item 3 = v3');
});