recoil
Version:
Recoil - A state management library for React
86 lines (82 loc) • 2.85 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 {
getRecoilTestFn
} = require('../../__test_utils__/Recoil_TestingUtils');
let React, act, selector, constSelector, errorSelector, asyncSelector, renderElements, useRecoilValueLoadable, flushPromisesAndTimers;
const testRecoil = getRecoilTestFn(() => {
React = require('react');
({
act
} = require('ReactTestUtils'));
constSelector = require('../../recoil_values/Recoil_constSelector');
errorSelector = require('../../recoil_values/Recoil_errorSelector');
selector = require('../../recoil_values/Recoil_selector');
({
asyncSelector,
renderElements,
flushPromisesAndTimers
} = require('../../__test_utils__/Recoil_TestingUtils'));
({
useRecoilValueLoadable
} = require('../Recoil_Hooks'));
}); // These tests should cover the Loadable interface returned by useRecoilValueLoadable.
// It is also used by useRecoilStateNoThrow, waitForNone, and waitForAny
testRecoil('useRecoilValueLoadable - loadable with value', async () => {
const valueSel = constSelector('VALUE');
let promise;
declare function ReadLoadable(): any;
const c = renderElements(<ReadLoadable />);
expect(c.textContent).toEqual('VALUE');
await promise;
});
testRecoil('useRecoilValueLoadable - loadable with error', async () => {
const valueSel = errorSelector('ERROR');
let promise;
declare function ReadLoadable(): any;
const c = renderElements(<ReadLoadable />);
expect(c.textContent).toEqual('VALUE');
await promise;
});
testRecoil('useRecoilValueLoadable - loading loadable', async () => {
const [valueSel, resolve] = asyncSelector();
let resolved = false;
const promises = [];
declare function ReadLoadable(): any;
const c = renderElements(<ReadLoadable />);
expect(c.textContent).toEqual('LOADING');
resolve('VALUE');
resolved = true;
act(() => jest.runAllTimers());
expect(c.textContent).toEqual('VALUE');
await Promise.all(promises.map(async promise => {
if (!(promise instanceof Promise)) {
// for flow
throw new Error('Expected a promise');
}
const res = await promise;
const val = typeof res === 'string' ? res : res.__value;
expect(val).toBe('VALUE');
}));
});
testRecoil('useRecoilValueLoadable() with an async throwing selector results in a loadable in error state', async () => {
const asyncError = selector({
key: 'asyncError',
get: async () => {
throw new Error('Test Error');
}
});
declare var Test: () => any;
const c = renderElements(<Test />);
await act(() => flushPromisesAndTimers());
expect(c.textContent).toEqual('Has error');
});