UNPKG

recoil

Version:

Recoil - A state management library for React

119 lines (114 loc) 4.78 kB
/** * 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 */ 'use strict'; const { getRecoilTestFn } = require('../../__test_utils__/Recoil_TestingUtils'); let TreeCache, loadableWithValue, nullthrows; const testRecoil = getRecoilTestFn(() => { ({ TreeCache } = require('../Recoil_TreeCache')); nullthrows = require('../../util/Recoil_nullthrows'); ({ loadableWithValue } = require('../../adt/Recoil_Loadable')); }); describe('TreeCache', () => { testRecoil('setting and getting values', () => { const cache = new TreeCache(); const [route1, loadable1] = [[['a', 2], ['b', 3]], loadableWithValue('value1')]; const [route2, loadable2] = [[['a', 3], ['b', 4]], loadableWithValue('value2')]; const [route3, loadable3] = [[['a', 4]], loadableWithValue('value3')]; cache.set(route1, loadable1); cache.set(route2, loadable2); cache.set(route3, loadable3); expect(cache.get(nodeKey => route1.find(([key]) => key === nodeKey)?.[1])).toBe(loadable1); expect(cache.get(nodeKey => route2.find(([key]) => key === nodeKey)?.[1])).toBe(loadable2); expect(cache.get(nodeKey => route3.find(([key]) => key === nodeKey)?.[1])).toBe(loadable3); expect(cache.size()).toBe(3); }); testRecoil('deleting values', () => { const cache = new TreeCache(); const [route1, loadable1] = [[['a', 2], ['b', 3]], loadableWithValue('value1')]; const [route2, loadable2] = [[['a', 3], ['b', 4]], loadableWithValue('value2')]; const [route3, loadable3] = [[['a', 4]], loadableWithValue('value3')]; cache.set(route1, loadable1); cache.set(route2, loadable2); cache.set(route3, loadable3); const leaf1 = cache.getLeafNode(nodeKey => route1.find(([key]) => key === nodeKey)?.[1]); const leaf2 = cache.getLeafNode(nodeKey => route2.find(([key]) => key === nodeKey)?.[1]); const leaf3 = cache.getLeafNode(nodeKey => route3.find(([key]) => key === nodeKey)?.[1]); expect(leaf1).toBeDefined(); expect(leaf2).toBeDefined(); expect(leaf3).toBeDefined(); const leaf1Node = nullthrows(leaf1); const leaf2Node = nullthrows(leaf2); const leaf3Node = nullthrows(leaf3); expect(cache.size()).toBe(3); const deleted1 = cache.delete(leaf1Node); expect(deleted1).toBe(true); expect(cache.size()).toBe(2); const deleted2 = cache.delete(leaf2Node); expect(deleted2).toBe(true); expect(cache.size()).toBe(1); const deleted3 = cache.delete(leaf3Node); expect(deleted3).toBe(true); expect(cache.size()).toBe(0); expect(cache.root()).toBeNull(); const deletedAgain = cache.delete(leaf1Node); expect(deletedAgain).toBe(false); }); testRecoil('onHit() handler', () => { const [route1, loadable1] = [[['a', 2], ['b', 3]], loadableWithValue('value1')]; const onHit = jest.fn(); const cache = new TreeCache({ onHit }); declare var getter: (nodeKey: any) => any; cache.set(route1, loadable1); // hit cache.get(getter); // miss cache.get(() => {}); // hit cache.get(getter); expect(onHit).toHaveBeenCalledTimes(2); }); testRecoil('onSet() handler', () => { const onSet = jest.fn(); const cache = new TreeCache({ onSet }); const [route1, loadable1] = [[['a', 2], ['b', 3]], loadableWithValue('value1')]; const [route2, loadable2] = [[['a', 3], ['b', 4]], loadableWithValue('value2')]; const [route3, loadable3] = [[['a', 4]], loadableWithValue('value3')]; cache.set(route1, loadable1); cache.set(route2, loadable2); cache.set(route3, loadable3); expect(onSet).toHaveBeenCalledTimes(3); }); testRecoil('default key generation uses reference equality', () => { const [route1, loadable1] = [[['a', [2]], ['b', [3]]], loadableWithValue('value1')]; const cache = new TreeCache(); cache.set(route1, loadable1); const resultWithKeyCopy = cache.get(nodeKey => [...(route1.find(([key]) => key === nodeKey)?.[1] ?? [])]); expect(resultWithKeyCopy).toBeUndefined(); const result = cache.get(nodeKey => route1.find(([key]) => key === nodeKey)?.[1]); expect(result).toBe(loadable1); }); testRecoil('mapNodeValue() to implement value equality keys', () => { const cache = new TreeCache({ mapNodeValue: value => JSON.stringify(value) }); const [route1, loadable1] = [[['a', [2]], ['b', [3]]], loadableWithValue('value1')]; cache.set(route1, loadable1); const resultWithKeyCopy = cache.get(nodeKey => [...(route1.find(([key]) => key === nodeKey)?.[1] ?? [])]); expect(resultWithKeyCopy).toBe(loadable1); }); });