UNPKG

recoil

Version:

Recoil - A state management library for React

124 lines (121 loc) 3.96 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. Confidential and proprietary. * * @emails oncall+recoil * @flow strict-local * @format */ 'use strict'; import type { Store } from '../Recoil_State'; const { getRecoilTestFn } = require('../../testing/Recoil_TestingUtils'); let React, ReactDOM, act, useSetRecoilState, atom, constSelector, selector, ReadsAtom, renderElements, RecoilRoot, useStoreRef; const testRecoil = getRecoilTestFn(() => { React = require('React'); ReactDOM = require('ReactDOM'); ({ act } = require('ReactTestUtils')); ({ useSetRecoilState } = require('../../hooks/Recoil_Hooks')); atom = require('../../recoil_values/Recoil_atom'); constSelector = require('../../recoil_values/Recoil_constSelector'); selector = require('../../recoil_values/Recoil_selector'); ({ ReadsAtom, renderElements } = require('../../testing/Recoil_TestingUtils')); ({ RecoilRoot } = require('../Recoil_RecoilRoot.react')); ({ useStoreRef } = require('../Recoil_RecoilRoot.react')); }); describe('initializeState', () => { testRecoil('initialize atom', () => { const myAtom = atom({ key: 'RecoilRoot - initializeState - atom', default: 'DEFAULT' }); const mySelector = constSelector(myAtom); declare function initializeState(arg0: any): any; const container = document.createElement('div'); act(() => { ReactDOM.render(<RecoilRoot initializeState={initializeState}> <ReadsAtom atom={myAtom} /> <ReadsAtom atom={mySelector} /> </RecoilRoot>, container); }); expect(container.textContent).toEqual('"INITIALIZE""INITIALIZE"'); }); testRecoil('initialize selector', () => { const myAtom = atom({ key: 'RecoilRoot - initializeState - selector', default: 'DEFAULT' }); const mySelector = selector({ key: 'RecoilRoot - initializeState - selector selector', get: ({ get }) => get(myAtom), set: ({ set }, newValue) => set(myAtom, newValue) }); declare function initializeState(arg0: any): any; const container = document.createElement('div'); act(() => { ReactDOM.render(<RecoilRoot initializeState={initializeState}> <ReadsAtom atom={myAtom} /> <ReadsAtom atom={mySelector} /> </RecoilRoot>, container); }); expect(container.textContent).toEqual('"INITIALIZE""INITIALIZE"'); }); testRecoil('initialize with nested store', () => { declare var GetStore: (arg0: { children: (Store) => React.Node }) => any; const container = document.createElement('div'); act(() => { ReactDOM.render(<RecoilRoot> <GetStore> {storeA => <RecoilRoot store_INTERNAL={storeA}> <GetStore> {storeB => { expect(storeA === storeB).toBe(true); return 'NESTED_ROOT/'; }} </GetStore> </RecoilRoot>} </GetStore> ROOT </RecoilRoot>, container); }); expect(container.textContent).toEqual('NESTED_ROOT/ROOT'); }); }); testRecoil('Impure state updater functions that trigger atom updates are detected', () => { // This test ensures that we throw a clean error rather than mysterious breakage // if the user supplies a state updater function that triggers another update // within its execution. These state updater functions are supposed to be pure. // We can't detect all forms of impurity but this one in particular will make // Recoil break, so we detect it and throw an error. const atomA = atom({ key: 'RecoilRoot/impureUpdater/a', default: 0 }); const atomB = atom({ key: 'RecoilRoot/impureUpdater/b', default: 0 }); let update; declare function Component(): any; renderElements(<Component />); expect(() => act(() => { update(); })).toThrow('pure function'); });