1 import { combineReducers } from 'redux';
3 import type { OptimisticReducersMapObject, WrappedOptimisticState } from '../types';
4 import type { TestState } from '../utils/testing.utils';
7 createTestDeterministicAction,
8 createTestOptimisticHistoryItem,
10 } from '../utils/testing.utils';
11 import withOptimistic from '../with-optimistic';
12 import selectIsOptimistic, { asIfNotOptimistic } from './select-is-optimistic';
14 describe('selector as if is optimistic', () => {
15 describe('asIfNotOptimistic', () => {
16 test('should return empty state object if provided empty reducer map entries', () => {
17 const reducers = { test: testReducer };
19 const rootReducer = combineReducers(reducers);
20 const state = rootReducer({ test: { items: [] } }, createTestAction());
22 const reducerMap = {} as OptimisticReducersMapObject<typeof state>;
23 const result = asIfNotOptimistic(state, reducerMap);
25 expect(result).toEqual({});
28 test('should only keep the subset state inferred from the reducer map', () => {
34 checkpoint: { items: [] },
37 } as WrappedOptimisticState<TestState>,
41 testOptimistic: withOptimistic([], testReducer).reducer,
44 const result = asIfNotOptimistic(state, reducerMap);
46 expect(Object.keys(result).length).toEqual(1);
47 expect(result.testOptimistic).toEqual(state.testOptimistic);
50 test('should compute optimistic substate without optimistic updates', () => {
55 checkpoint: { items: [] },
57 createTestDeterministicAction('add', 1),
58 createTestOptimisticHistoryItem('add', 2),
59 createTestOptimisticHistoryItem('add', 3),
62 } as WrappedOptimisticState<TestState>,
65 const optimisticReducers: OptimisticReducersMapObject<typeof state> = {
66 testOptimistic: withOptimistic([], testReducer).reducer,
69 const result = asIfNotOptimistic(state, optimisticReducers);
71 expect(result.testOptimistic?.items).toEqual([1]);
74 test('should handle deeply nested optimistic reducers', () => {
81 checkpoint: { items: [] },
83 createTestDeterministicAction('add', 1),
84 createTestOptimisticHistoryItem('add', 2),
85 createTestOptimisticHistoryItem('add', 3),
88 } as WrappedOptimisticState<TestState>,
93 const optimisticReducers = {
96 testOptimistic: withOptimistic([], testReducer).reducer,
101 const result = asIfNotOptimistic(state, optimisticReducers);
103 expect(result.depth1.depth2.testOptimistic.items).toEqual([1]);
107 describe('selectIsOptimistic', () => {
108 test('should return true if selected state without optimistic updates diverges', () => {
113 checkpoint: { items: [] },
115 createTestDeterministicAction('add', 1),
116 createTestOptimisticHistoryItem('add', 2),
117 createTestOptimisticHistoryItem('add', 3),
120 } as WrappedOptimisticState<TestState>,
124 testOptimistic: withOptimistic([], testReducer).reducer,
127 const isOptimistic = selectIsOptimistic(state)(reducerMap)((s) => s.testOptimistic.items);
128 expect(isOptimistic).toBe(true);
131 test('should return false if both selected states with & without optimistic updates match', () => {
136 checkpoint: { items: [] },
138 createTestDeterministicAction('add', 1),
139 createTestDeterministicAction('add', 2),
140 createTestDeterministicAction('add', 3),
143 } as WrappedOptimisticState<TestState>,
146 const reducerMap: OptimisticReducersMapObject<typeof state> = {
147 testOptimistic: withOptimistic([], testReducer).reducer,
150 const isOptimistic = selectIsOptimistic(state)(reducerMap)((s) => s.testOptimistic.items);
151 expect(isOptimistic).toBe(false);