@mic-rexjs/usecases-react 2.12.0 → 2.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/index.min.js +1 -1
  2. package/es/components/SafeUseCaseFragment/index.js +17 -7
  3. package/es/components/SafeUseCaseFragment/types.js +1 -1
  4. package/es/components/UseCaseFragment/index.js +16 -6
  5. package/es/components/UseCaseFragment/types.js +1 -1
  6. package/es/entities/matchPropertyFailedResult/types.js +1 -1
  7. package/es/enums/ArgumentTypes/index.js +3 -3
  8. package/es/enums/Statuses/index.js +22 -22
  9. package/es/hooks/useArgumentTypes/index.js +12 -10
  10. package/es/hooks/useConstant/index.js +7 -4
  11. package/es/hooks/useConstant/types.js +1 -1
  12. package/es/hooks/useConstantEntityReducers/index.js +4 -4
  13. package/es/hooks/useConstantFn/index.js +9 -6
  14. package/es/hooks/useConstantReducers/index.js +4 -4
  15. package/es/hooks/useContext/index.js +14 -11
  16. package/es/hooks/useContext/index.test.js +50 -44
  17. package/es/hooks/useContextualItem/index.js +27 -25
  18. package/es/hooks/useContextualItem/types.js +1 -1
  19. package/es/hooks/useDepsKey/index.js +9 -5
  20. package/es/hooks/useEntity/index.js +65 -61
  21. package/es/hooks/useFullArguments/index.js +12 -17
  22. package/es/hooks/useFullArguments/types.js +1 -1
  23. package/es/hooks/useIsRenderingRef/index.js +6 -6
  24. package/es/hooks/useProvider/index.js +21 -15
  25. package/es/hooks/useProvider/types.js +1 -1
  26. package/es/hooks/useRuntimeEntity/index.js +18 -16
  27. package/es/hooks/useStatuses/index.js +19 -19
  28. package/es/hooks/useUseCase/index.js +78 -53
  29. package/es/hooks/useUseCase/index.test.js +2400 -1755
  30. package/es/hooks/useUseCase/types.d.ts +1 -1
  31. package/es/hooks/useUseCase/types.js +1 -1
  32. package/es/index.js +1 -1
  33. package/es/methods/triggerWatchers/index.js +12 -7
  34. package/es/types.js +1 -1
  35. package/es/usecases/contextUseCase/index.js +70 -65
  36. package/es/usecases/contextUseCase/types.js +1 -1
  37. package/es/usecases/methodUseCase/index.js +69 -52
  38. package/es/usecases/methodUseCase/types.js +1 -1
  39. package/es/usecases/valueUseCase/index.js +175 -167
  40. package/es/usecases/valueUseCase/types.js +1 -1
  41. package/lib/components/UseCaseFragment/index.js +1 -1
  42. package/lib/hooks/useUseCase/index.js +4 -3
  43. package/lib/hooks/useUseCase/index.test.js +48 -49
  44. package/lib/methods/triggerWatchers/index.js +9 -7
  45. package/lib/usecases/valueUseCase/index.js +1 -1
  46. package/package.json +3 -3
@@ -1,8 +1,9 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import { useUseCase } from '.';
3
4
  import { useDepsKey } from '../useDepsKey';
4
5
  import { beforeEach, describe, expect, jest, test } from '@jest/globals';
5
- import { entityUseCase, objectUseCase, } from '@mic-rexjs/usecases';
6
+ import { entityUseCase, objectUseCase } from '@mic-rexjs/usecases';
6
7
  import { fireEvent, screen } from '@testing-library/dom';
7
8
  import { act, render, renderHook } from '@testing-library/react';
8
9
  import { useDeepCompareEffect, useMemoizedFn, useMount, useUpdate, useUpdateEffect } from 'ahooks';
@@ -15,1833 +16,2477 @@ const PATH_2 = `hello${EXT_2}`;
15
16
  const PARENT_BUTTON_TEXT = 'parent button';
16
17
  const CHILD_BUTTON_TEXT = 'child button';
17
18
  const defaultFile = {
18
- path: '',
19
- ext: '',
20
- size: 0,
19
+ path: '',
20
+ ext: '',
21
+ size: 0
21
22
  };
22
- const fileUseCase = (options = {}) => {
23
- const entityReducers = objectUseCase();
24
- const { pathPrefix = '', onPathChange } = options;
25
- const init = function* (entity, newEntity = defaultFile) {
26
- yield () => {
27
- return newEntity;
28
- };
29
- };
30
- const setPath = function* (entity, path) {
31
- const { path: oldPath } = entity;
32
- const newPath = pathPrefix + path;
33
- yield {
34
- ...entity,
35
- path: newPath,
36
- ext: path.match(/\.[^.]+$/)?.[0] || '',
37
- };
38
- onPathChange?.(newPath, oldPath);
23
+ const fileUseCase = function () {
24
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
25
+ const entityReducers = objectUseCase();
26
+ const _options$pathPrefix = options.pathPrefix,
27
+ pathPrefix = _options$pathPrefix === void 0 ? '' : _options$pathPrefix,
28
+ onPathChange = options.onPathChange;
29
+ const init = function (entity) {
30
+ let newEntity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultFile;
31
+ return function* () {
32
+ yield () => {
33
+ return newEntity;
34
+ };
35
+ }();
36
+ };
37
+ const setPath = function* (entity, path) {
38
+ var _path$match;
39
+ const oldPath = entity.path;
40
+ const newPath = pathPrefix + path;
41
+ yield {
42
+ ...entity,
43
+ path: newPath,
44
+ ext: ((_path$match = path.match(/\.[^.]+$/)) === null || _path$match === void 0 ? void 0 : _path$match[0]) || ''
39
45
  };
40
- const readFile = async function* (entity, path) {
41
- const size = 2000;
42
- yield* setPath(entity, path);
43
- await Promise.resolve(null);
44
- yield (oldEntity) => {
45
- return {
46
- ...oldEntity,
47
- size,
48
- };
49
- };
50
- return size;
46
+ onPathChange === null || onPathChange === void 0 || onPathChange(newPath, oldPath);
47
+ };
48
+ const readFile = async function* (entity, path) {
49
+ const size = 2000;
50
+ yield* setPath(entity, path);
51
+ await Promise.resolve(null);
52
+ yield oldEntity => {
53
+ return {
54
+ ...oldEntity,
55
+ size
56
+ };
51
57
  };
52
- const isImage = (entity) => {
53
- const { ext } = entity;
54
- return [EXT_1, EXT_2].includes(ext);
55
- };
56
- return { ...entityReducers, init, setPath, readFile, isImage };
58
+ return size;
59
+ };
60
+ const isImage = entity => {
61
+ const ext = entity.ext;
62
+ return [EXT_1, EXT_2].includes(ext);
63
+ };
64
+ return {
65
+ ...entityReducers,
66
+ init,
67
+ setPath,
68
+ readFile,
69
+ isImage
70
+ };
57
71
  };
58
72
  const subtractionReducer = jest.fn((value1, value2) => {
59
- return value1 - value2;
73
+ return value1 - value2;
60
74
  });
61
- const mathUseCase = (options = {}) => {
62
- const { extraValue = 0 } = options;
63
- const add = (value1, value2) => {
64
- return value1 + value2 + extraValue;
65
- };
66
- return { add, subtraction: subtractionReducer };
75
+ const mathUseCase = function () {
76
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
77
+ const _options$extraValue = options.extraValue,
78
+ extraValue = _options$extraValue === void 0 ? 0 : _options$extraValue;
79
+ const add = (value1, value2) => {
80
+ return value1 + value2 + extraValue;
81
+ };
82
+ return {
83
+ add,
84
+ subtraction: subtractionReducer
85
+ };
67
86
  };
68
87
  const fieldPathUseCase = () => {
69
- return objectUseCase();
88
+ return objectUseCase();
70
89
  };
71
- const Child = ({ textPrefix = '', onUpdate, onPathChange, onUndefinedEntity }) => {
72
- const [file, { setPath }] = useUseCase(fileUseCase);
73
- const { path, ext } = file || {};
74
- const onClick = () => {
75
- setPath(PATH_2);
76
- };
77
- const undefinedEntity = useMemoizedFn(() => {
78
- onUndefinedEntity?.();
79
- });
80
- useUpdateEffect(() => {
81
- onUpdate?.();
82
- });
83
- useEffect(() => {
84
- if (file === void 0) {
85
- undefinedEntity();
86
- }
87
- }, [file, undefinedEntity]);
88
- const pathChange = useMemoizedFn(() => {
89
- onPathChange?.(path);
90
- });
91
- useUpdateEffect(pathChange, [path, pathChange]);
92
- return (_jsxs("div", { children: [_jsxs("main", { children: ["child path: ", path, _jsx("br", {}), "child ext: ", ext] }), _jsx("footer", { children: _jsx("button", { onClick: onClick, children: textPrefix + CHILD_BUTTON_TEXT }) })] }));
90
+ const Child = _ref => {
91
+ let _ref$textPrefix = _ref.textPrefix,
92
+ textPrefix = _ref$textPrefix === void 0 ? '' : _ref$textPrefix,
93
+ onUpdate = _ref.onUpdate,
94
+ onPathChange = _ref.onPathChange,
95
+ onUndefinedEntity = _ref.onUndefinedEntity;
96
+ const _useUseCase = useUseCase(fileUseCase),
97
+ _useUseCase2 = _slicedToArray(_useUseCase, 2),
98
+ file = _useUseCase2[0],
99
+ setPath = _useUseCase2[1].setPath;
100
+ const _ref2 = file || {},
101
+ path = _ref2.path,
102
+ ext = _ref2.ext;
103
+ const onClick = () => {
104
+ setPath(PATH_2);
105
+ };
106
+ const undefinedEntity = useMemoizedFn(() => {
107
+ onUndefinedEntity === null || onUndefinedEntity === void 0 || onUndefinedEntity();
108
+ });
109
+ useUpdateEffect(() => {
110
+ onUpdate === null || onUpdate === void 0 || onUpdate();
111
+ });
112
+ useEffect(() => {
113
+ if (file === void 0) {
114
+ undefinedEntity();
115
+ }
116
+ }, [file, undefinedEntity]);
117
+ const pathChange = useMemoizedFn(() => {
118
+ onPathChange === null || onPathChange === void 0 || onPathChange(path);
119
+ });
120
+ useUpdateEffect(pathChange, [path, pathChange]);
121
+ return _jsxs("div", {
122
+ children: [_jsxs("main", {
123
+ children: ["child path: ", path, _jsx("br", {}), "child ext: ", ext]
124
+ }), _jsx("footer", {
125
+ children: _jsx("button", {
126
+ onClick: onClick,
127
+ children: textPrefix + CHILD_BUTTON_TEXT
128
+ })
129
+ })]
130
+ });
93
131
  };
94
- const Parent = ({ children, onUpdate, onSetPath }) => {
95
- const [{ path, ext }, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase);
96
- const onClick = () => {
97
- setPath(onSetPath?.() || '');
98
- };
99
- useUpdateEffect(() => {
100
- onUpdate?.();
101
- });
102
- return (_jsx(Provider, { children: _jsxs("div", { children: [_jsxs("header", { children: ["parent path: ", path, _jsx("br", {}), "parent ext: ", ext] }), _jsx("main", { children: children }), _jsx("footer", { children: _jsx("button", { onClick: onClick, children: PARENT_BUTTON_TEXT }) })] }) }));
132
+ const Parent = _ref3 => {
133
+ let children = _ref3.children,
134
+ onUpdate = _ref3.onUpdate,
135
+ onSetPath = _ref3.onSetPath;
136
+ const _useUseCase3 = useUseCase(defaultFile, fileUseCase),
137
+ _useUseCase4 = _slicedToArray(_useUseCase3, 3),
138
+ _useUseCase4$ = _useUseCase4[0],
139
+ path = _useUseCase4$.path,
140
+ ext = _useUseCase4$.ext,
141
+ setPath = _useUseCase4[1].setPath,
142
+ Provider = _useUseCase4[2];
143
+ const onClick = () => {
144
+ setPath((onSetPath === null || onSetPath === void 0 ? void 0 : onSetPath()) || '');
145
+ };
146
+ useUpdateEffect(() => {
147
+ onUpdate === null || onUpdate === void 0 || onUpdate();
148
+ });
149
+ return _jsx(Provider, {
150
+ children: _jsxs("div", {
151
+ children: [_jsxs("header", {
152
+ children: ["parent path: ", path, _jsx("br", {}), "parent ext: ", ext]
153
+ }), _jsx("main", {
154
+ children: children
155
+ }), _jsx("footer", {
156
+ children: _jsx("button", {
157
+ onClick: onClick,
158
+ children: PARENT_BUTTON_TEXT
159
+ })
160
+ })]
161
+ })
162
+ });
103
163
  };
104
- const MathParent = ({ extraValue = 0, onUpdate }) => {
105
- const { add } = useUseCase(mathUseCase, { extraValue }, [extraValue]);
106
- const onClick = () => {
107
- add(1, 2);
108
- };
109
- useUpdateEffect(() => {
110
- onUpdate?.();
111
- });
112
- return (_jsx("div", { children: _jsx("button", { onClick: onClick, children: PARENT_BUTTON_TEXT }) }));
164
+ const MathParent = _ref4 => {
165
+ let _ref4$extraValue = _ref4.extraValue,
166
+ extraValue = _ref4$extraValue === void 0 ? 0 : _ref4$extraValue,
167
+ onUpdate = _ref4.onUpdate;
168
+ const _useUseCase5 = useUseCase(mathUseCase, {
169
+ extraValue
170
+ }, [extraValue]),
171
+ add = _useUseCase5.add;
172
+ const onClick = () => {
173
+ add(1, 2);
174
+ };
175
+ useUpdateEffect(() => {
176
+ onUpdate === null || onUpdate === void 0 || onUpdate();
177
+ });
178
+ return _jsx("div", {
179
+ children: _jsx("button", {
180
+ onClick: onClick,
181
+ children: PARENT_BUTTON_TEXT
182
+ })
183
+ });
113
184
  };
114
185
  const useDeepCompareUpdate = (callback, deps) => {
115
- const isFirstRef = useRef(true);
116
- const memoizedCallback = useMemoizedFn(callback);
117
- const depsKey = useDepsKey(deps);
118
- useEffect(() => {
119
- return () => {
120
- isFirstRef.current = false;
121
- };
122
- });
123
- useDeepCompareEffect(() => {
124
- if (isFirstRef.current) {
125
- return;
126
- }
127
- memoizedCallback();
128
- }, [depsKey, memoizedCallback]);
186
+ const isFirstRef = useRef(true);
187
+ const memoizedCallback = useMemoizedFn(callback);
188
+ const depsKey = useDepsKey(deps);
189
+ useEffect(() => {
190
+ return () => {
191
+ isFirstRef.current = false;
192
+ };
193
+ });
194
+ useDeepCompareEffect(() => {
195
+ if (isFirstRef.current) {
196
+ return;
197
+ }
198
+ memoizedCallback();
199
+ }, [depsKey, memoizedCallback]);
129
200
  };
130
201
  beforeEach(() => {
131
- subtractionReducer.mockClear();
202
+ subtractionReducer.mockClear();
132
203
  });
133
204
  describe('useUseCase', () => {
134
- describe('`useUseCase` should work the same as `useRootCoreCollection`', () => {
135
- test('check context type', () => {
136
- const { result } = renderHook(() => {
137
- return useUseCase(defaultFile, fileUseCase);
138
- });
139
- const { current: cores } = result;
140
- expect(Array.isArray(cores)).toBe(true);
141
- expect(cores).toHaveLength(3);
142
- });
143
- test('`entity` should equal `defaultFile`', () => {
144
- const { result } = renderHook(() => {
145
- return useUseCase(defaultFile, fileUseCase);
146
- });
147
- const { current: cores } = result;
148
- const [entity] = cores;
149
- expect(entity).toEqual(defaultFile);
150
- });
151
- test('Should return the `EntityStore.value` if root entity has not changed', () => {
152
- const { result } = renderHook(() => {
153
- return useUseCase(defaultFile, fileUseCase);
154
- });
155
- const { current: collection } = result;
156
- const [, { setPath }] = collection;
157
- act(() => {
158
- setPath(PATH_1);
159
- });
160
- expect(result.current[0]).toEqual({ ...defaultFile, path: PATH_1, ext: EXT_1 });
161
- });
162
- test('Should return the root entity if root entity has changed', () => {
163
- let file = defaultFile;
164
- const { result, rerender } = renderHook(() => {
165
- return useUseCase(file, fileUseCase);
166
- });
167
- file = { ...defaultFile, path: PATH_2 };
168
- rerender();
169
- expect(result.current[0]).toEqual({ ...defaultFile, path: PATH_2 });
170
- // 渲染多一次,避免第二次渲染的 `entity` 没变化而取错缓存的情况
171
- rerender();
172
- expect(result.current[0]).toEqual({ ...defaultFile, path: PATH_2 });
173
- });
174
- test('Should return the root entity if root entity has changed even with entity state changed', () => {
175
- let file = defaultFile;
176
- const { result } = renderHook(() => {
177
- return useUseCase(file, fileUseCase);
178
- });
179
- const { current: collection } = result;
180
- const [, { setPath }] = collection;
181
- act(() => {
182
- file = { ...defaultFile, path: PATH_2 };
183
- setPath(PATH_1);
184
- });
185
- expect(result.current[0]).toEqual({ ...defaultFile, path: PATH_2 });
186
- });
187
- test('Should support entity getter', () => {
188
- const file = defaultFile;
189
- const { result } = renderHook(() => {
190
- return useUseCase(() => {
191
- return file;
192
- }, fileUseCase);
193
- });
194
- const { current: [currentFile], } = result;
195
- expect(currentFile).toEqual(file);
196
- });
197
- test('Entity getter should provide the current entity', () => {
198
- let updateIndex = 0;
199
- const file = defaultFile;
200
- const onFile = jest.fn();
201
- const { result } = renderHook(() => {
202
- return useUseCase((currentFile) => {
203
- onFile(currentFile);
204
- return currentFile ?? file;
205
- }, fileUseCase, {}, [updateIndex++]);
206
- });
207
- const { current: [, { setPath: setPath1 }], } = result;
208
- expect(onFile).toHaveBeenCalledTimes(1);
209
- expect(onFile).toHaveBeenCalledWith(void 0);
210
- act(() => {
211
- setPath1(PATH_1);
212
- });
213
- const { current: [, { setPath: setPath2 }], } = result;
214
- expect(onFile).toHaveBeenCalledTimes(2);
215
- expect(onFile).toHaveBeenCalledWith({ ...file, ext: EXT_1, path: PATH_1 });
216
- act(() => {
217
- setPath2(PATH_2);
218
- });
219
- expect(onFile).toHaveBeenCalledTimes(3);
220
- expect(onFile).toHaveBeenCalledWith({ ...file, ext: EXT_2, path: PATH_2 });
221
- });
222
- test('Entity getter should provide the changed deps', () => {
223
- let updateIndex = 0;
224
- const file = defaultFile;
225
- const symbol = Symbol('changedDep');
226
- const onChangedDeps = jest.fn();
227
- const { result } = renderHook(() => {
228
- return useUseCase((currentFile = file, changedDeps) => {
229
- // 验证参数类型
230
- const [index1, num1, index2, string1, index3, boolean1] = changedDeps;
231
- const a = index1;
232
- const b = num1;
233
- const c = index2;
234
- const d = string1;
235
- const e = index3;
236
- const f = boolean1;
237
- void a;
238
- void b;
239
- void c;
240
- void d;
241
- void e;
242
- void f;
243
- // 先 `fill` 填充,再合并,以 `symbol` 代替虚无项去匹配
244
- onChangedDeps(Object.assign([...changedDeps].fill(symbol), changedDeps));
245
- return currentFile;
246
- }, fileUseCase, {}, [updateIndex++, 0, updateIndex++, 'xyz', updateIndex++, false]);
247
- });
248
- const { current: [, { setPath: setPath }], } = result;
249
- expect(onChangedDeps).toHaveBeenCalledTimes(1);
250
- expect(onChangedDeps).toHaveBeenCalledWith([symbol, symbol, symbol, symbol, symbol, symbol]);
251
- act(() => {
252
- setPath(PATH_1);
253
- });
254
- expect(onChangedDeps).toHaveBeenCalledTimes(2);
255
- expect(onChangedDeps).toHaveBeenCalledWith([3, symbol, 4, symbol, 5, symbol]);
256
- });
257
- test('Entity property getter should always return the same object if nothing changed after component update', () => {
258
- let updateTimes = 0;
259
- const data = {
260
- x: 1,
261
- get obj() {
262
- return {};
263
- },
264
- };
265
- const { rerender } = renderHook(() => {
266
- const collection = useUseCase(data, objectUseCase);
267
- const [{ obj }] = collection;
268
- useMemo(() => {
269
- void obj;
270
- updateTimes++;
271
- }, [obj]);
272
- return collection;
273
- });
274
- expect(updateTimes).toEqual(1);
275
- act(() => {
276
- rerender();
277
- });
278
- expect(updateTimes).toEqual(1);
205
+ describe('`useUseCase` should work the same as `useRootCoreCollection`', () => {
206
+ test('check context type', () => {
207
+ const _renderHook = renderHook(() => {
208
+ return useUseCase(defaultFile, fileUseCase);
209
+ }),
210
+ result = _renderHook.result;
211
+ const cores = result.current;
212
+ expect(Array.isArray(cores)).toBe(true);
213
+ expect(cores).toHaveLength(3);
214
+ });
215
+ test('`entity` should equal `defaultFile`', () => {
216
+ const _renderHook2 = renderHook(() => {
217
+ return useUseCase(defaultFile, fileUseCase);
218
+ }),
219
+ result = _renderHook2.result;
220
+ const cores = result.current;
221
+ const _cores = _slicedToArray(cores, 1),
222
+ entity = _cores[0];
223
+ expect(entity).toEqual(defaultFile);
224
+ });
225
+ test('Should return the `EntityStore.value` if root entity has not changed', () => {
226
+ const _renderHook3 = renderHook(() => {
227
+ return useUseCase(defaultFile, fileUseCase);
228
+ }),
229
+ result = _renderHook3.result;
230
+ const collection = result.current;
231
+ const _collection = _slicedToArray(collection, 2),
232
+ setPath = _collection[1].setPath;
233
+ act(() => {
234
+ setPath(PATH_1);
235
+ });
236
+ expect(result.current[0]).toEqual({
237
+ ...defaultFile,
238
+ path: PATH_1,
239
+ ext: EXT_1
240
+ });
241
+ });
242
+ test('Should return the root entity if root entity has changed', () => {
243
+ let file = defaultFile;
244
+ const _renderHook4 = renderHook(() => {
245
+ return useUseCase(file, fileUseCase);
246
+ }),
247
+ result = _renderHook4.result,
248
+ rerender = _renderHook4.rerender;
249
+ file = {
250
+ ...defaultFile,
251
+ path: PATH_2
252
+ };
253
+ rerender();
254
+ expect(result.current[0]).toEqual({
255
+ ...defaultFile,
256
+ path: PATH_2
257
+ });
258
+ // 渲染多一次,避免第二次渲染的 `entity` 没变化而取错缓存的情况
259
+ rerender();
260
+ expect(result.current[0]).toEqual({
261
+ ...defaultFile,
262
+ path: PATH_2
263
+ });
264
+ });
265
+ test('Should return the root entity if root entity has changed even with entity state changed', () => {
266
+ let file = defaultFile;
267
+ const _renderHook5 = renderHook(() => {
268
+ return useUseCase(file, fileUseCase);
269
+ }),
270
+ result = _renderHook5.result;
271
+ const collection = result.current;
272
+ const _collection2 = _slicedToArray(collection, 2),
273
+ setPath = _collection2[1].setPath;
274
+ act(() => {
275
+ file = {
276
+ ...defaultFile,
277
+ path: PATH_2
278
+ };
279
+ setPath(PATH_1);
280
+ });
281
+ expect(result.current[0]).toEqual({
282
+ ...defaultFile,
283
+ path: PATH_2
284
+ });
285
+ });
286
+ test('Should support entity getter', () => {
287
+ const file = defaultFile;
288
+ const _renderHook6 = renderHook(() => {
289
+ return useUseCase(() => {
290
+ return file;
291
+ }, fileUseCase);
292
+ }),
293
+ result = _renderHook6.result;
294
+ const _result$current = _slicedToArray(result.current, 1),
295
+ currentFile = _result$current[0];
296
+ expect(currentFile).toEqual(file);
297
+ });
298
+ test('Entity getter should provide the current entity', () => {
299
+ let updateIndex = 0;
300
+ const file = defaultFile;
301
+ const onFile = jest.fn();
302
+ const _renderHook7 = renderHook(() => {
303
+ return useUseCase(currentFile => {
304
+ onFile(currentFile);
305
+ return currentFile !== null && currentFile !== void 0 ? currentFile : file;
306
+ }, fileUseCase, {}, [updateIndex++]);
307
+ }),
308
+ result = _renderHook7.result;
309
+ const _result$current2 = _slicedToArray(result.current, 2),
310
+ setPath1 = _result$current2[1].setPath;
311
+ expect(onFile).toHaveBeenCalledTimes(1);
312
+ expect(onFile).toHaveBeenCalledWith(void 0);
313
+ act(() => {
314
+ setPath1(PATH_1);
315
+ });
316
+ const _result$current3 = _slicedToArray(result.current, 2),
317
+ setPath2 = _result$current3[1].setPath;
318
+ expect(onFile).toHaveBeenCalledTimes(2);
319
+ expect(onFile).toHaveBeenCalledWith({
320
+ ...file,
321
+ ext: EXT_1,
322
+ path: PATH_1
323
+ });
324
+ act(() => {
325
+ setPath2(PATH_2);
326
+ });
327
+ expect(onFile).toHaveBeenCalledTimes(3);
328
+ expect(onFile).toHaveBeenCalledWith({
329
+ ...file,
330
+ ext: EXT_2,
331
+ path: PATH_2
332
+ });
333
+ });
334
+ test('Entity getter should provide the changed deps', () => {
335
+ let updateIndex = 0;
336
+ const file = defaultFile;
337
+ const symbol = Symbol('changedDep');
338
+ const onChangedDeps = jest.fn();
339
+ const _renderHook8 = renderHook(() => {
340
+ return useUseCase(function () {
341
+ let currentFile = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : file;
342
+ let changedDeps = arguments.length > 1 ? arguments[1] : undefined;
343
+ // 验证参数类型
344
+ const _changedDeps = _slicedToArray(changedDeps, 6),
345
+ index1 = _changedDeps[0],
346
+ num1 = _changedDeps[1],
347
+ index2 = _changedDeps[2],
348
+ string1 = _changedDeps[3],
349
+ index3 = _changedDeps[4],
350
+ boolean1 = _changedDeps[5];
351
+ const a = index1;
352
+ const b = num1;
353
+ const c = index2;
354
+ const d = string1;
355
+ const e = index3;
356
+ const f = boolean1;
357
+ void a;
358
+ void b;
359
+ void c;
360
+ void d;
361
+ void e;
362
+ void f;
363
+ // 先 `fill` 填充,再合并,以 `symbol` 代替虚无项去匹配
364
+ onChangedDeps(Object.assign([...changedDeps].fill(symbol), changedDeps));
365
+ return currentFile;
366
+ }, fileUseCase, {}, [updateIndex++, 0, updateIndex++, 'xyz', updateIndex++, false]);
367
+ }),
368
+ result = _renderHook8.result;
369
+ const _result$current4 = _slicedToArray(result.current, 2),
370
+ setPath = _result$current4[1].setPath;
371
+ expect(onChangedDeps).toHaveBeenCalledTimes(1);
372
+ expect(onChangedDeps).toHaveBeenCalledWith([symbol, symbol, symbol, symbol, symbol, symbol]);
373
+ act(() => {
374
+ setPath(PATH_1);
375
+ });
376
+ expect(onChangedDeps).toHaveBeenCalledTimes(2);
377
+ expect(onChangedDeps).toHaveBeenCalledWith([3, symbol, 4, symbol, 5, symbol]);
378
+ });
379
+ test('Entity property getter should always return the same object if nothing changed after component update', () => {
380
+ let updateTimes = 0;
381
+ const data = {
382
+ x: 1,
383
+ get obj() {
384
+ return {};
385
+ }
386
+ };
387
+ const _renderHook9 = renderHook(() => {
388
+ const collection = useUseCase(data, objectUseCase);
389
+ const _collection3 = _slicedToArray(collection, 1),
390
+ obj = _collection3[0].obj;
391
+ useMemo(() => {
392
+ void obj;
393
+ updateTimes++;
394
+ }, [obj]);
395
+ return collection;
396
+ }),
397
+ rerender = _renderHook9.rerender;
398
+ expect(updateTimes).toEqual(1);
399
+ act(() => {
400
+ rerender();
401
+ });
402
+ expect(updateTimes).toEqual(1);
403
+ });
404
+ test('Entity property getter should always return a new object if something changed after component update', () => {
405
+ let updateTimes = 0;
406
+ const data = {
407
+ x: 1,
408
+ get obj() {
409
+ return {};
410
+ }
411
+ };
412
+ const _renderHook0 = renderHook(() => {
413
+ const collection = useUseCase(data, objectUseCase);
414
+ const _collection4 = _slicedToArray(collection, 1),
415
+ obj = _collection4[0].obj;
416
+ useMemo(() => {
417
+ void obj;
418
+ updateTimes++;
419
+ }, [obj]);
420
+ return collection;
421
+ }),
422
+ result = _renderHook0.result;
423
+ const current = result.current;
424
+ const _current = _slicedToArray(current, 2),
425
+ setEntity = _current[1].setEntity;
426
+ expect(updateTimes).toEqual(1);
427
+ act(() => {
428
+ setEntity({
429
+ x: 2
279
430
  });
280
- test('Entity property getter should always return a new object if something changed after component update', () => {
281
- let updateTimes = 0;
282
- const data = {
283
- x: 1,
284
- get obj() {
285
- return {};
286
- },
431
+ });
432
+ expect(updateTimes).toEqual(2);
433
+ });
434
+ test('Entity getter should provide the first argument with current entity when deps has change.', () => {
435
+ let entityArg;
436
+ let times = 0;
437
+ const file = defaultFile;
438
+ const _renderHook1 = renderHook(() => {
439
+ return useUseCase(function () {
440
+ let entity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : file;
441
+ const path = entity.path;
442
+ entityArg = entity;
443
+ return {
444
+ ...entity,
445
+ path: path + '1'
287
446
  };
288
- const { result } = renderHook(() => {
289
- const collection = useUseCase(data, objectUseCase);
290
- const [{ obj }] = collection;
291
- useMemo(() => {
292
- void obj;
293
- updateTimes++;
294
- }, [obj]);
295
- return collection;
296
- });
297
- const { current } = result;
298
- const [, { setEntity }] = current;
299
- expect(updateTimes).toEqual(1);
300
- act(() => {
301
- setEntity({ x: 2 });
302
- });
303
- expect(updateTimes).toEqual(2);
304
- });
305
- test('Entity getter should provide the first argument with current entity when deps has change.', () => {
306
- let entityArg;
307
- let times = 0;
308
- const file = defaultFile;
309
- const { result } = renderHook(() => {
310
- return useUseCase((entity = file) => {
311
- const { path } = entity;
312
- entityArg = entity;
313
- return {
314
- ...entity,
315
- path: path + '1',
316
- };
317
- }, fileUseCase, {}, [times++]);
318
- });
319
- const { current: collection1 } = result;
320
- const [currentFile1, { setPath }] = collection1;
321
- expect(entityArg).toEqual(defaultFile);
322
- expect(currentFile1).toEqual({ ...defaultFile, path: '1' });
323
- act(() => {
324
- setPath('2');
325
- });
326
- const { current: collection2 } = result;
327
- const [currentFile2] = collection2;
328
- expect(entityArg).toEqual({ ...defaultFile, path: '2' });
329
- expect(currentFile2).toEqual({ ...defaultFile, path: '21' });
447
+ }, fileUseCase, {}, [times++]);
448
+ }),
449
+ result = _renderHook1.result;
450
+ const collection1 = result.current;
451
+ const _collection5 = _slicedToArray(collection1, 2),
452
+ currentFile1 = _collection5[0],
453
+ setPath = _collection5[1].setPath;
454
+ expect(entityArg).toEqual(defaultFile);
455
+ expect(currentFile1).toEqual({
456
+ ...defaultFile,
457
+ path: '1'
458
+ });
459
+ act(() => {
460
+ setPath('2');
461
+ });
462
+ const collection2 = result.current;
463
+ const _collection6 = _slicedToArray(collection2, 1),
464
+ currentFile2 = _collection6[0];
465
+ expect(entityArg).toEqual({
466
+ ...defaultFile,
467
+ path: '2'
468
+ });
469
+ expect(currentFile2).toEqual({
470
+ ...defaultFile,
471
+ path: '21'
472
+ });
473
+ });
474
+ test('`reducers` should be returned as an object', () => {
475
+ const _renderHook10 = renderHook(() => {
476
+ return useUseCase(defaultFile, fileUseCase);
477
+ }),
478
+ result = _renderHook10.result;
479
+ const cores = result.current;
480
+ const _cores2 = _slicedToArray(cores, 2),
481
+ reducers = _cores2[1];
482
+ expect(typeof reducers).toBe('object');
483
+ });
484
+ test('`Provider` should be returned as a function', () => {
485
+ const _renderHook11 = renderHook(() => {
486
+ return useUseCase(defaultFile, fileUseCase);
487
+ }),
488
+ result = _renderHook11.result;
489
+ const cores = result.current;
490
+ const _cores3 = _slicedToArray(cores, 3),
491
+ Provider = _cores3[2];
492
+ expect(typeof Provider).toBe('function');
493
+ });
494
+ test('`usecase` should be called only once if deps has not provided', () => {
495
+ const mockUseCase = jest.fn(fileUseCase);
496
+ const _renderHook12 = renderHook(() => {
497
+ return useUseCase(defaultFile, mockUseCase);
498
+ }),
499
+ result = _renderHook12.result,
500
+ rerender = _renderHook12.rerender;
501
+ const cores = result.current;
502
+ const _cores4 = _slicedToArray(cores, 2),
503
+ setEntity = _cores4[1].setEntity;
504
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
505
+ act(() => {
506
+ setEntity({
507
+ ...defaultFile
330
508
  });
331
- test('`reducers` should be returned as an object', () => {
332
- const { result } = renderHook(() => {
333
- return useUseCase(defaultFile, fileUseCase);
334
- });
335
- const { current: cores } = result;
336
- const [, reducers] = cores;
337
- expect(typeof reducers).toBe('object');
509
+ });
510
+ rerender();
511
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
512
+ });
513
+ test('`usecase` should be called only once if deps has not changed', () => {
514
+ const mockUseCase = jest.fn(fileUseCase);
515
+ const _renderHook13 = renderHook(() => {
516
+ return useUseCase(defaultFile, mockUseCase, {}, [1, 'x']);
517
+ }),
518
+ result = _renderHook13.result,
519
+ rerender = _renderHook13.rerender;
520
+ const cores = result.current;
521
+ const _cores5 = _slicedToArray(cores, 2),
522
+ setEntity = _cores5[1].setEntity;
523
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
524
+ act(() => {
525
+ setEntity({
526
+ ...defaultFile
338
527
  });
339
- test('`Provider` should be returned as a function', () => {
340
- const { result } = renderHook(() => {
341
- return useUseCase(defaultFile, fileUseCase);
342
- });
343
- const { current: cores } = result;
344
- const [, , Provider] = cores;
345
- expect(typeof Provider).toBe('function');
528
+ });
529
+ rerender();
530
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
531
+ });
532
+ test('`usecase` should be called if deps has changed', () => {
533
+ let i = 0;
534
+ const mockUseCase = jest.fn(fileUseCase);
535
+ const _renderHook14 = renderHook(() => {
536
+ return useUseCase(defaultFile, mockUseCase, {}, [i++, 'x']);
537
+ }),
538
+ result = _renderHook14.result,
539
+ rerender = _renderHook14.rerender;
540
+ const cores = result.current;
541
+ const _cores6 = _slicedToArray(cores, 2),
542
+ setEntity = _cores6[1].setEntity;
543
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
544
+ act(() => {
545
+ setEntity({
546
+ ...defaultFile
346
547
  });
347
- test('`usecase` should be called only once if deps has not provided', () => {
348
- const mockUseCase = jest.fn(fileUseCase);
349
- const { result, rerender } = renderHook(() => {
350
- return useUseCase(defaultFile, mockUseCase);
351
- });
352
- const { current: cores } = result;
353
- const [, { setEntity }] = cores;
354
- expect(mockUseCase).toHaveBeenCalledTimes(1);
355
- act(() => {
356
- setEntity({
357
- ...defaultFile,
358
- });
359
- });
360
- rerender();
361
- expect(mockUseCase).toHaveBeenCalledTimes(1);
548
+ });
549
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
550
+ rerender();
551
+ expect(mockUseCase).toHaveBeenCalledTimes(2);
552
+ });
553
+ test('after call non-generator reducer, it should not trigger update', () => {
554
+ const onUpdate = jest.fn();
555
+ const onDeepUpdate = jest.fn();
556
+ const _renderHook15 = renderHook(() => {
557
+ const context = useUseCase(defaultFile, fileUseCase);
558
+ const _context = _slicedToArray(context, 2),
559
+ reducers = _context[1];
560
+ const isImage = reducers.isImage;
561
+ const update = useUpdate();
562
+ useUpdateEffect(() => {
563
+ onUpdate();
564
+ }, [context]);
565
+ useDeepCompareUpdate(() => {
566
+ onDeepUpdate();
567
+ }, [context]);
568
+ return shouldUpdate => {
569
+ isImage();
570
+ if (!shouldUpdate) {
571
+ return;
572
+ }
573
+ update();
574
+ };
575
+ }),
576
+ result = _renderHook15.result;
577
+ act(() => {
578
+ result.current();
579
+ });
580
+ expect(onUpdate).toHaveBeenCalledTimes(0);
581
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
582
+ act(() => {
583
+ result.current(true);
584
+ });
585
+ expect(onUpdate).toHaveBeenCalledTimes(0);
586
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
587
+ });
588
+ test('after `yield entity`, it should trigger update', () => {
589
+ const onUpdate = jest.fn();
590
+ const _renderHook16 = renderHook(() => {
591
+ useUpdateEffect(() => {
592
+ onUpdate();
593
+ });
594
+ return useUseCase(defaultFile, fileUseCase);
595
+ }),
596
+ result = _renderHook16.result;
597
+ const cores = result.current;
598
+ const _cores7 = _slicedToArray(cores, 2),
599
+ entity = _cores7[0],
600
+ reducers = _cores7[1];
601
+ const setPath = reducers.setPath,
602
+ setEntity = reducers.setEntity;
603
+ act(() => {
604
+ setPath(PATH_1);
605
+ setEntity({
606
+ size: 5000
362
607
  });
363
- test('`usecase` should be called only once if deps has not changed', () => {
364
- const mockUseCase = jest.fn(fileUseCase);
365
- const { result, rerender } = renderHook(() => {
366
- return useUseCase(defaultFile, mockUseCase, {}, [1, 'x']);
367
- });
368
- const { current: cores } = result;
369
- const [, { setEntity }] = cores;
370
- expect(mockUseCase).toHaveBeenCalledTimes(1);
371
- act(() => {
372
- setEntity({
373
- ...defaultFile,
374
- });
375
- });
376
- rerender();
377
- expect(mockUseCase).toHaveBeenCalledTimes(1);
608
+ });
609
+ expect(result.current).not.toBe(cores);
610
+ expect(result.current[0]).not.toBe(entity);
611
+ expect(result.current[1]).not.toBe(reducers);
612
+ expect(result.current[1].setPath).not.toBe(setPath);
613
+ expect(result.current[0]).toEqual({
614
+ ...defaultFile,
615
+ path: PATH_1,
616
+ ext: EXT_1,
617
+ size: 5000
618
+ });
619
+ expect(onUpdate).toHaveBeenCalledTimes(1);
620
+ });
621
+ test('after `yield entity` on async mode, it should trigger update', async () => {
622
+ const onUpdate = jest.fn();
623
+ const _renderHook17 = renderHook(() => {
624
+ useUpdateEffect(() => {
625
+ onUpdate();
626
+ });
627
+ return useUseCase(defaultFile, fileUseCase);
628
+ }),
629
+ result = _renderHook17.result;
630
+ const cores = result.current;
631
+ const _cores8 = _slicedToArray(cores, 2),
632
+ entity = _cores8[0],
633
+ reducers = _cores8[1];
634
+ const readFile = reducers.readFile;
635
+ const promise = act(() => {
636
+ return readFile(PATH_1);
637
+ });
638
+ expect(result.current).toBe(cores);
639
+ expect(result.current).toEqual(cores);
640
+ expect(onUpdate).toHaveBeenCalledTimes(0);
641
+ await promise;
642
+ expect(result.current[0]).not.toBe(entity);
643
+ expect(result.current[1]).not.toBe(reducers);
644
+ expect(result.current[1].readFile).not.toBe(readFile);
645
+ expect(result.current[0].path).toBe(PATH_1);
646
+ expect(result.current[0].ext).toBe(EXT_1);
647
+ expect(result.current[0].size).toBe(2000);
648
+ expect(onUpdate).toHaveBeenCalledTimes(1);
649
+ });
650
+ test('after `yield entity` callbacks, it should trigger update', () => {
651
+ const onUpdate = jest.fn();
652
+ const _renderHook18 = renderHook(() => {
653
+ useUpdateEffect(() => {
654
+ onUpdate();
655
+ });
656
+ return useUseCase(defaultFile, fileUseCase);
657
+ }),
658
+ result = _renderHook18.result;
659
+ const cores = result.current;
660
+ const _cores9 = _slicedToArray(cores, 2),
661
+ reducers = _cores9[1];
662
+ const init = reducers.init;
663
+ act(() => {
664
+ init({
665
+ ...defaultFile,
666
+ size: 5000
378
667
  });
379
- test('`usecase` should be called if deps has changed', () => {
380
- let i = 0;
381
- const mockUseCase = jest.fn(fileUseCase);
382
- const { result, rerender } = renderHook(() => {
383
- return useUseCase(defaultFile, mockUseCase, {}, [i++, 'x']);
384
- });
385
- const { current: cores } = result;
386
- const [, { setEntity }] = cores;
387
- expect(mockUseCase).toHaveBeenCalledTimes(1);
388
- act(() => {
389
- setEntity({
390
- ...defaultFile,
391
- });
392
- });
393
- expect(mockUseCase).toHaveBeenCalledTimes(1);
394
- rerender();
395
- expect(mockUseCase).toHaveBeenCalledTimes(2);
668
+ });
669
+ expect(result.current[0].size).toBe(5000);
670
+ expect(result.current[1]).not.toBe(reducers);
671
+ expect(result.current[1].init).not.toBe(init);
672
+ expect(onUpdate).toHaveBeenCalledTimes(1);
673
+ });
674
+ test('reducer call should be cached if component is at rendering phase', () => {
675
+ const buttonText = 'button';
676
+ const addReducer = jest.fn((entity, substring) => {
677
+ return entity + substring;
678
+ });
679
+ const stringUseCase = () => {
680
+ const entityReducers = entityUseCase();
681
+ return {
682
+ ...entityReducers,
683
+ add: addReducer
684
+ };
685
+ };
686
+ const CacheTestComponent = () => {
687
+ const _useUseCase6 = useUseCase('', stringUseCase),
688
+ _useUseCase7 = _slicedToArray(_useUseCase6, 2),
689
+ add = _useUseCase7[1].add;
690
+ const update = useUpdate();
691
+ const onClick = () => {
692
+ update();
693
+ };
694
+ add('x');
695
+ return _jsx("button", {
696
+ onClick: onClick,
697
+ children: buttonText
396
698
  });
397
- test('after call non-generator reducer, it should not trigger update', () => {
398
- const onUpdate = jest.fn();
399
- const onDeepUpdate = jest.fn();
400
- const { result } = renderHook(() => {
401
- const context = useUseCase(defaultFile, fileUseCase);
402
- const [, reducers] = context;
403
- const { isImage } = reducers;
404
- const update = useUpdate();
405
- useUpdateEffect(() => {
406
- onUpdate();
407
- }, [context]);
408
- useDeepCompareUpdate(() => {
409
- onDeepUpdate();
410
- }, [context]);
411
- return (shouldUpdate) => {
412
- isImage();
413
- if (!shouldUpdate) {
414
- return;
415
- }
416
- update();
417
- };
418
- });
419
- act(() => {
420
- result.current();
421
- });
422
- expect(onUpdate).toHaveBeenCalledTimes(0);
423
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
424
- act(() => {
425
- result.current(true);
426
- });
427
- expect(onUpdate).toHaveBeenCalledTimes(0);
428
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
699
+ };
700
+ render(_jsx(CacheTestComponent, {}));
701
+ expect(addReducer).toHaveBeenCalledTimes(1);
702
+ expect(addReducer).toHaveBeenCalledWith('', 'x');
703
+ expect(addReducer).toHaveReturnedWith('x');
704
+ fireEvent.click(screen.getByText(buttonText));
705
+ expect(addReducer).toHaveBeenCalledTimes(1);
706
+ });
707
+ test('reducer call should not be cached if component is not at rendering phase', () => {
708
+ const buttonText = 'button';
709
+ const addReducer = jest.fn((entity, substring) => {
710
+ return entity + substring;
711
+ });
712
+ const stringUseCase = () => {
713
+ const entityReducers = entityUseCase();
714
+ return {
715
+ ...entityReducers,
716
+ add: addReducer
717
+ };
718
+ };
719
+ const CacheTestComponent = () => {
720
+ const _useUseCase8 = useUseCase('', stringUseCase),
721
+ _useUseCase9 = _slicedToArray(_useUseCase8, 2),
722
+ add = _useUseCase9[1].add;
723
+ const onClick = () => {
724
+ add('x');
725
+ };
726
+ useMount(() => {
727
+ add('x');
728
+ add('x');
429
729
  });
430
- test('after `yield entity`, it should trigger update', () => {
431
- const onUpdate = jest.fn();
432
- const { result } = renderHook(() => {
433
- useUpdateEffect(() => {
434
- onUpdate();
435
- });
436
- return useUseCase(defaultFile, fileUseCase);
437
- });
438
- const { current: cores } = result;
439
- const [entity, reducers] = cores;
440
- const { setPath, setEntity } = reducers;
441
- act(() => {
442
- setPath(PATH_1);
443
- setEntity({ size: 5000 });
444
- });
445
- expect(result.current).not.toBe(cores);
446
- expect(result.current[0]).not.toBe(entity);
447
- expect(result.current[1]).not.toBe(reducers);
448
- expect(result.current[1].setPath).not.toBe(setPath);
449
- expect(result.current[0]).toEqual({
450
- ...defaultFile,
451
- path: PATH_1,
452
- ext: EXT_1,
453
- size: 5000,
454
- });
455
- expect(onUpdate).toHaveBeenCalledTimes(1);
730
+ return _jsx("button", {
731
+ onClick: onClick,
732
+ children: buttonText
456
733
  });
457
- test('after `yield entity` on async mode, it should trigger update', async () => {
458
- const onUpdate = jest.fn();
459
- const { result } = renderHook(() => {
460
- useUpdateEffect(() => {
461
- onUpdate();
462
- });
463
- return useUseCase(defaultFile, fileUseCase);
464
- });
465
- const { current: cores } = result;
466
- const [entity, reducers] = cores;
467
- const { readFile } = reducers;
468
- const promise = act(() => {
469
- return readFile(PATH_1);
470
- });
471
- expect(result.current).toBe(cores);
472
- expect(result.current).toEqual(cores);
473
- expect(onUpdate).toHaveBeenCalledTimes(0);
474
- await promise;
475
- expect(result.current[0]).not.toBe(entity);
476
- expect(result.current[1]).not.toBe(reducers);
477
- expect(result.current[1].readFile).not.toBe(readFile);
478
- expect(result.current[0].path).toBe(PATH_1);
479
- expect(result.current[0].ext).toBe(EXT_1);
480
- expect(result.current[0].size).toBe(2000);
481
- expect(onUpdate).toHaveBeenCalledTimes(1);
734
+ };
735
+ render(_jsx(CacheTestComponent, {}));
736
+ expect(addReducer).toHaveBeenCalledTimes(2);
737
+ expect(addReducer).toHaveBeenNthCalledWith(1, '', 'x');
738
+ expect(addReducer).toHaveBeenNthCalledWith(2, '', 'x');
739
+ fireEvent.click(screen.getByText(buttonText));
740
+ expect(addReducer).toHaveBeenCalledTimes(3);
741
+ expect(addReducer).toHaveBeenNthCalledWith(3, '', 'x');
742
+ });
743
+ test('reducer call should not be cached if entity or parameters have changed', () => {
744
+ let count = 0;
745
+ let addedText = 'x';
746
+ const setButtonText = 'button';
747
+ const updateButtonText = 'update';
748
+ const addReducer = jest.fn((entity, substring) => {
749
+ return entity + substring;
750
+ });
751
+ const stringUseCase = () => {
752
+ const entityReducers = entityUseCase();
753
+ return {
754
+ ...entityReducers,
755
+ add: addReducer
756
+ };
757
+ };
758
+ const CacheTestComponent = () => {
759
+ const _useUseCase0 = useUseCase('', stringUseCase),
760
+ _useUseCase1 = _slicedToArray(_useUseCase0, 2),
761
+ _useUseCase1$ = _useUseCase1[1],
762
+ add = _useUseCase1$.add,
763
+ setEntity = _useUseCase1$.setEntity;
764
+ const update = useUpdate();
765
+ add(addedText);
766
+ const onSet = () => {
767
+ setEntity(`${count++}`);
768
+ };
769
+ const onUpdate = () => {
770
+ update();
771
+ };
772
+ return _jsxs("div", {
773
+ children: [_jsx("button", {
774
+ onClick: onSet,
775
+ children: setButtonText
776
+ }), _jsx("button", {
777
+ onClick: onUpdate,
778
+ children: updateButtonText
779
+ })]
482
780
  });
483
- test('after `yield entity` callbacks, it should trigger update', () => {
484
- const onUpdate = jest.fn();
485
- const { result } = renderHook(() => {
486
- useUpdateEffect(() => {
487
- onUpdate();
488
- });
489
- return useUseCase(defaultFile, fileUseCase);
490
- });
491
- const { current: cores } = result;
492
- const [, reducers] = cores;
493
- const { init } = reducers;
494
- act(() => {
495
- init({ ...defaultFile, size: 5000 });
496
- });
497
- expect(result.current[0].size).toBe(5000);
498
- expect(result.current[1]).not.toBe(reducers);
499
- expect(result.current[1].init).not.toBe(init);
500
- expect(onUpdate).toHaveBeenCalledTimes(1);
781
+ };
782
+ render(_jsx(CacheTestComponent, {}));
783
+ expect(addReducer).toHaveBeenCalledTimes(1);
784
+ expect(addReducer).toHaveBeenCalledWith('', 'x');
785
+ fireEvent.click(screen.getByText(setButtonText));
786
+ expect(addReducer).toHaveBeenCalledTimes(2);
787
+ expect(addReducer).toHaveBeenCalledWith('0', 'x');
788
+ expect(addReducer).toHaveReturnedWith('0x');
789
+ addedText = 'y';
790
+ fireEvent.click(screen.getByText(updateButtonText));
791
+ expect(addReducer).toHaveBeenCalledTimes(3);
792
+ expect(addReducer).toHaveBeenCalledWith('0', 'y');
793
+ expect(addReducer).toHaveReturnedWith('0y');
794
+ fireEvent.click(screen.getByText(updateButtonText));
795
+ expect(addReducer).toHaveBeenCalledTimes(3);
796
+ });
797
+ test('`options.onChange` should be trigger when entity has changed', () => {
798
+ const onChange = jest.fn();
799
+ const _renderHook19 = renderHook(() => {
800
+ return useUseCase(defaultFile, fileUseCase, {
801
+ onChange
802
+ });
803
+ }),
804
+ result = _renderHook19.result;
805
+ const cores = result.current;
806
+ const _cores0 = _slicedToArray(cores, 2),
807
+ reducers = _cores0[1];
808
+ const setPath = reducers.setPath;
809
+ expect(onChange).toHaveBeenCalledTimes(0);
810
+ act(() => {
811
+ setPath(PATH_1);
812
+ });
813
+ expect(onChange).toHaveBeenCalledTimes(1);
814
+ expect(onChange).toHaveBeenLastCalledWith({
815
+ ...defaultFile,
816
+ path: PATH_1,
817
+ ext: EXT_1
818
+ }, defaultFile);
819
+ });
820
+ test('`options.onChange` should always trigger the latest one', () => {
821
+ const onChange1 = jest.fn();
822
+ const onChange2 = jest.fn();
823
+ let onChange = onChange1;
824
+ const _renderHook20 = renderHook(() => {
825
+ return useUseCase(defaultFile, fileUseCase, {
826
+ onChange
827
+ }, []);
828
+ }),
829
+ result = _renderHook20.result;
830
+ const cores = result.current;
831
+ const _cores1 = _slicedToArray(cores, 2),
832
+ reducers = _cores1[1];
833
+ const setPath = reducers.setPath;
834
+ expect(onChange1).toHaveBeenCalledTimes(0);
835
+ act(() => {
836
+ setPath(PATH_1);
837
+ onChange = onChange2;
838
+ });
839
+ expect(onChange2).toHaveBeenCalledTimes(0);
840
+ expect(onChange1).toHaveBeenCalledTimes(1);
841
+ expect(onChange1).toHaveBeenLastCalledWith({
842
+ ...defaultFile,
843
+ path: PATH_1,
844
+ ext: EXT_1
845
+ }, defaultFile);
846
+ act(() => {
847
+ setPath(PATH_2);
848
+ });
849
+ expect(onChange1).toHaveBeenCalledTimes(1);
850
+ expect(onChange2).toHaveBeenCalledTimes(1);
851
+ expect(onChange2).toHaveBeenLastCalledWith({
852
+ ...defaultFile,
853
+ path: PATH_2,
854
+ ext: EXT_2
855
+ }, {
856
+ ...defaultFile,
857
+ path: PATH_1,
858
+ ext: EXT_1
859
+ });
860
+ });
861
+ test('`options.options` should override rest options', () => {
862
+ const _renderHook21 = renderHook(() => {
863
+ return useUseCase(defaultFile, fileUseCase, {
864
+ pathPrefix: 'xyz/',
865
+ options: {
866
+ pathPrefix: '123/'
867
+ }
868
+ });
869
+ }),
870
+ result = _renderHook21.result;
871
+ const cores = result.current;
872
+ const _cores10 = _slicedToArray(cores, 2),
873
+ path = _cores10[0].path,
874
+ reducers = _cores10[1];
875
+ const setPath = reducers.setPath;
876
+ expect(path).toBe('');
877
+ act(() => {
878
+ setPath(PATH_1);
879
+ });
880
+ expect(result.current[0].path).toBe('123/' + PATH_1);
881
+ });
882
+ test('Option functions: use `T` (not `S`) when `S extends T`', () => {
883
+ const testObjectUseCase = function () {
884
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
885
+ const objectReducers = objectUseCase();
886
+ void options;
887
+ return {
888
+ ...objectReducers
889
+ };
890
+ };
891
+ renderHook(() => {
892
+ useUseCase(defaultFile, testObjectUseCase, {
893
+ onUpdate(data) {
894
+ void data;
895
+ return Promise.reject();
896
+ }
501
897
  });
502
- test('reducer call should be cached if component is at rendering phase', () => {
503
- const buttonText = 'button';
504
- const addReducer = jest.fn((entity, substring) => {
505
- return entity + substring;
506
- });
507
- const stringUseCase = () => {
508
- const entityReducers = entityUseCase();
509
- return {
510
- ...entityReducers,
511
- add: addReducer,
512
- };
513
- };
514
- const CacheTestComponent = () => {
515
- const [, { add }] = useUseCase('', stringUseCase);
516
- const update = useUpdate();
517
- const onClick = () => {
518
- update();
519
- };
520
- add('x');
521
- return _jsx("button", { onClick: onClick, children: buttonText });
522
- };
523
- render(_jsx(CacheTestComponent, {}));
524
- expect(addReducer).toHaveBeenCalledTimes(1);
525
- expect(addReducer).toHaveBeenCalledWith('', 'x');
526
- expect(addReducer).toHaveReturnedWith('x');
527
- fireEvent.click(screen.getByText(buttonText));
528
- expect(addReducer).toHaveBeenCalledTimes(1);
898
+ });
899
+ // 这个测试仅仅是为了确保类型不会报错,不验证实际逻辑
900
+ expect(1).toBe(1);
901
+ });
902
+ test('when `options` has changed, it should not trigger update', () => {
903
+ const onUpdate = jest.fn();
904
+ const onDeepUpdate = jest.fn();
905
+ const _renderHook22 = renderHook(() => {
906
+ const _useState = useState('user/'),
907
+ _useState2 = _slicedToArray(_useState, 2),
908
+ pathPrefix = _useState2[0],
909
+ setPathPrefix = _useState2[1];
910
+ const context = useUseCase(defaultFile, fileUseCase, {
911
+ pathPrefix
912
+ });
913
+ useUpdateEffect(() => {
914
+ onUpdate();
915
+ }, [context]);
916
+ useDeepCompareUpdate(() => {
917
+ onDeepUpdate();
918
+ }, [context]);
919
+ return setPathPrefix;
920
+ }),
921
+ result = _renderHook22.result;
922
+ expect(onUpdate).toHaveBeenCalledTimes(0);
923
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
924
+ act(() => {
925
+ result.current('my/');
926
+ });
927
+ expect(onUpdate).toHaveBeenCalledTimes(0);
928
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
929
+ });
930
+ test('when `deps` has changed, it should trigger update', () => {
931
+ const onUpdate = jest.fn();
932
+ const onDeepUpdate = jest.fn();
933
+ const _renderHook23 = renderHook(() => {
934
+ const _useState3 = useState('user/'),
935
+ _useState4 = _slicedToArray(_useState3, 2),
936
+ pathPrefix = _useState4[0],
937
+ setPathPrefix = _useState4[1];
938
+ const context = useUseCase(defaultFile, fileUseCase, {
939
+ pathPrefix
940
+ }, [pathPrefix]);
941
+ useUpdateEffect(() => {
942
+ onUpdate();
943
+ }, [context]);
944
+ useDeepCompareUpdate(() => {
945
+ onDeepUpdate();
946
+ }, [context]);
947
+ return setPathPrefix;
948
+ }),
949
+ result = _renderHook23.result;
950
+ expect(onUpdate).toHaveBeenCalledTimes(0);
951
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
952
+ act(() => {
953
+ result.current('my/');
954
+ });
955
+ expect(onUpdate).toHaveBeenCalledTimes(1);
956
+ expect(onDeepUpdate).toHaveBeenCalledTimes(1);
957
+ });
958
+ test('empty `deps` should not trigger update', () => {
959
+ const onUpdate = jest.fn();
960
+ const onDeepUpdate = jest.fn();
961
+ const _renderHook24 = renderHook(() => {
962
+ const _useState5 = useState('user/'),
963
+ _useState6 = _slicedToArray(_useState5, 2),
964
+ pathPrefix = _useState6[0],
965
+ setPathPrefix = _useState6[1];
966
+ const context = useUseCase(defaultFile, fileUseCase, {
967
+ pathPrefix
968
+ }, []);
969
+ useUpdateEffect(() => {
970
+ onUpdate();
971
+ }, [context]);
972
+ useDeepCompareUpdate(() => {
973
+ onDeepUpdate();
974
+ }, [context]);
975
+ return setPathPrefix;
976
+ }),
977
+ result = _renderHook24.result;
978
+ expect(onUpdate).toHaveBeenCalledTimes(0);
979
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
980
+ act(() => {
981
+ result.current('my/');
982
+ });
983
+ expect(onUpdate).toHaveBeenCalledTimes(0);
984
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
985
+ });
986
+ test(`should call latest functions of usecase options even deps has not change`, () => {
987
+ const onPathChange1 = jest.fn();
988
+ const onPathChange2 = jest.fn();
989
+ let onPathChange = onPathChange1;
990
+ const _renderHook25 = renderHook(() => {
991
+ return useUseCase(defaultFile, fileUseCase, {
992
+ onPathChange
993
+ });
994
+ }),
995
+ result = _renderHook25.result;
996
+ const context = result.current;
997
+ const _context2 = _slicedToArray(context, 2),
998
+ setPath = _context2[1].setPath;
999
+ act(() => {
1000
+ setPath(PATH_1);
1001
+ onPathChange = onPathChange2;
1002
+ });
1003
+ expect(onPathChange1).toHaveBeenCalledTimes(1);
1004
+ expect(onPathChange2).toHaveBeenCalledTimes(0);
1005
+ expect(onPathChange1).toHaveBeenLastCalledWith(PATH_1, '');
1006
+ act(() => {
1007
+ setPath(PATH_2);
1008
+ });
1009
+ expect(onPathChange1).toHaveBeenCalledTimes(1);
1010
+ expect(onPathChange2).toHaveBeenCalledTimes(1);
1011
+ expect(onPathChange2).toHaveBeenLastCalledWith(PATH_2, PATH_1);
1012
+ });
1013
+ test('`options.watch` should be trigger after entity changed', () => {
1014
+ const onPathChange = jest.fn();
1015
+ const onSizeChange = jest.fn();
1016
+ const _renderHook26 = renderHook(() => {
1017
+ return useUseCase(defaultFile, fileUseCase, {
1018
+ watch: {
1019
+ path: onPathChange,
1020
+ size: onSizeChange
1021
+ }
1022
+ });
1023
+ }),
1024
+ result = _renderHook26.result;
1025
+ const cores = result.current;
1026
+ const _cores11 = _slicedToArray(cores, 2),
1027
+ setPath = _cores11[1].setPath;
1028
+ expect(onPathChange).toHaveBeenCalledTimes(0);
1029
+ act(() => {
1030
+ setPath(PATH_1);
1031
+ });
1032
+ expect(onPathChange).toHaveBeenCalledTimes(1);
1033
+ expect(onSizeChange).toHaveBeenCalledTimes(0);
1034
+ expect(onPathChange).toHaveBeenLastCalledWith({
1035
+ fieldPaths: ['path'],
1036
+ newEntity: {
1037
+ ...defaultFile,
1038
+ path: PATH_1,
1039
+ ext: EXT_1
1040
+ },
1041
+ oldEntity: defaultFile,
1042
+ newValue: PATH_1,
1043
+ oldValue: ''
1044
+ });
1045
+ });
1046
+ test('`options.watch` should trigger the latest one', () => {
1047
+ const onPathChange1 = jest.fn();
1048
+ const onPathChange2 = jest.fn();
1049
+ let onPathChange = onPathChange1;
1050
+ const _renderHook27 = renderHook(() => {
1051
+ return useUseCase(defaultFile, fileUseCase, {
1052
+ watch: {
1053
+ path: onPathChange
1054
+ }
1055
+ });
1056
+ }),
1057
+ result = _renderHook27.result;
1058
+ const cores = result.current;
1059
+ const _cores12 = _slicedToArray(cores, 2),
1060
+ _cores12$ = _cores12[1],
1061
+ setPath = _cores12$.setPath,
1062
+ setEntity = _cores12$.setEntity;
1063
+ expect(onPathChange1).toHaveBeenCalledTimes(0);
1064
+ act(() => {
1065
+ setPath(PATH_1);
1066
+ setEntity({
1067
+ size: 5000
529
1068
  });
530
- test('reducer call should not be cached if component is not at rendering phase', () => {
531
- const buttonText = 'button';
532
- const addReducer = jest.fn((entity, substring) => {
533
- return entity + substring;
534
- });
535
- const stringUseCase = () => {
536
- const entityReducers = entityUseCase();
537
- return {
538
- ...entityReducers,
539
- add: addReducer,
540
- };
541
- };
542
- const CacheTestComponent = () => {
543
- const [, { add }] = useUseCase('', stringUseCase);
544
- const onClick = () => {
545
- add('x');
546
- };
547
- useMount(() => {
548
- add('x');
549
- add('x');
550
- });
551
- return _jsx("button", { onClick: onClick, children: buttonText });
552
- };
553
- render(_jsx(CacheTestComponent, {}));
554
- expect(addReducer).toHaveBeenCalledTimes(2);
555
- expect(addReducer).toHaveBeenNthCalledWith(1, '', 'x');
556
- expect(addReducer).toHaveBeenNthCalledWith(2, '', 'x');
557
- fireEvent.click(screen.getByText(buttonText));
558
- expect(addReducer).toHaveBeenCalledTimes(3);
559
- expect(addReducer).toHaveBeenNthCalledWith(3, '', 'x');
1069
+ onPathChange = onPathChange2;
1070
+ });
1071
+ expect(onPathChange1).toHaveBeenCalledTimes(1);
1072
+ expect(onPathChange1).toHaveBeenLastCalledWith({
1073
+ fieldPaths: ['path'],
1074
+ newEntity: {
1075
+ ...defaultFile,
1076
+ path: PATH_1,
1077
+ ext: EXT_1
1078
+ },
1079
+ oldEntity: defaultFile,
1080
+ newValue: PATH_1,
1081
+ oldValue: ''
1082
+ });
1083
+ act(() => {
1084
+ setPath('');
1085
+ });
1086
+ expect(onPathChange1).toHaveBeenCalledTimes(1);
1087
+ expect(onPathChange2).toHaveBeenCalledTimes(1);
1088
+ expect(onPathChange2).toHaveBeenLastCalledWith({
1089
+ fieldPaths: ['path'],
1090
+ newEntity: {
1091
+ ...defaultFile,
1092
+ size: 5000
1093
+ },
1094
+ oldEntity: {
1095
+ ...defaultFile,
1096
+ path: PATH_1,
1097
+ ext: EXT_1,
1098
+ size: 5000
1099
+ },
1100
+ newValue: '',
1101
+ oldValue: PATH_1
1102
+ });
1103
+ });
1104
+ test('`options.watch` should work with array field path of array', () => {
1105
+ const initialData = {};
1106
+ const onExtChange = jest.fn();
1107
+ const onSizeChange = jest.fn();
1108
+ const _renderHook28 = renderHook(() => {
1109
+ return useUseCase(initialData, fieldPathUseCase, {
1110
+ watch: {
1111
+ 'list.ext': onExtChange,
1112
+ 'list.size': onSizeChange
1113
+ }
1114
+ });
1115
+ }),
1116
+ result = _renderHook28.result;
1117
+ const cores = result.current;
1118
+ const _cores13 = _slicedToArray(cores, 2),
1119
+ setEntity = _cores13[1].setEntity;
1120
+ act(() => {
1121
+ setEntity({
1122
+ list: [defaultFile]
560
1123
  });
561
- test('reducer call should not be cached if entity or parameters have changed', () => {
562
- let count = 0;
563
- let addedText = 'x';
564
- const setButtonText = 'button';
565
- const updateButtonText = 'update';
566
- const addReducer = jest.fn((entity, substring) => {
567
- return entity + substring;
568
- });
569
- const stringUseCase = () => {
570
- const entityReducers = entityUseCase();
571
- return {
572
- ...entityReducers,
573
- add: addReducer,
574
- };
575
- };
576
- const CacheTestComponent = () => {
577
- const [, { add, setEntity }] = useUseCase('', stringUseCase);
578
- const update = useUpdate();
579
- add(addedText);
580
- const onSet = () => {
581
- setEntity(`${count++}`);
582
- };
583
- const onUpdate = () => {
584
- update();
585
- };
586
- return (_jsxs("div", { children: [_jsx("button", { onClick: onSet, children: setButtonText }), _jsx("button", { onClick: onUpdate, children: updateButtonText })] }));
587
- };
588
- render(_jsx(CacheTestComponent, {}));
589
- expect(addReducer).toHaveBeenCalledTimes(1);
590
- expect(addReducer).toHaveBeenCalledWith('', 'x');
591
- fireEvent.click(screen.getByText(setButtonText));
592
- expect(addReducer).toHaveBeenCalledTimes(2);
593
- expect(addReducer).toHaveBeenCalledWith('0', 'x');
594
- expect(addReducer).toHaveReturnedWith('0x');
595
- addedText = 'y';
596
- fireEvent.click(screen.getByText(updateButtonText));
597
- expect(addReducer).toHaveBeenCalledTimes(3);
598
- expect(addReducer).toHaveBeenCalledWith('0', 'y');
599
- expect(addReducer).toHaveReturnedWith('0y');
600
- fireEvent.click(screen.getByText(updateButtonText));
601
- expect(addReducer).toHaveBeenCalledTimes(3);
1124
+ });
1125
+ expect(onExtChange).toHaveBeenCalledTimes(1);
1126
+ expect(onSizeChange).toHaveBeenCalledTimes(1);
1127
+ expect(onExtChange).toHaveBeenCalledWith({
1128
+ fieldPaths: ['list', '0', 'ext'],
1129
+ newEntity: {
1130
+ list: [defaultFile]
1131
+ },
1132
+ oldEntity: {},
1133
+ newValue: '',
1134
+ oldValue: void 0
1135
+ });
1136
+ expect(onSizeChange).toHaveBeenCalledWith({
1137
+ fieldPaths: ['list', '0', 'size'],
1138
+ newEntity: {
1139
+ list: [defaultFile]
1140
+ },
1141
+ oldEntity: {},
1142
+ newValue: 0,
1143
+ oldValue: void 0
1144
+ });
1145
+ act(() => {
1146
+ setEntity({
1147
+ list: [{
1148
+ ...defaultFile,
1149
+ ext: EXT_1
1150
+ }]
602
1151
  });
603
- test('`options.onChange` should be trigger when entity has changed', () => {
604
- const onChange = jest.fn();
605
- const { result } = renderHook(() => {
606
- return useUseCase(defaultFile, fileUseCase, { onChange });
607
- });
608
- const { current: cores } = result;
609
- const [, reducers] = cores;
610
- const { setPath } = reducers;
611
- expect(onChange).toHaveBeenCalledTimes(0);
612
- act(() => {
613
- setPath(PATH_1);
614
- });
615
- expect(onChange).toHaveBeenCalledTimes(1);
616
- expect(onChange).toHaveBeenLastCalledWith({ ...defaultFile, path: PATH_1, ext: EXT_1 }, defaultFile);
1152
+ });
1153
+ expect(onExtChange).toHaveBeenCalledTimes(2);
1154
+ expect(onSizeChange).toHaveBeenCalledTimes(1);
1155
+ expect(onExtChange).toHaveBeenCalledWith({
1156
+ fieldPaths: ['list', '0', 'ext'],
1157
+ newEntity: {
1158
+ list: [{
1159
+ ...defaultFile,
1160
+ ext: EXT_1
1161
+ }]
1162
+ },
1163
+ oldEntity: {
1164
+ list: [defaultFile]
1165
+ },
1166
+ newValue: EXT_1,
1167
+ oldValue: ''
1168
+ });
1169
+ act(() => {
1170
+ setEntity({
1171
+ list: [{
1172
+ ...defaultFile,
1173
+ ext: EXT_1
1174
+ }, {
1175
+ ...defaultFile,
1176
+ ext: EXT_2
1177
+ }]
617
1178
  });
618
- test('`options.onChange` should always trigger the latest one', () => {
619
- const onChange1 = jest.fn();
620
- const onChange2 = jest.fn();
621
- let onChange = onChange1;
622
- const { result } = renderHook(() => {
623
- return useUseCase(defaultFile, fileUseCase, { onChange }, []);
624
- });
625
- const { current: cores } = result;
626
- const [, reducers] = cores;
627
- const { setPath } = reducers;
628
- expect(onChange1).toHaveBeenCalledTimes(0);
629
- act(() => {
630
- setPath(PATH_1);
631
- onChange = onChange2;
632
- });
633
- expect(onChange2).toHaveBeenCalledTimes(0);
634
- expect(onChange1).toHaveBeenCalledTimes(1);
635
- expect(onChange1).toHaveBeenLastCalledWith({ ...defaultFile, path: PATH_1, ext: EXT_1 }, defaultFile);
636
- act(() => {
637
- setPath(PATH_2);
638
- });
639
- expect(onChange1).toHaveBeenCalledTimes(1);
640
- expect(onChange2).toHaveBeenCalledTimes(1);
641
- expect(onChange2).toHaveBeenLastCalledWith({ ...defaultFile, path: PATH_2, ext: EXT_2 }, { ...defaultFile, path: PATH_1, ext: EXT_1 });
1179
+ });
1180
+ expect(onExtChange).toHaveBeenCalledTimes(3);
1181
+ expect(onSizeChange).toHaveBeenCalledTimes(2);
1182
+ expect(onExtChange).toHaveBeenCalledWith({
1183
+ fieldPaths: ['list', '1', 'ext'],
1184
+ newEntity: {
1185
+ list: [{
1186
+ ...defaultFile,
1187
+ ext: EXT_1
1188
+ }, {
1189
+ ...defaultFile,
1190
+ ext: EXT_2
1191
+ }]
1192
+ },
1193
+ oldEntity: {
1194
+ list: [{
1195
+ ...defaultFile,
1196
+ ext: EXT_1
1197
+ }]
1198
+ },
1199
+ newValue: EXT_2,
1200
+ oldValue: void 0
1201
+ });
1202
+ expect(onSizeChange).toHaveBeenCalledWith({
1203
+ fieldPaths: ['list', '1', 'size'],
1204
+ newEntity: {
1205
+ list: [{
1206
+ ...defaultFile,
1207
+ ext: EXT_1
1208
+ }, {
1209
+ ...defaultFile,
1210
+ ext: EXT_2
1211
+ }]
1212
+ },
1213
+ oldEntity: {
1214
+ list: [{
1215
+ ...defaultFile,
1216
+ ext: EXT_1
1217
+ }]
1218
+ },
1219
+ newValue: 0,
1220
+ oldValue: void 0
1221
+ });
1222
+ act(() => {
1223
+ setEntity({
1224
+ nestedList: []
642
1225
  });
643
- test('`options.options` should override rest options', () => {
644
- const { result } = renderHook(() => {
645
- return useUseCase(defaultFile, fileUseCase, {
646
- pathPrefix: 'xyz/',
647
- options: { pathPrefix: '123/' },
648
- });
649
- });
650
- const { current: cores } = result;
651
- const [{ path }, reducers] = cores;
652
- const { setPath } = reducers;
653
- expect(path).toBe('');
654
- act(() => {
655
- setPath(PATH_1);
656
- });
657
- expect(result.current[0].path).toBe('123/' + PATH_1);
1226
+ });
1227
+ expect(onExtChange).toHaveBeenCalledTimes(3);
1228
+ expect(onSizeChange).toHaveBeenCalledTimes(2);
1229
+ act(() => {
1230
+ setEntity(() => {
1231
+ return {
1232
+ list: [{
1233
+ ...defaultFile,
1234
+ ext: EXT_2
1235
+ }, {
1236
+ ...defaultFile,
1237
+ ext: EXT_1
1238
+ }, defaultFile]
1239
+ };
658
1240
  });
659
- test('Option functions: use `T` (not `S`) when `S extends T`', () => {
660
- const testObjectUseCase = (options = {}) => {
661
- const objectReducers = objectUseCase();
662
- void options;
663
- return { ...objectReducers };
664
- };
665
- renderHook(() => {
666
- useUseCase(defaultFile, testObjectUseCase, {
667
- onUpdate(data) {
668
- void data;
669
- return Promise.reject();
670
- },
671
- });
672
- });
673
- // 这个测试仅仅是为了确保类型不会报错,不验证实际逻辑
674
- expect(1).toBe(1);
1241
+ });
1242
+ expect(onExtChange).toHaveBeenCalledTimes(6);
1243
+ expect(onSizeChange).toHaveBeenCalledTimes(3);
1244
+ expect(onExtChange).toHaveBeenNthCalledWith(4, {
1245
+ fieldPaths: ['list', '0', 'ext'],
1246
+ newEntity: {
1247
+ list: [{
1248
+ ...defaultFile,
1249
+ ext: EXT_2
1250
+ }, {
1251
+ ...defaultFile,
1252
+ ext: EXT_1
1253
+ }, defaultFile]
1254
+ },
1255
+ oldEntity: {
1256
+ list: [{
1257
+ ...defaultFile,
1258
+ ext: EXT_1
1259
+ }, {
1260
+ ...defaultFile,
1261
+ ext: EXT_2
1262
+ }],
1263
+ nestedList: []
1264
+ },
1265
+ newValue: EXT_2,
1266
+ oldValue: EXT_1
1267
+ });
1268
+ expect(onExtChange).toHaveBeenNthCalledWith(5, {
1269
+ fieldPaths: ['list', '1', 'ext'],
1270
+ newEntity: {
1271
+ list: [{
1272
+ ...defaultFile,
1273
+ ext: EXT_2
1274
+ }, {
1275
+ ...defaultFile,
1276
+ ext: EXT_1
1277
+ }, defaultFile]
1278
+ },
1279
+ oldEntity: {
1280
+ list: [{
1281
+ ...defaultFile,
1282
+ ext: EXT_1
1283
+ }, {
1284
+ ...defaultFile,
1285
+ ext: EXT_2
1286
+ }],
1287
+ nestedList: []
1288
+ },
1289
+ newValue: EXT_1,
1290
+ oldValue: EXT_2
1291
+ });
1292
+ expect(onExtChange).toHaveBeenNthCalledWith(6, {
1293
+ fieldPaths: ['list', '2', 'ext'],
1294
+ newEntity: {
1295
+ list: [{
1296
+ ...defaultFile,
1297
+ ext: EXT_2
1298
+ }, {
1299
+ ...defaultFile,
1300
+ ext: EXT_1
1301
+ }, defaultFile]
1302
+ },
1303
+ oldEntity: {
1304
+ list: [{
1305
+ ...defaultFile,
1306
+ ext: EXT_1
1307
+ }, {
1308
+ ...defaultFile,
1309
+ ext: EXT_2
1310
+ }],
1311
+ nestedList: []
1312
+ },
1313
+ newValue: '',
1314
+ oldValue: void 0
1315
+ });
1316
+ expect(onSizeChange).toHaveBeenCalledWith({
1317
+ fieldPaths: ['list', '2', 'size'],
1318
+ newEntity: {
1319
+ list: [{
1320
+ ...defaultFile,
1321
+ ext: EXT_2
1322
+ }, {
1323
+ ...defaultFile,
1324
+ ext: EXT_1
1325
+ }, defaultFile]
1326
+ },
1327
+ oldEntity: {
1328
+ list: [{
1329
+ ...defaultFile,
1330
+ ext: EXT_1
1331
+ }, {
1332
+ ...defaultFile,
1333
+ ext: EXT_2
1334
+ }],
1335
+ nestedList: []
1336
+ },
1337
+ newValue: 0,
1338
+ oldValue: void 0
1339
+ });
1340
+ act(() => {
1341
+ setEntity(() => {
1342
+ return {};
675
1343
  });
676
- test('when `options` has changed, it should not trigger update', () => {
677
- const onUpdate = jest.fn();
678
- const onDeepUpdate = jest.fn();
679
- const { result } = renderHook(() => {
680
- const [pathPrefix, setPathPrefix] = useState('user/');
681
- const context = useUseCase(defaultFile, fileUseCase, { pathPrefix });
682
- useUpdateEffect(() => {
683
- onUpdate();
684
- }, [context]);
685
- useDeepCompareUpdate(() => {
686
- onDeepUpdate();
687
- }, [context]);
688
- return setPathPrefix;
689
- });
690
- expect(onUpdate).toHaveBeenCalledTimes(0);
691
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
692
- act(() => {
693
- result.current('my/');
694
- });
695
- expect(onUpdate).toHaveBeenCalledTimes(0);
696
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
1344
+ });
1345
+ expect(onExtChange).toHaveBeenCalledTimes(9);
1346
+ expect(onSizeChange).toHaveBeenCalledTimes(6);
1347
+ expect(onExtChange).toHaveBeenNthCalledWith(7, {
1348
+ fieldPaths: ['list', '0', 'ext'],
1349
+ newEntity: {},
1350
+ oldEntity: {
1351
+ list: [{
1352
+ ...defaultFile,
1353
+ ext: EXT_2
1354
+ }, {
1355
+ ...defaultFile,
1356
+ ext: EXT_1
1357
+ }, defaultFile]
1358
+ },
1359
+ newValue: void 0,
1360
+ oldValue: EXT_2
1361
+ });
1362
+ expect(onExtChange).toHaveBeenNthCalledWith(8, {
1363
+ fieldPaths: ['list', '1', 'ext'],
1364
+ newEntity: {},
1365
+ oldEntity: {
1366
+ list: [{
1367
+ ...defaultFile,
1368
+ ext: EXT_2
1369
+ }, {
1370
+ ...defaultFile,
1371
+ ext: EXT_1
1372
+ }, defaultFile]
1373
+ },
1374
+ newValue: void 0,
1375
+ oldValue: EXT_1
1376
+ });
1377
+ expect(onExtChange).toHaveBeenNthCalledWith(9, {
1378
+ fieldPaths: ['list', '2', 'ext'],
1379
+ newEntity: {},
1380
+ oldEntity: {
1381
+ list: [{
1382
+ ...defaultFile,
1383
+ ext: EXT_2
1384
+ }, {
1385
+ ...defaultFile,
1386
+ ext: EXT_1
1387
+ }, defaultFile]
1388
+ },
1389
+ newValue: void 0,
1390
+ oldValue: ''
1391
+ });
1392
+ expect(onSizeChange).toHaveBeenNthCalledWith(4, {
1393
+ fieldPaths: ['list', '0', 'size'],
1394
+ newEntity: {},
1395
+ oldEntity: {
1396
+ list: [{
1397
+ ...defaultFile,
1398
+ ext: EXT_2
1399
+ }, {
1400
+ ...defaultFile,
1401
+ ext: EXT_1
1402
+ }, defaultFile]
1403
+ },
1404
+ newValue: void 0,
1405
+ oldValue: 0
1406
+ });
1407
+ expect(onSizeChange).toHaveBeenNthCalledWith(5, {
1408
+ fieldPaths: ['list', '1', 'size'],
1409
+ newEntity: {},
1410
+ oldEntity: {
1411
+ list: [{
1412
+ ...defaultFile,
1413
+ ext: EXT_2
1414
+ }, {
1415
+ ...defaultFile,
1416
+ ext: EXT_1
1417
+ }, defaultFile]
1418
+ },
1419
+ newValue: void 0,
1420
+ oldValue: 0
1421
+ });
1422
+ expect(onSizeChange).toHaveBeenNthCalledWith(6, {
1423
+ fieldPaths: ['list', '2', 'size'],
1424
+ newEntity: {},
1425
+ oldEntity: {
1426
+ list: [{
1427
+ ...defaultFile,
1428
+ ext: EXT_2
1429
+ }, {
1430
+ ...defaultFile,
1431
+ ext: EXT_1
1432
+ }, defaultFile]
1433
+ },
1434
+ newValue: void 0,
1435
+ oldValue: 0
1436
+ });
1437
+ });
1438
+ test('`options.watch` should work with field path of array length', () => {
1439
+ const onEntityLengthChange = jest.fn();
1440
+ const onListLengthChange = jest.fn();
1441
+ const lengthUseCase = () => {
1442
+ return entityUseCase();
1443
+ };
1444
+ const _renderHook29 = renderHook(() => {
1445
+ return useUseCase([], lengthUseCase, {
1446
+ watch: {
1447
+ length: onEntityLengthChange,
1448
+ 'list.length': onListLengthChange
1449
+ }
1450
+ });
1451
+ }),
1452
+ result = _renderHook29.result;
1453
+ const cores = result.current;
1454
+ const _cores14 = _slicedToArray(cores, 2),
1455
+ setEntity = _cores14[1].setEntity;
1456
+ expect(onEntityLengthChange).toHaveBeenCalledTimes(0);
1457
+ expect(onListLengthChange).toHaveBeenCalledTimes(0);
1458
+ act(() => {
1459
+ setEntity([{
1460
+ list: [defaultFile, defaultFile]
1461
+ }]);
1462
+ });
1463
+ expect(onEntityLengthChange).toHaveBeenCalledTimes(1);
1464
+ expect(onListLengthChange).toHaveBeenCalledTimes(1);
1465
+ expect(onEntityLengthChange).toHaveBeenCalledWith({
1466
+ fieldPaths: ['length'],
1467
+ newEntity: [{
1468
+ list: [defaultFile, defaultFile]
1469
+ }],
1470
+ oldEntity: [],
1471
+ newValue: 1,
1472
+ oldValue: 0
1473
+ });
1474
+ expect(onListLengthChange).toHaveBeenCalledWith({
1475
+ fieldPaths: ['0', 'list', 'length'],
1476
+ newEntity: [{
1477
+ list: [defaultFile, defaultFile]
1478
+ }],
1479
+ oldEntity: [],
1480
+ newValue: 2,
1481
+ oldValue: void 0
1482
+ });
1483
+ });
1484
+ test('`options.watch` should work with field path of nested array', () => {
1485
+ const initialData = {};
1486
+ const onChange = jest.fn();
1487
+ const _renderHook30 = renderHook(() => {
1488
+ return useUseCase(initialData, fieldPathUseCase, {
1489
+ watch: {
1490
+ 'nestedList.size': onChange
1491
+ }
1492
+ });
1493
+ }),
1494
+ result = _renderHook30.result;
1495
+ const cores = result.current;
1496
+ const _cores15 = _slicedToArray(cores, 2),
1497
+ setEntity = _cores15[1].setEntity;
1498
+ expect(onChange).toHaveBeenCalledTimes(0);
1499
+ act(() => {
1500
+ setEntity({
1501
+ nestedList: [[[defaultFile]]]
697
1502
  });
698
- test('when `deps` has changed, it should trigger update', () => {
699
- const onUpdate = jest.fn();
700
- const onDeepUpdate = jest.fn();
701
- const { result } = renderHook(() => {
702
- const [pathPrefix, setPathPrefix] = useState('user/');
703
- const context = useUseCase(defaultFile, fileUseCase, { pathPrefix }, [pathPrefix]);
704
- useUpdateEffect(() => {
705
- onUpdate();
706
- }, [context]);
707
- useDeepCompareUpdate(() => {
708
- onDeepUpdate();
709
- }, [context]);
710
- return setPathPrefix;
711
- });
712
- expect(onUpdate).toHaveBeenCalledTimes(0);
713
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
714
- act(() => {
715
- result.current('my/');
716
- });
717
- expect(onUpdate).toHaveBeenCalledTimes(1);
718
- expect(onDeepUpdate).toHaveBeenCalledTimes(1);
1503
+ });
1504
+ expect(onChange).toHaveBeenCalledTimes(1);
1505
+ expect(onChange).toHaveBeenCalledWith({
1506
+ fieldPaths: ['nestedList', '0', '0', '0', 'size'],
1507
+ newEntity: {
1508
+ nestedList: [[[defaultFile]]]
1509
+ },
1510
+ oldEntity: {},
1511
+ newValue: 0,
1512
+ oldValue: void 0
1513
+ });
1514
+ act(() => {
1515
+ setEntity({
1516
+ nestedList: [[[{
1517
+ ...defaultFile,
1518
+ size: 100
1519
+ }, {
1520
+ ...defaultFile,
1521
+ size: 200
1522
+ }]], [[{
1523
+ ...defaultFile,
1524
+ size: 300
1525
+ }]]]
719
1526
  });
720
- test('empty `deps` should not trigger update', () => {
721
- const onUpdate = jest.fn();
722
- const onDeepUpdate = jest.fn();
723
- const { result } = renderHook(() => {
724
- const [pathPrefix, setPathPrefix] = useState('user/');
725
- const context = useUseCase(defaultFile, fileUseCase, { pathPrefix }, []);
726
- useUpdateEffect(() => {
727
- onUpdate();
728
- }, [context]);
729
- useDeepCompareUpdate(() => {
730
- onDeepUpdate();
731
- }, [context]);
732
- return setPathPrefix;
733
- });
734
- expect(onUpdate).toHaveBeenCalledTimes(0);
735
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
736
- act(() => {
737
- result.current('my/');
738
- });
739
- expect(onUpdate).toHaveBeenCalledTimes(0);
740
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
1527
+ });
1528
+ expect(onChange).toHaveBeenCalledTimes(4);
1529
+ expect(onChange).toHaveBeenNthCalledWith(2, {
1530
+ fieldPaths: ['nestedList', '0', '0', '0', 'size'],
1531
+ newEntity: {
1532
+ nestedList: [[[{
1533
+ ...defaultFile,
1534
+ size: 100
1535
+ }, {
1536
+ ...defaultFile,
1537
+ size: 200
1538
+ }]], [[{
1539
+ ...defaultFile,
1540
+ size: 300
1541
+ }]]]
1542
+ },
1543
+ oldEntity: {
1544
+ nestedList: [[[defaultFile]]]
1545
+ },
1546
+ newValue: 100,
1547
+ oldValue: 0
1548
+ });
1549
+ expect(onChange).toHaveBeenNthCalledWith(3, {
1550
+ fieldPaths: ['nestedList', '0', '0', '1', 'size'],
1551
+ newEntity: {
1552
+ nestedList: [[[{
1553
+ ...defaultFile,
1554
+ size: 100
1555
+ }, {
1556
+ ...defaultFile,
1557
+ size: 200
1558
+ }]], [[{
1559
+ ...defaultFile,
1560
+ size: 300
1561
+ }]]]
1562
+ },
1563
+ oldEntity: {
1564
+ nestedList: [[[defaultFile]]]
1565
+ },
1566
+ newValue: 200,
1567
+ oldValue: void 0
1568
+ });
1569
+ expect(onChange).toHaveBeenNthCalledWith(4, {
1570
+ fieldPaths: ['nestedList', '1', '0', '0', 'size'],
1571
+ newEntity: {
1572
+ nestedList: [[[{
1573
+ ...defaultFile,
1574
+ size: 100
1575
+ }, {
1576
+ ...defaultFile,
1577
+ size: 200
1578
+ }]], [[{
1579
+ ...defaultFile,
1580
+ size: 300
1581
+ }]]]
1582
+ },
1583
+ oldEntity: {
1584
+ nestedList: [[[defaultFile]]]
1585
+ },
1586
+ newValue: 300,
1587
+ oldValue: void 0
1588
+ });
1589
+ });
1590
+ test('`options.watch` should work with field path of object', () => {
1591
+ const initialData = {};
1592
+ const onExtChange = jest.fn();
1593
+ const onSizeChange = jest.fn();
1594
+ const _renderHook31 = renderHook(() => {
1595
+ return useUseCase(initialData, fieldPathUseCase, {
1596
+ watch: {
1597
+ 'obj.file.ext': onExtChange,
1598
+ 'obj.file.size': onSizeChange
1599
+ }
1600
+ });
1601
+ }),
1602
+ result = _renderHook31.result;
1603
+ const cores = result.current;
1604
+ const _cores16 = _slicedToArray(cores, 2),
1605
+ setEntity = _cores16[1].setEntity;
1606
+ expect(onExtChange).toHaveBeenCalledTimes(0);
1607
+ act(() => {
1608
+ setEntity({
1609
+ obj: {
1610
+ file: {
1611
+ ext: EXT_1
1612
+ }
1613
+ }
741
1614
  });
742
- test(`should call latest functions of usecase options even deps has not change`, () => {
743
- const onPathChange1 = jest.fn();
744
- const onPathChange2 = jest.fn();
745
- let onPathChange = onPathChange1;
746
- const { result } = renderHook(() => {
747
- return useUseCase(defaultFile, fileUseCase, { onPathChange });
748
- });
749
- const { current: context } = result;
750
- const [, { setPath }] = context;
751
- act(() => {
752
- setPath(PATH_1);
753
- onPathChange = onPathChange2;
754
- });
755
- expect(onPathChange1).toHaveBeenCalledTimes(1);
756
- expect(onPathChange2).toHaveBeenCalledTimes(0);
757
- expect(onPathChange1).toHaveBeenLastCalledWith(PATH_1, '');
758
- act(() => {
759
- setPath(PATH_2);
760
- });
761
- expect(onPathChange1).toHaveBeenCalledTimes(1);
762
- expect(onPathChange2).toHaveBeenCalledTimes(1);
763
- expect(onPathChange2).toHaveBeenLastCalledWith(PATH_2, PATH_1);
1615
+ });
1616
+ expect(onExtChange).toHaveBeenCalledTimes(1);
1617
+ expect(onSizeChange).toHaveBeenCalledTimes(0);
1618
+ expect(onExtChange).toHaveBeenCalledWith({
1619
+ fieldPaths: ['obj', 'file', 'ext'],
1620
+ newEntity: {
1621
+ obj: {
1622
+ file: {
1623
+ ext: EXT_1
1624
+ }
1625
+ }
1626
+ },
1627
+ oldEntity: {},
1628
+ newValue: EXT_1,
1629
+ oldValue: void 0
1630
+ });
1631
+ act(() => {
1632
+ setEntity(() => {
1633
+ return {};
764
1634
  });
765
- test('`options.watch` should be trigger after entity changed', () => {
766
- const onPathChange = jest.fn();
767
- const onSizeChange = jest.fn();
768
- const { result } = renderHook(() => {
769
- return useUseCase(defaultFile, fileUseCase, {
770
- watch: {
771
- path: onPathChange,
772
- size: onSizeChange,
773
- },
774
- });
775
- });
776
- const { current: cores } = result;
777
- const [, { setPath }] = cores;
778
- expect(onPathChange).toHaveBeenCalledTimes(0);
779
- act(() => {
780
- setPath(PATH_1);
781
- });
782
- expect(onPathChange).toHaveBeenCalledTimes(1);
783
- expect(onSizeChange).toHaveBeenCalledTimes(0);
784
- expect(onPathChange).toHaveBeenLastCalledWith({
785
- fieldPaths: ['path'],
786
- newEntity: { ...defaultFile, path: PATH_1, ext: EXT_1 },
787
- oldEntity: defaultFile,
788
- newValue: PATH_1,
789
- oldValue: '',
790
- });
1635
+ });
1636
+ expect(onExtChange).toHaveBeenCalledTimes(2);
1637
+ expect(onSizeChange).toHaveBeenCalledTimes(0);
1638
+ expect(onExtChange).toHaveBeenCalledWith({
1639
+ fieldPaths: ['obj', 'file', 'ext'],
1640
+ newEntity: {},
1641
+ oldEntity: {
1642
+ obj: {
1643
+ file: {
1644
+ ext: EXT_1
1645
+ }
1646
+ }
1647
+ },
1648
+ newValue: void 0,
1649
+ oldValue: EXT_1
1650
+ });
1651
+ });
1652
+ test('multiple `Provider` should work', () => {
1653
+ const onNumberMount = jest.fn();
1654
+ const onStringMount = jest.fn();
1655
+ const onBooleanMount = jest.fn();
1656
+ const numberUseCase = () => {
1657
+ return entityUseCase();
1658
+ };
1659
+ const stringUseCase = () => {
1660
+ return entityUseCase();
1661
+ };
1662
+ const booleanUseCase = () => {
1663
+ return entityUseCase();
1664
+ };
1665
+ const TestChildComponent = () => {
1666
+ const _useUseCase10 = useUseCase(numberUseCase),
1667
+ _useUseCase11 = _slicedToArray(_useUseCase10, 1),
1668
+ numberValue = _useUseCase11[0];
1669
+ const _useUseCase12 = useUseCase(stringUseCase),
1670
+ _useUseCase13 = _slicedToArray(_useUseCase12, 1),
1671
+ stringValue = _useUseCase13[0];
1672
+ const _useUseCase14 = useUseCase(booleanUseCase),
1673
+ _useUseCase15 = _slicedToArray(_useUseCase14, 1),
1674
+ booleanValue = _useUseCase15[0];
1675
+ useMount(() => {
1676
+ onNumberMount(numberValue);
1677
+ onStringMount(stringValue);
1678
+ onBooleanMount(booleanValue);
791
1679
  });
792
- test('`options.watch` should trigger the latest one', () => {
793
- const onPathChange1 = jest.fn();
794
- const onPathChange2 = jest.fn();
795
- let onPathChange = onPathChange1;
796
- const { result } = renderHook(() => {
797
- return useUseCase(defaultFile, fileUseCase, {
798
- watch: {
799
- path: onPathChange,
800
- },
801
- });
802
- });
803
- const { current: cores } = result;
804
- const [, { setPath, setEntity }] = cores;
805
- expect(onPathChange1).toHaveBeenCalledTimes(0);
806
- act(() => {
807
- setPath(PATH_1);
808
- setEntity({ size: 5000 });
809
- onPathChange = onPathChange2;
810
- });
811
- expect(onPathChange1).toHaveBeenCalledTimes(1);
812
- expect(onPathChange1).toHaveBeenLastCalledWith({
813
- fieldPaths: ['path'],
814
- newEntity: { ...defaultFile, path: PATH_1, ext: EXT_1 },
815
- oldEntity: defaultFile,
816
- newValue: PATH_1,
817
- oldValue: '',
818
- });
819
- act(() => {
820
- setPath('');
821
- });
822
- expect(onPathChange1).toHaveBeenCalledTimes(1);
823
- expect(onPathChange2).toHaveBeenCalledTimes(1);
824
- expect(onPathChange2).toHaveBeenLastCalledWith({
825
- fieldPaths: ['path'],
826
- newEntity: { ...defaultFile, size: 5000 },
827
- oldEntity: { ...defaultFile, path: PATH_1, ext: EXT_1, size: 5000 },
828
- newValue: '',
829
- oldValue: PATH_1,
830
- });
1680
+ return null;
1681
+ };
1682
+ const TestParentComponent = () => {
1683
+ const _useUseCase16 = useUseCase(11, numberUseCase),
1684
+ _useUseCase17 = _slicedToArray(_useUseCase16, 3),
1685
+ NumberProvider = _useUseCase17[2];
1686
+ const _useUseCase18 = useUseCase('hello', stringUseCase),
1687
+ _useUseCase19 = _slicedToArray(_useUseCase18, 3),
1688
+ StringProvider = _useUseCase19[2];
1689
+ const _useUseCase20 = useUseCase(true, booleanUseCase),
1690
+ _useUseCase21 = _slicedToArray(_useUseCase20, 3),
1691
+ BooleanProvider = _useUseCase21[2];
1692
+ return _jsx(NumberProvider, {
1693
+ with: [StringProvider, BooleanProvider],
1694
+ children: _jsx(TestChildComponent, {})
831
1695
  });
832
- test('`options.watch` should work with array field path of array', () => {
833
- const initialData = {};
834
- const onExtChange = jest.fn();
835
- const onSizeChange = jest.fn();
836
- const { result } = renderHook(() => {
837
- return useUseCase(initialData, fieldPathUseCase, {
838
- watch: {
839
- 'list.ext': onExtChange,
840
- 'list.size': onSizeChange,
841
- },
842
- });
843
- });
844
- const { current: cores } = result;
845
- const [, { setEntity }] = cores;
846
- act(() => {
847
- setEntity({ list: [defaultFile] });
848
- });
849
- expect(onExtChange).toHaveBeenCalledTimes(1);
850
- expect(onSizeChange).toHaveBeenCalledTimes(1);
851
- expect(onExtChange).toHaveBeenCalledWith({
852
- fieldPaths: ['list', '0', 'ext'],
853
- newEntity: { list: [defaultFile] },
854
- oldEntity: {},
855
- newValue: '',
856
- oldValue: void 0,
857
- });
858
- expect(onSizeChange).toHaveBeenCalledWith({
859
- fieldPaths: ['list', '0', 'size'],
860
- newEntity: { list: [defaultFile] },
861
- oldEntity: {},
862
- newValue: 0,
863
- oldValue: void 0,
864
- });
865
- act(() => {
866
- setEntity({ list: [{ ...defaultFile, ext: EXT_1 }] });
867
- });
868
- expect(onExtChange).toHaveBeenCalledTimes(2);
869
- expect(onSizeChange).toHaveBeenCalledTimes(1);
870
- expect(onExtChange).toHaveBeenCalledWith({
871
- fieldPaths: ['list', '0', 'ext'],
872
- newEntity: { list: [{ ...defaultFile, ext: EXT_1 }] },
873
- oldEntity: { list: [defaultFile] },
874
- newValue: EXT_1,
875
- oldValue: '',
876
- });
877
- act(() => {
878
- setEntity({
879
- list: [
880
- { ...defaultFile, ext: EXT_1 },
881
- { ...defaultFile, ext: EXT_2 },
882
- ],
883
- });
884
- });
885
- expect(onExtChange).toHaveBeenCalledTimes(3);
886
- expect(onSizeChange).toHaveBeenCalledTimes(2);
887
- expect(onExtChange).toHaveBeenCalledWith({
888
- fieldPaths: ['list', '1', 'ext'],
889
- newEntity: {
890
- list: [
891
- { ...defaultFile, ext: EXT_1 },
892
- { ...defaultFile, ext: EXT_2 },
893
- ],
894
- },
895
- oldEntity: { list: [{ ...defaultFile, ext: EXT_1 }] },
896
- newValue: EXT_2,
897
- oldValue: void 0,
898
- });
899
- expect(onSizeChange).toHaveBeenCalledWith({
900
- fieldPaths: ['list', '1', 'size'],
901
- newEntity: {
902
- list: [
903
- { ...defaultFile, ext: EXT_1 },
904
- { ...defaultFile, ext: EXT_2 },
905
- ],
906
- },
907
- oldEntity: { list: [{ ...defaultFile, ext: EXT_1 }] },
908
- newValue: 0,
909
- oldValue: void 0,
910
- });
911
- act(() => {
912
- setEntity({
913
- nestedList: [],
914
- });
915
- });
916
- expect(onExtChange).toHaveBeenCalledTimes(3);
917
- expect(onSizeChange).toHaveBeenCalledTimes(2);
918
- act(() => {
919
- setEntity(() => {
920
- return {
921
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
922
- };
923
- });
924
- });
925
- expect(onExtChange).toHaveBeenCalledTimes(6);
926
- expect(onSizeChange).toHaveBeenCalledTimes(3);
927
- expect(onExtChange).toHaveBeenNthCalledWith(4, {
928
- fieldPaths: ['list', '0', 'ext'],
929
- newEntity: {
930
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
931
- },
932
- oldEntity: {
933
- list: [
934
- { ...defaultFile, ext: EXT_1 },
935
- { ...defaultFile, ext: EXT_2 },
936
- ],
937
- nestedList: [],
938
- },
939
- newValue: EXT_2,
940
- oldValue: EXT_1,
941
- });
942
- expect(onExtChange).toHaveBeenNthCalledWith(5, {
943
- fieldPaths: ['list', '1', 'ext'],
944
- newEntity: {
945
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
946
- },
947
- oldEntity: {
948
- list: [
949
- { ...defaultFile, ext: EXT_1 },
950
- { ...defaultFile, ext: EXT_2 },
951
- ],
952
- nestedList: [],
953
- },
954
- newValue: EXT_1,
955
- oldValue: EXT_2,
956
- });
957
- expect(onExtChange).toHaveBeenNthCalledWith(6, {
958
- fieldPaths: ['list', '2', 'ext'],
959
- newEntity: {
960
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
961
- },
962
- oldEntity: {
963
- list: [
964
- { ...defaultFile, ext: EXT_1 },
965
- { ...defaultFile, ext: EXT_2 },
966
- ],
967
- nestedList: [],
968
- },
969
- newValue: '',
970
- oldValue: void 0,
971
- });
972
- expect(onSizeChange).toHaveBeenCalledWith({
973
- fieldPaths: ['list', '2', 'size'],
974
- newEntity: {
975
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
976
- },
977
- oldEntity: {
978
- list: [
979
- { ...defaultFile, ext: EXT_1 },
980
- { ...defaultFile, ext: EXT_2 },
981
- ],
982
- nestedList: [],
983
- },
984
- newValue: 0,
985
- oldValue: void 0,
986
- });
987
- act(() => {
988
- setEntity(() => {
989
- return {};
990
- });
991
- });
992
- expect(onExtChange).toHaveBeenCalledTimes(9);
993
- expect(onSizeChange).toHaveBeenCalledTimes(6);
994
- expect(onExtChange).toHaveBeenNthCalledWith(7, {
995
- fieldPaths: ['list', '0', 'ext'],
996
- newEntity: {},
997
- oldEntity: {
998
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
999
- },
1000
- newValue: void 0,
1001
- oldValue: EXT_2,
1002
- });
1003
- expect(onExtChange).toHaveBeenNthCalledWith(8, {
1004
- fieldPaths: ['list', '1', 'ext'],
1005
- newEntity: {},
1006
- oldEntity: {
1007
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
1008
- },
1009
- newValue: void 0,
1010
- oldValue: EXT_1,
1011
- });
1012
- expect(onExtChange).toHaveBeenNthCalledWith(9, {
1013
- fieldPaths: ['list', '2', 'ext'],
1014
- newEntity: {},
1015
- oldEntity: {
1016
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
1017
- },
1018
- newValue: void 0,
1019
- oldValue: '',
1020
- });
1021
- expect(onSizeChange).toHaveBeenNthCalledWith(4, {
1022
- fieldPaths: ['list', '0', 'size'],
1023
- newEntity: {},
1024
- oldEntity: {
1025
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
1026
- },
1027
- newValue: void 0,
1028
- oldValue: 0,
1029
- });
1030
- expect(onSizeChange).toHaveBeenNthCalledWith(5, {
1031
- fieldPaths: ['list', '1', 'size'],
1032
- newEntity: {},
1033
- oldEntity: {
1034
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
1035
- },
1036
- newValue: void 0,
1037
- oldValue: 0,
1038
- });
1039
- expect(onSizeChange).toHaveBeenNthCalledWith(6, {
1040
- fieldPaths: ['list', '2', 'size'],
1041
- newEntity: {},
1042
- oldEntity: {
1043
- list: [{ ...defaultFile, ext: EXT_2 }, { ...defaultFile, ext: EXT_1 }, defaultFile],
1044
- },
1045
- newValue: void 0,
1046
- oldValue: 0,
1047
- });
1696
+ };
1697
+ render(_jsx(TestParentComponent, {}));
1698
+ expect(onNumberMount).toHaveBeenCalledWith(11);
1699
+ expect(onStringMount).toHaveBeenCalledWith('hello');
1700
+ expect(onBooleanMount).toHaveBeenCalledWith(true);
1701
+ });
1702
+ });
1703
+ describe('`useUseCase` should work the same as `useContextualCoreCollection`', () => {
1704
+ test('Provider should be returned in child component', () => {
1705
+ const onCore = jest.fn();
1706
+ const TestChild = () => {
1707
+ const core = useUseCase(fileUseCase);
1708
+ const length = core.length;
1709
+ const _core = _slicedToArray(core, 3),
1710
+ file = _core[0],
1711
+ Provider = _core[2];
1712
+ useEffect(() => {
1713
+ onCore(file, length, typeof Provider);
1048
1714
  });
1049
- test('`options.watch` should work with field path of array length', () => {
1050
- const onEntityLengthChange = jest.fn();
1051
- const onListLengthChange = jest.fn();
1052
- const lengthUseCase = () => {
1053
- return entityUseCase();
1715
+ return _jsx(Fragment, {});
1716
+ };
1717
+ const TestParent = () => {
1718
+ const _useUseCase22 = useUseCase(() => {
1719
+ return {
1720
+ ...defaultFile,
1721
+ ext: EXT_1
1054
1722
  };
1055
- const { result } = renderHook(() => {
1056
- return useUseCase([], lengthUseCase, {
1057
- watch: {
1058
- length: onEntityLengthChange,
1059
- 'list.length': onListLengthChange,
1060
- },
1061
- });
1062
- });
1063
- const { current: cores } = result;
1064
- const [, { setEntity }] = cores;
1065
- expect(onEntityLengthChange).toHaveBeenCalledTimes(0);
1066
- expect(onListLengthChange).toHaveBeenCalledTimes(0);
1067
- act(() => {
1068
- setEntity([{ list: [defaultFile, defaultFile] }]);
1069
- });
1070
- expect(onEntityLengthChange).toHaveBeenCalledTimes(1);
1071
- expect(onListLengthChange).toHaveBeenCalledTimes(1);
1072
- expect(onEntityLengthChange).toHaveBeenCalledWith({
1073
- fieldPaths: ['length'],
1074
- newEntity: [{ list: [defaultFile, defaultFile] }],
1075
- oldEntity: [],
1076
- newValue: 1,
1077
- oldValue: 0,
1078
- });
1079
- expect(onListLengthChange).toHaveBeenCalledWith({
1080
- fieldPaths: ['0', 'list', 'length'],
1081
- newEntity: [{ list: [defaultFile, defaultFile] }],
1082
- oldEntity: [],
1083
- newValue: 2,
1084
- oldValue: void 0,
1085
- });
1086
- });
1087
- test('`options.watch` should work with field path of nested array', () => {
1088
- const initialData = {};
1089
- const onChange = jest.fn();
1090
- const { result } = renderHook(() => {
1091
- return useUseCase(initialData, fieldPathUseCase, {
1092
- watch: {
1093
- 'nestedList.size': onChange,
1094
- },
1095
- });
1096
- });
1097
- const { current: cores } = result;
1098
- const [, { setEntity }] = cores;
1099
- expect(onChange).toHaveBeenCalledTimes(0);
1100
- act(() => {
1101
- setEntity({ nestedList: [[[defaultFile]]] });
1102
- });
1103
- expect(onChange).toHaveBeenCalledTimes(1);
1104
- expect(onChange).toHaveBeenCalledWith({
1105
- fieldPaths: ['nestedList', '0', '0', '0', 'size'],
1106
- newEntity: { nestedList: [[[defaultFile]]] },
1107
- oldEntity: {},
1108
- newValue: 0,
1109
- oldValue: void 0,
1110
- });
1111
- act(() => {
1112
- setEntity({
1113
- nestedList: [
1114
- [
1115
- [
1116
- { ...defaultFile, size: 100 },
1117
- { ...defaultFile, size: 200 },
1118
- ],
1119
- ],
1120
- [[{ ...defaultFile, size: 300 }]],
1121
- ],
1122
- });
1123
- });
1124
- expect(onChange).toHaveBeenCalledTimes(4);
1125
- expect(onChange).toHaveBeenNthCalledWith(2, {
1126
- fieldPaths: ['nestedList', '0', '0', '0', 'size'],
1127
- newEntity: {
1128
- nestedList: [
1129
- [
1130
- [
1131
- { ...defaultFile, size: 100 },
1132
- { ...defaultFile, size: 200 },
1133
- ],
1134
- ],
1135
- [[{ ...defaultFile, size: 300 }]],
1136
- ],
1137
- },
1138
- oldEntity: { nestedList: [[[defaultFile]]] },
1139
- newValue: 100,
1140
- oldValue: 0,
1141
- });
1142
- expect(onChange).toHaveBeenNthCalledWith(3, {
1143
- fieldPaths: ['nestedList', '0', '0', '1', 'size'],
1144
- newEntity: {
1145
- nestedList: [
1146
- [
1147
- [
1148
- { ...defaultFile, size: 100 },
1149
- { ...defaultFile, size: 200 },
1150
- ],
1151
- ],
1152
- [[{ ...defaultFile, size: 300 }]],
1153
- ],
1154
- },
1155
- oldEntity: { nestedList: [[[defaultFile]]] },
1156
- newValue: 200,
1157
- oldValue: void 0,
1158
- });
1159
- expect(onChange).toHaveBeenNthCalledWith(4, {
1160
- fieldPaths: ['nestedList', '1', '0', '0', 'size'],
1161
- newEntity: {
1162
- nestedList: [
1163
- [
1164
- [
1165
- { ...defaultFile, size: 100 },
1166
- { ...defaultFile, size: 200 },
1167
- ],
1168
- ],
1169
- [[{ ...defaultFile, size: 300 }]],
1170
- ],
1171
- },
1172
- oldEntity: { nestedList: [[[defaultFile]]] },
1173
- newValue: 300,
1174
- oldValue: void 0,
1175
- });
1723
+ }, fileUseCase),
1724
+ _useUseCase23 = _slicedToArray(_useUseCase22, 3),
1725
+ Provider = _useUseCase23[2];
1726
+ return _jsx(Provider, {
1727
+ children: _jsx(TestChild, {})
1176
1728
  });
1177
- test('`options.watch` should work with field path of object', () => {
1178
- const initialData = {};
1179
- const onExtChange = jest.fn();
1180
- const onSizeChange = jest.fn();
1181
- const { result } = renderHook(() => {
1182
- return useUseCase(initialData, fieldPathUseCase, {
1183
- watch: {
1184
- 'obj.file.ext': onExtChange,
1185
- 'obj.file.size': onSizeChange,
1186
- },
1187
- });
1188
- });
1189
- const { current: cores } = result;
1190
- const [, { setEntity }] = cores;
1191
- expect(onExtChange).toHaveBeenCalledTimes(0);
1192
- act(() => {
1193
- setEntity({
1194
- obj: {
1195
- file: {
1196
- ext: EXT_1,
1197
- },
1198
- },
1199
- });
1200
- });
1201
- expect(onExtChange).toHaveBeenCalledTimes(1);
1202
- expect(onSizeChange).toHaveBeenCalledTimes(0);
1203
- expect(onExtChange).toHaveBeenCalledWith({
1204
- fieldPaths: ['obj', 'file', 'ext'],
1205
- newEntity: {
1206
- obj: {
1207
- file: {
1208
- ext: EXT_1,
1209
- },
1210
- },
1211
- },
1212
- oldEntity: {},
1213
- newValue: EXT_1,
1214
- oldValue: void 0,
1215
- });
1216
- act(() => {
1217
- setEntity(() => {
1218
- return {};
1219
- });
1220
- });
1221
- expect(onExtChange).toHaveBeenCalledTimes(2);
1222
- expect(onSizeChange).toHaveBeenCalledTimes(0);
1223
- expect(onExtChange).toHaveBeenCalledWith({
1224
- fieldPaths: ['obj', 'file', 'ext'],
1225
- newEntity: {},
1226
- oldEntity: {
1227
- obj: {
1228
- file: {
1229
- ext: EXT_1,
1230
- },
1231
- },
1232
- },
1233
- newValue: void 0,
1234
- oldValue: EXT_1,
1235
- });
1729
+ };
1730
+ render(_jsx(TestParent, {}));
1731
+ expect(onCore).toHaveBeenCalledWith({
1732
+ ...defaultFile,
1733
+ ext: EXT_1
1734
+ }, 3, 'function');
1735
+ });
1736
+ test('Provider should work in child component or popup component', () => {
1737
+ const onChange = jest.fn();
1738
+ const onRootFile = jest.fn();
1739
+ const onPopupFile = jest.fn();
1740
+ const buttonText = 'button';
1741
+ const Popup = () => {
1742
+ const _useUseCase24 = useUseCase(fileUseCase),
1743
+ _useUseCase25 = _slicedToArray(_useUseCase24, 2),
1744
+ file = _useUseCase25[0],
1745
+ setEntity = _useUseCase25[1].setEntity;
1746
+ const onClick = () => {
1747
+ setEntity({
1748
+ ext: EXT_2
1749
+ });
1750
+ };
1751
+ useEffect(() => {
1752
+ onPopupFile(file);
1753
+ }, [file]);
1754
+ return _jsx("button", {
1755
+ onClick: onClick,
1756
+ children: buttonText
1236
1757
  });
1237
- test('multiple `Provider` should work', () => {
1238
- const onNumberMount = jest.fn();
1239
- const onStringMount = jest.fn();
1240
- const onBooleanMount = jest.fn();
1241
- const numberUseCase = () => {
1242
- return entityUseCase();
1243
- };
1244
- const stringUseCase = () => {
1245
- return entityUseCase();
1246
- };
1247
- const booleanUseCase = () => {
1248
- return entityUseCase();
1249
- };
1250
- const TestChildComponent = () => {
1251
- const [numberValue] = useUseCase(numberUseCase);
1252
- const [stringValue] = useUseCase(stringUseCase);
1253
- const [booleanValue] = useUseCase(booleanUseCase);
1254
- useMount(() => {
1255
- onNumberMount(numberValue);
1256
- onStringMount(stringValue);
1257
- onBooleanMount(booleanValue);
1258
- });
1259
- return null;
1260
- };
1261
- const TestParentComponent = () => {
1262
- const [, , NumberProvider] = useUseCase(11, numberUseCase);
1263
- const [, , StringProvider] = useUseCase('hello', stringUseCase);
1264
- const [, , BooleanProvider] = useUseCase(true, booleanUseCase);
1265
- return (_jsx(NumberProvider, { with: [StringProvider, BooleanProvider], children: _jsx(TestChildComponent, {}) }));
1758
+ };
1759
+ const TestChild = () => {
1760
+ const _useUseCase26 = useUseCase(fileUseCase),
1761
+ _useUseCase27 = _slicedToArray(_useUseCase26, 3),
1762
+ Provider = _useUseCase27[2];
1763
+ return createPortal(_jsx(Provider, {
1764
+ children: _jsx(Popup, {})
1765
+ }), document.body);
1766
+ };
1767
+ const TestParent = () => {
1768
+ const _useUseCase28 = useUseCase(() => {
1769
+ return {
1770
+ ...defaultFile,
1771
+ ext: EXT_1
1266
1772
  };
1267
- render(_jsx(TestParentComponent, {}));
1268
- expect(onNumberMount).toHaveBeenCalledWith(11);
1269
- expect(onStringMount).toHaveBeenCalledWith('hello');
1270
- expect(onBooleanMount).toHaveBeenCalledWith(true);
1773
+ }, fileUseCase, {
1774
+ onChange
1775
+ }),
1776
+ _useUseCase29 = _slicedToArray(_useUseCase28, 3),
1777
+ file = _useUseCase29[0],
1778
+ Provider = _useUseCase29[2];
1779
+ useEffect(() => {
1780
+ onRootFile(file);
1781
+ }, [file]);
1782
+ return _jsx(Provider, {
1783
+ children: _jsx(TestChild, {})
1271
1784
  });
1785
+ };
1786
+ render(_jsx(TestParent, {}));
1787
+ expect(onRootFile).toHaveBeenCalledWith({
1788
+ ...defaultFile,
1789
+ ext: EXT_1
1790
+ });
1791
+ expect(onPopupFile).toHaveBeenCalledWith({
1792
+ ...defaultFile,
1793
+ ext: EXT_1
1794
+ });
1795
+ fireEvent.click(screen.getByText(buttonText));
1796
+ expect(onRootFile).toHaveBeenCalledWith({
1797
+ ...defaultFile,
1798
+ ext: EXT_2
1799
+ });
1800
+ expect(onPopupFile).toHaveBeenCalledWith({
1801
+ ...defaultFile,
1802
+ ext: EXT_2
1803
+ });
1272
1804
  });
1273
- describe('`useUseCase` should work the same as `useContextualCoreCollection`', () => {
1274
- test('Provider should be returned in child component', () => {
1275
- const onCore = jest.fn();
1276
- const TestChild = () => {
1277
- const core = useUseCase(fileUseCase);
1278
- const { length } = core;
1279
- const [file, , Provider] = core;
1280
- useEffect(() => {
1281
- onCore(file, length, typeof Provider);
1282
- });
1283
- return _jsx(Fragment, {});
1284
- };
1285
- const TestParent = () => {
1286
- const [, , Provider] = useUseCase(() => {
1287
- return { ...defaultFile, ext: EXT_1 };
1288
- }, fileUseCase);
1289
- return (_jsx(Provider, { children: _jsx(TestChild, {}) }));
1290
- };
1291
- render(_jsx(TestParent, {}));
1292
- expect(onCore).toHaveBeenCalledWith({ ...defaultFile, ext: EXT_1 }, 3, 'function');
1805
+ test('Should trigger Parent & Child to update', () => {
1806
+ const onParentUpdate = jest.fn();
1807
+ const onChildUpdate = jest.fn();
1808
+ const onPathChange = jest.fn();
1809
+ const onUndefinedEntity = jest.fn();
1810
+ const onSetPath = jest.fn(() => {
1811
+ return PATH_1;
1812
+ });
1813
+ render(_jsx("div", {
1814
+ children: _jsx(Parent, {
1815
+ onSetPath: onSetPath,
1816
+ onUpdate: onParentUpdate,
1817
+ children: _jsx(Child, {
1818
+ onUpdate: onChildUpdate,
1819
+ onPathChange: onPathChange,
1820
+ onUndefinedEntity: onUndefinedEntity
1821
+ })
1822
+ })
1823
+ }));
1824
+ fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
1825
+ expect(onSetPath).toHaveBeenCalledTimes(1);
1826
+ expect(onParentUpdate).toHaveBeenCalledTimes(1);
1827
+ expect(onChildUpdate).toHaveBeenCalledTimes(1);
1828
+ expect(onPathChange).toHaveBeenCalledWith(PATH_1);
1829
+ fireEvent.click(screen.getByText(CHILD_BUTTON_TEXT));
1830
+ expect(onSetPath).toHaveBeenCalledTimes(1);
1831
+ expect(onParentUpdate).toHaveBeenCalledTimes(2);
1832
+ expect(onChildUpdate).toHaveBeenCalledTimes(2);
1833
+ expect(onPathChange).toHaveBeenCalledWith(PATH_2);
1834
+ expect(onUndefinedEntity).toHaveBeenCalledTimes(0);
1835
+ });
1836
+ test('`usecase` should not be called at child component', () => {
1837
+ const mockUseCase = jest.fn(fileUseCase);
1838
+ const A = () => {
1839
+ useUseCase(mockUseCase);
1840
+ return _jsx(Fragment, {});
1841
+ };
1842
+ const B = () => {
1843
+ const _useUseCase30 = useUseCase(defaultFile, mockUseCase),
1844
+ _useUseCase31 = _slicedToArray(_useUseCase30, 3),
1845
+ Provider = _useUseCase31[2];
1846
+ return _jsx(Provider, {
1847
+ children: _jsx(A, {})
1293
1848
  });
1294
- test('Provider should work in child component or popup component', () => {
1295
- const onChange = jest.fn();
1296
- const onRootFile = jest.fn();
1297
- const onPopupFile = jest.fn();
1298
- const buttonText = 'button';
1299
- const Popup = () => {
1300
- const [file, { setEntity }] = useUseCase(fileUseCase);
1301
- const onClick = () => {
1302
- setEntity({ ext: EXT_2 });
1303
- };
1304
- useEffect(() => {
1305
- onPopupFile(file);
1306
- }, [file]);
1307
- return _jsx("button", { onClick: onClick, children: buttonText });
1308
- };
1309
- const TestChild = () => {
1310
- const [, , Provider] = useUseCase(fileUseCase);
1311
- return createPortal(_jsx(Provider, { children: _jsx(Popup, {}) }), document.body);
1312
- };
1313
- const TestParent = () => {
1314
- const [file, , Provider] = useUseCase(() => {
1315
- return { ...defaultFile, ext: EXT_1 };
1316
- }, fileUseCase, { onChange });
1317
- useEffect(() => {
1318
- onRootFile(file);
1319
- }, [file]);
1320
- return (_jsx(Provider, { children: _jsx(TestChild, {}) }));
1321
- };
1322
- render(_jsx(TestParent, {}));
1323
- expect(onRootFile).toHaveBeenCalledWith({ ...defaultFile, ext: EXT_1 });
1324
- expect(onPopupFile).toHaveBeenCalledWith({ ...defaultFile, ext: EXT_1 });
1325
- fireEvent.click(screen.getByText(buttonText));
1326
- expect(onRootFile).toHaveBeenCalledWith({ ...defaultFile, ext: EXT_2 });
1327
- expect(onPopupFile).toHaveBeenCalledWith({ ...defaultFile, ext: EXT_2 });
1849
+ };
1850
+ render(_jsx(B, {}));
1851
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
1852
+ });
1853
+ test('reducer call should be cached if component is at rendering phase in child components', () => {
1854
+ const buttonText = 'button';
1855
+ const addReducer = jest.fn((entity, substring) => {
1856
+ return entity + substring;
1857
+ });
1858
+ const stringUseCase = () => {
1859
+ const entityReducers = entityUseCase();
1860
+ return {
1861
+ ...entityReducers,
1862
+ add: addReducer
1863
+ };
1864
+ };
1865
+ const A = () => {
1866
+ const _useUseCase32 = useUseCase(stringUseCase),
1867
+ _useUseCase33 = _slicedToArray(_useUseCase32, 2),
1868
+ add = _useUseCase33[1].add;
1869
+ const update = useUpdate();
1870
+ const onClick = () => {
1871
+ update();
1872
+ };
1873
+ add('x');
1874
+ return _jsx("button", {
1875
+ onClick: onClick,
1876
+ children: buttonText
1328
1877
  });
1329
- test('Should trigger Parent & Child to update', () => {
1330
- const onParentUpdate = jest.fn();
1331
- const onChildUpdate = jest.fn();
1332
- const onPathChange = jest.fn();
1333
- const onUndefinedEntity = jest.fn();
1334
- const onSetPath = jest.fn(() => {
1335
- return PATH_1;
1336
- });
1337
- render(_jsx("div", { children: _jsx(Parent, { onSetPath: onSetPath, onUpdate: onParentUpdate, children: _jsx(Child, { onUpdate: onChildUpdate, onPathChange: onPathChange, onUndefinedEntity: onUndefinedEntity }) }) }));
1338
- fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
1339
- expect(onSetPath).toHaveBeenCalledTimes(1);
1340
- expect(onParentUpdate).toHaveBeenCalledTimes(1);
1341
- expect(onChildUpdate).toHaveBeenCalledTimes(1);
1342
- expect(onPathChange).toHaveBeenCalledWith(PATH_1);
1343
- fireEvent.click(screen.getByText(CHILD_BUTTON_TEXT));
1344
- expect(onSetPath).toHaveBeenCalledTimes(1);
1345
- expect(onParentUpdate).toHaveBeenCalledTimes(2);
1346
- expect(onChildUpdate).toHaveBeenCalledTimes(2);
1347
- expect(onPathChange).toHaveBeenCalledWith(PATH_2);
1348
- expect(onUndefinedEntity).toHaveBeenCalledTimes(0);
1878
+ };
1879
+ const B = () => {
1880
+ const _useUseCase34 = useUseCase('', stringUseCase),
1881
+ _useUseCase35 = _slicedToArray(_useUseCase34, 3),
1882
+ Provider = _useUseCase35[2];
1883
+ return _jsx(Provider, {
1884
+ children: _jsx(A, {})
1349
1885
  });
1350
- test('`usecase` should not be called at child component', () => {
1351
- const mockUseCase = jest.fn(fileUseCase);
1352
- const A = () => {
1353
- useUseCase(mockUseCase);
1354
- return _jsx(Fragment, {});
1355
- };
1356
- const B = () => {
1357
- const [, , Provider] = useUseCase(defaultFile, mockUseCase);
1358
- return (_jsx(Provider, { children: _jsx(A, {}) }));
1359
- };
1360
- render(_jsx(B, {}));
1361
- expect(mockUseCase).toHaveBeenCalledTimes(1);
1886
+ };
1887
+ render(_jsx(B, {}));
1888
+ expect(addReducer).toHaveBeenCalledTimes(1);
1889
+ expect(addReducer).toHaveBeenCalledWith('', 'x');
1890
+ expect(addReducer).toHaveReturnedWith('x');
1891
+ fireEvent.click(screen.getByText(buttonText));
1892
+ expect(addReducer).toHaveBeenCalledTimes(1);
1893
+ });
1894
+ test('reducer call should not be cached if component is not at rendering phase in child components', () => {
1895
+ const buttonText = 'button';
1896
+ const addReducer = jest.fn((entity, substring) => {
1897
+ return entity + substring;
1898
+ });
1899
+ const stringUseCase = () => {
1900
+ const entityReducers = entityUseCase();
1901
+ return {
1902
+ ...entityReducers,
1903
+ add: addReducer
1904
+ };
1905
+ };
1906
+ const A = () => {
1907
+ const _useUseCase36 = useUseCase(stringUseCase),
1908
+ _useUseCase37 = _slicedToArray(_useUseCase36, 2),
1909
+ add = _useUseCase37[1].add;
1910
+ const onClick = () => {
1911
+ add('x');
1912
+ };
1913
+ useMount(() => {
1914
+ add('x');
1915
+ add('x');
1362
1916
  });
1363
- test('reducer call should be cached if component is at rendering phase in child components', () => {
1364
- const buttonText = 'button';
1365
- const addReducer = jest.fn((entity, substring) => {
1366
- return entity + substring;
1367
- });
1368
- const stringUseCase = () => {
1369
- const entityReducers = entityUseCase();
1370
- return {
1371
- ...entityReducers,
1372
- add: addReducer,
1373
- };
1374
- };
1375
- const A = () => {
1376
- const [, { add }] = useUseCase(stringUseCase);
1377
- const update = useUpdate();
1378
- const onClick = () => {
1379
- update();
1380
- };
1381
- add('x');
1382
- return _jsx("button", { onClick: onClick, children: buttonText });
1383
- };
1384
- const B = () => {
1385
- const [, , Provider] = useUseCase('', stringUseCase);
1386
- return (_jsx(Provider, { children: _jsx(A, {}) }));
1387
- };
1388
- render(_jsx(B, {}));
1389
- expect(addReducer).toHaveBeenCalledTimes(1);
1390
- expect(addReducer).toHaveBeenCalledWith('', 'x');
1391
- expect(addReducer).toHaveReturnedWith('x');
1392
- fireEvent.click(screen.getByText(buttonText));
1393
- expect(addReducer).toHaveBeenCalledTimes(1);
1917
+ return _jsx("button", {
1918
+ onClick: onClick,
1919
+ children: buttonText
1394
1920
  });
1395
- test('reducer call should not be cached if component is not at rendering phase in child components', () => {
1396
- const buttonText = 'button';
1397
- const addReducer = jest.fn((entity, substring) => {
1398
- return entity + substring;
1399
- });
1400
- const stringUseCase = () => {
1401
- const entityReducers = entityUseCase();
1402
- return {
1403
- ...entityReducers,
1404
- add: addReducer,
1405
- };
1406
- };
1407
- const A = () => {
1408
- const [, { add }] = useUseCase(stringUseCase);
1409
- const onClick = () => {
1410
- add('x');
1411
- };
1412
- useMount(() => {
1413
- add('x');
1414
- add('x');
1415
- });
1416
- return _jsx("button", { onClick: onClick, children: buttonText });
1417
- };
1418
- const B = () => {
1419
- const [, , Provider] = useUseCase('', stringUseCase);
1420
- return (_jsx(Provider, { children: _jsx(A, {}) }));
1421
- };
1422
- render(_jsx(B, {}));
1423
- expect(addReducer).toHaveBeenCalledTimes(2);
1424
- expect(addReducer).toHaveBeenNthCalledWith(1, '', 'x');
1425
- expect(addReducer).toHaveBeenNthCalledWith(2, '', 'x');
1426
- fireEvent.click(screen.getByText(buttonText));
1427
- expect(addReducer).toHaveBeenCalledTimes(3);
1428
- expect(addReducer).toHaveBeenNthCalledWith(3, '', 'x');
1921
+ };
1922
+ const B = () => {
1923
+ const _useUseCase38 = useUseCase('', stringUseCase),
1924
+ _useUseCase39 = _slicedToArray(_useUseCase38, 3),
1925
+ Provider = _useUseCase39[2];
1926
+ return _jsx(Provider, {
1927
+ children: _jsx(A, {})
1429
1928
  });
1430
- test('reducer call should not be cached if entity or parameters have changed in child components', () => {
1431
- let count = 0;
1432
- let addedText = 'x';
1433
- const setButtonText = 'button';
1434
- const updateButtonText = 'update';
1435
- const addReducer = jest.fn((entity, substring) => {
1436
- return entity + substring;
1437
- });
1438
- const stringUseCase = () => {
1439
- const entityReducers = entityUseCase();
1440
- return {
1441
- ...entityReducers,
1442
- add: addReducer,
1443
- };
1444
- };
1445
- const A = () => {
1446
- const [, { add, setEntity }] = useUseCase(stringUseCase);
1447
- const update = useUpdate();
1448
- add(addedText);
1449
- const onSet = () => {
1450
- setEntity(`${count++}`);
1451
- };
1452
- const onUpdate = () => {
1453
- update();
1454
- };
1455
- return (_jsxs("div", { children: [_jsx("button", { onClick: onSet, children: setButtonText }), _jsx("button", { onClick: onUpdate, children: updateButtonText })] }));
1456
- };
1457
- const B = () => {
1458
- const [, , Provider] = useUseCase('', stringUseCase);
1459
- return (_jsx(Provider, { children: _jsx(A, {}) }));
1460
- };
1461
- render(_jsx(B, {}));
1462
- expect(addReducer).toHaveBeenCalledTimes(1);
1463
- expect(addReducer).toHaveBeenCalledWith('', 'x');
1464
- fireEvent.click(screen.getByText(setButtonText));
1465
- expect(addReducer).toHaveBeenCalledTimes(2);
1466
- expect(addReducer).toHaveBeenCalledWith('0', 'x');
1467
- expect(addReducer).toHaveReturnedWith('0x');
1468
- addedText = 'y';
1469
- fireEvent.click(screen.getByText(updateButtonText));
1470
- expect(addReducer).toHaveBeenCalledTimes(3);
1471
- expect(addReducer).toHaveBeenCalledWith('0', 'y');
1472
- expect(addReducer).toHaveReturnedWith('0y');
1473
- fireEvent.click(screen.getByText(updateButtonText));
1474
- expect(addReducer).toHaveBeenCalledTimes(3);
1929
+ };
1930
+ render(_jsx(B, {}));
1931
+ expect(addReducer).toHaveBeenCalledTimes(2);
1932
+ expect(addReducer).toHaveBeenNthCalledWith(1, '', 'x');
1933
+ expect(addReducer).toHaveBeenNthCalledWith(2, '', 'x');
1934
+ fireEvent.click(screen.getByText(buttonText));
1935
+ expect(addReducer).toHaveBeenCalledTimes(3);
1936
+ expect(addReducer).toHaveBeenNthCalledWith(3, '', 'x');
1937
+ });
1938
+ test('reducer call should not be cached if entity or parameters have changed in child components', () => {
1939
+ let count = 0;
1940
+ let addedText = 'x';
1941
+ const setButtonText = 'button';
1942
+ const updateButtonText = 'update';
1943
+ const addReducer = jest.fn((entity, substring) => {
1944
+ return entity + substring;
1945
+ });
1946
+ const stringUseCase = () => {
1947
+ const entityReducers = entityUseCase();
1948
+ return {
1949
+ ...entityReducers,
1950
+ add: addReducer
1951
+ };
1952
+ };
1953
+ const A = () => {
1954
+ const _useUseCase40 = useUseCase(stringUseCase),
1955
+ _useUseCase41 = _slicedToArray(_useUseCase40, 2),
1956
+ _useUseCase41$ = _useUseCase41[1],
1957
+ add = _useUseCase41$.add,
1958
+ setEntity = _useUseCase41$.setEntity;
1959
+ const update = useUpdate();
1960
+ add(addedText);
1961
+ const onSet = () => {
1962
+ setEntity(`${count++}`);
1963
+ };
1964
+ const onUpdate = () => {
1965
+ update();
1966
+ };
1967
+ return _jsxs("div", {
1968
+ children: [_jsx("button", {
1969
+ onClick: onSet,
1970
+ children: setButtonText
1971
+ }), _jsx("button", {
1972
+ onClick: onUpdate,
1973
+ children: updateButtonText
1974
+ })]
1475
1975
  });
1476
- test('`options.onChange` event should be trigger in orders', () => {
1477
- let changeTimes = 0;
1478
- const updateChangeTimes = () => {
1479
- return ++changeTimes;
1480
- };
1481
- const onChangeA = jest.fn(updateChangeTimes);
1482
- const onChangeB = jest.fn(updateChangeTimes);
1483
- const onChangeC = jest.fn(updateChangeTimes);
1484
- const buttonText = 'my button';
1485
- const A = ({ children }) => {
1486
- useUseCase(fileUseCase, { onChange: onChangeA });
1487
- return _jsx(Fragment, { children: children });
1488
- };
1489
- const B = () => {
1490
- useUseCase(fileUseCase, { onChange: onChangeB });
1491
- return _jsx(Fragment, {});
1492
- };
1493
- const C = () => {
1494
- const [, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase, {
1495
- onChange: onChangeC,
1496
- });
1497
- const onFirstClick = () => {
1498
- setPath(PATH_1);
1499
- };
1500
- return (_jsxs(Provider, { children: [_jsx(A, { children: _jsx(B, {}) }), _jsx("button", { onClick: onFirstClick, children: buttonText })] }));
1501
- };
1502
- render(_jsx(C, {}));
1503
- expect(changeTimes).toBe(0);
1504
- fireEvent.click(screen.getByText(buttonText));
1505
- expect(onChangeA).toHaveReturnedWith(2);
1506
- expect(onChangeB).toHaveReturnedWith(3);
1507
- expect(onChangeC).toHaveReturnedWith(1);
1976
+ };
1977
+ const B = () => {
1978
+ const _useUseCase42 = useUseCase('', stringUseCase),
1979
+ _useUseCase43 = _slicedToArray(_useUseCase42, 3),
1980
+ Provider = _useUseCase43[2];
1981
+ return _jsx(Provider, {
1982
+ children: _jsx(A, {})
1508
1983
  });
1509
- test('`options.onChange` should always trigger the latest one in child components', () => {
1510
- const onFirstChange = jest.fn();
1511
- const onSecondChange = jest.fn();
1512
- let onChange = onFirstChange;
1513
- const firstButtonText = 'first button';
1514
- const secondButtonText = 'second button';
1515
- const A = () => {
1516
- const [, { setPath }] = useUseCase(fileUseCase, {
1517
- onChange,
1518
- });
1519
- const onFirstClick = () => {
1520
- setPath(PATH_1);
1521
- onChange = onSecondChange;
1522
- };
1523
- const onSecondClick = () => {
1524
- setPath('');
1525
- };
1526
- return (_jsxs(Fragment, { children: [_jsx("button", { onClick: onFirstClick, children: firstButtonText }), _jsx("button", { onClick: onSecondClick, children: secondButtonText })] }));
1527
- };
1528
- const B = () => {
1529
- const [, , Provider] = useUseCase(defaultFile, fileUseCase);
1530
- return (_jsx(Provider, { children: _jsx(A, {}) }));
1531
- };
1532
- render(_jsx(B, {}));
1533
- expect(onFirstChange).toHaveBeenCalledTimes(0);
1534
- fireEvent.click(screen.getByText(firstButtonText));
1535
- expect(onFirstChange).toHaveBeenCalledTimes(1);
1536
- expect(onSecondChange).toHaveBeenCalledTimes(0);
1537
- fireEvent.click(screen.getByText(secondButtonText));
1538
- expect(onFirstChange).toHaveBeenCalledTimes(1);
1539
- expect(onSecondChange).toHaveBeenCalledTimes(1);
1540
- expect(onSecondChange).toHaveBeenLastCalledWith(defaultFile, { ...defaultFile, ext: EXT_1, path: PATH_1 });
1984
+ };
1985
+ render(_jsx(B, {}));
1986
+ expect(addReducer).toHaveBeenCalledTimes(1);
1987
+ expect(addReducer).toHaveBeenCalledWith('', 'x');
1988
+ fireEvent.click(screen.getByText(setButtonText));
1989
+ expect(addReducer).toHaveBeenCalledTimes(2);
1990
+ expect(addReducer).toHaveBeenCalledWith('0', 'x');
1991
+ expect(addReducer).toHaveReturnedWith('0x');
1992
+ addedText = 'y';
1993
+ fireEvent.click(screen.getByText(updateButtonText));
1994
+ expect(addReducer).toHaveBeenCalledTimes(3);
1995
+ expect(addReducer).toHaveBeenCalledWith('0', 'y');
1996
+ expect(addReducer).toHaveReturnedWith('0y');
1997
+ fireEvent.click(screen.getByText(updateButtonText));
1998
+ expect(addReducer).toHaveBeenCalledTimes(3);
1999
+ });
2000
+ test('`options.onChange` event should be trigger in orders', () => {
2001
+ let changeTimes = 0;
2002
+ const updateChangeTimes = () => {
2003
+ return ++changeTimes;
2004
+ };
2005
+ const onChangeA = jest.fn(updateChangeTimes);
2006
+ const onChangeB = jest.fn(updateChangeTimes);
2007
+ const onChangeC = jest.fn(updateChangeTimes);
2008
+ const buttonText = 'my button';
2009
+ const A = _ref5 => {
2010
+ let children = _ref5.children;
2011
+ useUseCase(fileUseCase, {
2012
+ onChange: onChangeA
1541
2013
  });
1542
- test('`options.watch` should be trigger at child elements', () => {
1543
- const onExtChange = jest.fn();
1544
- const firstButtonText = 'first button';
1545
- const A = () => {
1546
- const [, { setPath }] = useUseCase(fileUseCase, {
1547
- watch: {
1548
- ext: onExtChange,
1549
- },
1550
- });
1551
- const onFirstClick = () => {
1552
- setPath(PATH_1);
1553
- };
1554
- return _jsx("button", { onClick: onFirstClick, children: firstButtonText });
1555
- };
1556
- const B = () => {
1557
- const [, , Provider] = useUseCase(defaultFile, fileUseCase, {});
1558
- return (_jsx(Provider, { children: _jsx(A, {}) }));
1559
- };
1560
- render(_jsx(B, {}));
1561
- expect(onExtChange).toHaveBeenCalledTimes(0);
1562
- fireEvent.click(screen.getByText(firstButtonText));
1563
- expect(onExtChange).toHaveBeenCalledTimes(1);
1564
- expect(onExtChange).toHaveBeenLastCalledWith({
1565
- fieldPaths: ['ext'],
1566
- newEntity: { ...defaultFile, ext: EXT_1, path: PATH_1 },
1567
- oldEntity: defaultFile,
1568
- newValue: EXT_1,
1569
- oldValue: '',
1570
- });
2014
+ return _jsx(Fragment, {
2015
+ children: children
1571
2016
  });
1572
- test('`options.watch` should be trigger in orders', () => {
1573
- let changeTimes = 0;
1574
- const updateChangeTimes = (e) => {
1575
- void e;
1576
- return ++changeTimes;
1577
- };
1578
- const onChangeA = jest.fn(updateChangeTimes);
1579
- const onChangeB = jest.fn(updateChangeTimes);
1580
- const onChangeC = jest.fn(updateChangeTimes);
1581
- const buttonText = 'my button';
1582
- const A = ({ children }) => {
1583
- useUseCase(fileUseCase, {
1584
- watch: {
1585
- ext: onChangeA,
1586
- },
1587
- });
1588
- return _jsx(Fragment, { children: children });
1589
- };
1590
- const B = () => {
1591
- useUseCase(fileUseCase, {
1592
- watch: {
1593
- ext: onChangeB,
1594
- },
1595
- });
1596
- return _jsx(Fragment, {});
1597
- };
1598
- const C = () => {
1599
- const [, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase, {
1600
- watch: {
1601
- ext: onChangeC,
1602
- },
1603
- });
1604
- const onFirstClick = () => {
1605
- setPath(PATH_1);
1606
- };
1607
- return (_jsxs(Provider, { children: [_jsx(A, { children: _jsx(B, {}) }), _jsx("button", { onClick: onFirstClick, children: buttonText })] }));
1608
- };
1609
- render(_jsx(C, {}));
1610
- expect(changeTimes).toBe(0);
1611
- fireEvent.click(screen.getByText(buttonText));
1612
- expect(onChangeA).toHaveReturnedWith(2);
1613
- expect(onChangeB).toHaveReturnedWith(3);
1614
- expect(onChangeC).toHaveReturnedWith(1);
2017
+ };
2018
+ const B = () => {
2019
+ useUseCase(fileUseCase, {
2020
+ onChange: onChangeB
1615
2021
  });
1616
- test('`options.watch` should trigger the latest one in child components', () => {
1617
- const onFirstExtChange = jest.fn();
1618
- const onSecondExtChange = jest.fn();
1619
- let onExtChange = onFirstExtChange;
1620
- const firstButtonText = 'first button';
1621
- const secondButtonText = 'second button';
1622
- const A = () => {
1623
- const [, { setPath }] = useUseCase(fileUseCase, {
1624
- watch: {
1625
- ext: onExtChange,
1626
- },
1627
- });
1628
- const onFirstClick = () => {
1629
- setPath(PATH_1);
1630
- onExtChange = onSecondExtChange;
1631
- };
1632
- const onSecondClick = () => {
1633
- setPath('');
1634
- };
1635
- return (_jsxs(Fragment, { children: [_jsx("button", { onClick: onFirstClick, children: firstButtonText }), _jsx("button", { onClick: onSecondClick, children: secondButtonText })] }));
1636
- };
1637
- const B = () => {
1638
- const [, , Provider] = useUseCase(defaultFile, fileUseCase);
1639
- return (_jsx(Provider, { children: _jsx(A, {}) }));
1640
- };
1641
- render(_jsx(B, {}));
1642
- expect(onFirstExtChange).toHaveBeenCalledTimes(0);
1643
- fireEvent.click(screen.getByText(firstButtonText));
1644
- expect(onFirstExtChange).toHaveBeenCalledTimes(1);
1645
- expect(onSecondExtChange).toHaveBeenCalledTimes(0);
1646
- fireEvent.click(screen.getByText(secondButtonText));
1647
- expect(onFirstExtChange).toHaveBeenCalledTimes(1);
1648
- expect(onSecondExtChange).toHaveBeenCalledTimes(1);
1649
- expect(onSecondExtChange).toHaveBeenLastCalledWith({
1650
- fieldPaths: ['ext'],
1651
- newEntity: defaultFile,
1652
- oldEntity: { ...defaultFile, ext: EXT_1, path: PATH_1 },
1653
- newValue: '',
1654
- oldValue: EXT_1,
1655
- });
2022
+ return _jsx(Fragment, {});
2023
+ };
2024
+ const C = () => {
2025
+ const _useUseCase44 = useUseCase(defaultFile, fileUseCase, {
2026
+ onChange: onChangeC
2027
+ }),
2028
+ _useUseCase45 = _slicedToArray(_useUseCase44, 3),
2029
+ setPath = _useUseCase45[1].setPath,
2030
+ Provider = _useUseCase45[2];
2031
+ const onFirstClick = () => {
2032
+ setPath(PATH_1);
2033
+ };
2034
+ return _jsxs(Provider, {
2035
+ children: [_jsx(A, {
2036
+ children: _jsx(B, {})
2037
+ }), _jsx("button", {
2038
+ onClick: onFirstClick,
2039
+ children: buttonText
2040
+ })]
1656
2041
  });
2042
+ };
2043
+ render(_jsx(C, {}));
2044
+ expect(changeTimes).toBe(0);
2045
+ fireEvent.click(screen.getByText(buttonText));
2046
+ expect(onChangeA).toHaveReturnedWith(2);
2047
+ expect(onChangeB).toHaveReturnedWith(3);
2048
+ expect(onChangeC).toHaveReturnedWith(1);
1657
2049
  });
1658
- describe('`useUseCase` should work the same as `useReducers`', () => {
1659
- test('`entity` should equal `defaultFile`', () => {
1660
- const { result } = renderHook(() => {
1661
- return useUseCase(mathUseCase);
1662
- });
1663
- const { current: reducers } = result;
1664
- expect(Array.isArray(reducers)).toBe(false);
2050
+ test('`options.onChange` should always trigger the latest one in child components', () => {
2051
+ const onFirstChange = jest.fn();
2052
+ const onSecondChange = jest.fn();
2053
+ let onChange = onFirstChange;
2054
+ const firstButtonText = 'first button';
2055
+ const secondButtonText = 'second button';
2056
+ const A = () => {
2057
+ const _useUseCase46 = useUseCase(fileUseCase, {
2058
+ onChange
2059
+ }),
2060
+ _useUseCase47 = _slicedToArray(_useUseCase46, 2),
2061
+ setPath = _useUseCase47[1].setPath;
2062
+ const onFirstClick = () => {
2063
+ setPath(PATH_1);
2064
+ onChange = onSecondChange;
2065
+ };
2066
+ const onSecondClick = () => {
2067
+ setPath('');
2068
+ };
2069
+ return _jsxs(Fragment, {
2070
+ children: [_jsx("button", {
2071
+ onClick: onFirstClick,
2072
+ children: firstButtonText
2073
+ }), _jsx("button", {
2074
+ onClick: onSecondClick,
2075
+ children: secondButtonText
2076
+ })]
1665
2077
  });
1666
- test('returned reducer should work', () => {
1667
- const { result } = renderHook(() => {
1668
- return useUseCase(mathUseCase);
1669
- });
1670
- const { current: reducers } = result;
1671
- const { add } = reducers;
1672
- expect(add(1, 2)).toBe(3);
2078
+ };
2079
+ const B = () => {
2080
+ const _useUseCase48 = useUseCase(defaultFile, fileUseCase),
2081
+ _useUseCase49 = _slicedToArray(_useUseCase48, 3),
2082
+ Provider = _useUseCase49[2];
2083
+ return _jsx(Provider, {
2084
+ children: _jsx(A, {})
1673
2085
  });
1674
- test('`usecase` should be called only once if deps has not provided', () => {
1675
- const mockUseCase = jest.fn(mathUseCase);
1676
- const { rerender } = renderHook(() => {
1677
- return useUseCase(mockUseCase);
1678
- });
1679
- expect(mockUseCase).toHaveBeenCalledTimes(1);
1680
- rerender();
1681
- expect(mockUseCase).toHaveBeenCalledTimes(1);
2086
+ };
2087
+ render(_jsx(B, {}));
2088
+ expect(onFirstChange).toHaveBeenCalledTimes(0);
2089
+ fireEvent.click(screen.getByText(firstButtonText));
2090
+ expect(onFirstChange).toHaveBeenCalledTimes(1);
2091
+ expect(onSecondChange).toHaveBeenCalledTimes(0);
2092
+ fireEvent.click(screen.getByText(secondButtonText));
2093
+ expect(onFirstChange).toHaveBeenCalledTimes(1);
2094
+ expect(onSecondChange).toHaveBeenCalledTimes(1);
2095
+ expect(onSecondChange).toHaveBeenLastCalledWith(defaultFile, {
2096
+ ...defaultFile,
2097
+ ext: EXT_1,
2098
+ path: PATH_1
2099
+ });
2100
+ });
2101
+ test('`options.watch` should be trigger at child elements', () => {
2102
+ const onExtChange = jest.fn();
2103
+ const firstButtonText = 'first button';
2104
+ const A = () => {
2105
+ const _useUseCase50 = useUseCase(fileUseCase, {
2106
+ watch: {
2107
+ ext: onExtChange
2108
+ }
2109
+ }),
2110
+ _useUseCase51 = _slicedToArray(_useUseCase50, 2),
2111
+ setPath = _useUseCase51[1].setPath;
2112
+ const onFirstClick = () => {
2113
+ setPath(PATH_1);
2114
+ };
2115
+ return _jsx("button", {
2116
+ onClick: onFirstClick,
2117
+ children: firstButtonText
1682
2118
  });
1683
- test('`usecase` should be called only once if deps has not changed', () => {
1684
- const mockUseCase = jest.fn(mathUseCase);
1685
- const { rerender } = renderHook(() => {
1686
- return useUseCase(mockUseCase, {}, [1, 'x']);
1687
- });
1688
- expect(mockUseCase).toHaveBeenCalledTimes(1);
1689
- rerender();
1690
- expect(mockUseCase).toHaveBeenCalledTimes(1);
2119
+ };
2120
+ const B = () => {
2121
+ const _useUseCase52 = useUseCase(defaultFile, fileUseCase, {}),
2122
+ _useUseCase53 = _slicedToArray(_useUseCase52, 3),
2123
+ Provider = _useUseCase53[2];
2124
+ return _jsx(Provider, {
2125
+ children: _jsx(A, {})
1691
2126
  });
1692
- test('`usecase` should be called if deps has changed', () => {
1693
- let i = 0;
1694
- const mockUseCase = jest.fn(mathUseCase);
1695
- const { rerender } = renderHook(() => {
1696
- return useUseCase(mockUseCase, {}, [i++, 'x']);
1697
- });
1698
- expect(mockUseCase).toHaveBeenCalledTimes(1);
1699
- rerender();
1700
- expect(mockUseCase).toHaveBeenCalledTimes(2);
2127
+ };
2128
+ render(_jsx(B, {}));
2129
+ expect(onExtChange).toHaveBeenCalledTimes(0);
2130
+ fireEvent.click(screen.getByText(firstButtonText));
2131
+ expect(onExtChange).toHaveBeenCalledTimes(1);
2132
+ expect(onExtChange).toHaveBeenLastCalledWith({
2133
+ fieldPaths: ['ext'],
2134
+ newEntity: {
2135
+ ...defaultFile,
2136
+ ext: EXT_1,
2137
+ path: PATH_1
2138
+ },
2139
+ oldEntity: defaultFile,
2140
+ newValue: EXT_1,
2141
+ oldValue: ''
2142
+ });
2143
+ });
2144
+ test('`options.watch` should be trigger in orders', () => {
2145
+ let changeTimes = 0;
2146
+ const updateChangeTimes = e => {
2147
+ void e;
2148
+ return ++changeTimes;
2149
+ };
2150
+ const onChangeA = jest.fn(updateChangeTimes);
2151
+ const onChangeB = jest.fn(updateChangeTimes);
2152
+ const onChangeC = jest.fn(updateChangeTimes);
2153
+ const buttonText = 'my button';
2154
+ const A = _ref6 => {
2155
+ let children = _ref6.children;
2156
+ useUseCase(fileUseCase, {
2157
+ watch: {
2158
+ ext: onChangeA
2159
+ }
1701
2160
  });
1702
- test('reducer call should not be cached if component is at rendering phase', () => {
1703
- const buttonText = 'button';
1704
- const CacheTestComponent = () => {
1705
- const { subtraction } = useUseCase(mathUseCase);
1706
- const update = useUpdate();
1707
- const onClick = () => {
1708
- update();
1709
- };
1710
- subtraction(5, 3);
1711
- return _jsx("button", { onClick: onClick, children: buttonText });
1712
- };
1713
- render(_jsx(CacheTestComponent, {}));
1714
- expect(subtractionReducer).toHaveBeenCalledTimes(1);
1715
- expect(subtractionReducer).toHaveBeenCalledWith(5, 3);
1716
- expect(subtractionReducer).toHaveReturnedWith(2);
1717
- fireEvent.click(screen.getByText(buttonText));
1718
- expect(subtractionReducer).toHaveBeenCalledTimes(2);
1719
- fireEvent.click(screen.getByText(buttonText));
1720
- expect(subtractionReducer).toHaveBeenCalledTimes(3);
2161
+ return _jsx(Fragment, {
2162
+ children: children
1721
2163
  });
1722
- test('reducer call should not be cached if component is not at rendering phase', () => {
1723
- const buttonText = 'button';
1724
- const CacheTestComponent = () => {
1725
- const { subtraction } = useUseCase(mathUseCase);
1726
- const onClick = () => {
1727
- subtraction(5, 3);
1728
- };
1729
- useMount(() => {
1730
- subtraction(5, 3);
1731
- subtraction(5, 3);
1732
- });
1733
- return _jsx("button", { onClick: onClick, children: buttonText });
1734
- };
1735
- render(_jsx(CacheTestComponent, {}));
1736
- expect(subtractionReducer).toHaveBeenCalledTimes(2);
1737
- expect(subtractionReducer).toHaveBeenNthCalledWith(1, 5, 3);
1738
- expect(subtractionReducer).toHaveNthReturnedWith(1, 2);
1739
- expect(subtractionReducer).toHaveBeenNthCalledWith(2, 5, 3);
1740
- expect(subtractionReducer).toHaveNthReturnedWith(2, 2);
1741
- fireEvent.click(screen.getByText(buttonText));
1742
- expect(subtractionReducer).toHaveBeenCalledTimes(3);
1743
- expect(subtractionReducer).toHaveBeenNthCalledWith(3, 5, 3);
1744
- expect(subtractionReducer).toHaveNthReturnedWith(3, 2);
2164
+ };
2165
+ const B = () => {
2166
+ useUseCase(fileUseCase, {
2167
+ watch: {
2168
+ ext: onChangeB
2169
+ }
1745
2170
  });
1746
- test('reducer call should not be cached if parameters have changed', () => {
1747
- let count = 0;
1748
- const buttonText = 'button';
1749
- const StringUseCaseTestComponent = () => {
1750
- const { subtraction } = useUseCase(mathUseCase);
1751
- const update = useUpdate();
1752
- subtraction(5, count++);
1753
- const onUpdate = () => {
1754
- update();
1755
- };
1756
- return (_jsx("div", { children: _jsx("button", { onClick: onUpdate, children: buttonText }) }));
1757
- };
1758
- render(_jsx(StringUseCaseTestComponent, {}));
1759
- expect(subtractionReducer).toHaveBeenCalledTimes(1);
1760
- expect(subtractionReducer).toHaveBeenCalledWith(5, 0);
1761
- fireEvent.click(screen.getByText(buttonText));
1762
- expect(subtractionReducer).toHaveBeenCalledTimes(2);
1763
- expect(subtractionReducer).toHaveBeenCalledWith(5, 1);
1764
- expect(subtractionReducer).toHaveReturnedWith(4);
2171
+ return _jsx(Fragment, {});
2172
+ };
2173
+ const C = () => {
2174
+ const _useUseCase54 = useUseCase(defaultFile, fileUseCase, {
2175
+ watch: {
2176
+ ext: onChangeC
2177
+ }
2178
+ }),
2179
+ _useUseCase55 = _slicedToArray(_useUseCase54, 3),
2180
+ setPath = _useUseCase55[1].setPath,
2181
+ Provider = _useUseCase55[2];
2182
+ const onFirstClick = () => {
2183
+ setPath(PATH_1);
2184
+ };
2185
+ return _jsxs(Provider, {
2186
+ children: [_jsx(A, {
2187
+ children: _jsx(B, {})
2188
+ }), _jsx("button", {
2189
+ onClick: onFirstClick,
2190
+ children: buttonText
2191
+ })]
1765
2192
  });
1766
- test('`options.extraValue` should be added after call `add` method', () => {
1767
- const { result } = renderHook(() => {
1768
- return useUseCase(mathUseCase, { extraValue: 5 });
1769
- });
1770
- const { current: reducers } = result;
1771
- const { add } = reducers;
1772
- expect(add(1, 2)).toBe(8);
2193
+ };
2194
+ render(_jsx(C, {}));
2195
+ expect(changeTimes).toBe(0);
2196
+ fireEvent.click(screen.getByText(buttonText));
2197
+ expect(onChangeA).toHaveReturnedWith(2);
2198
+ expect(onChangeB).toHaveReturnedWith(3);
2199
+ expect(onChangeC).toHaveReturnedWith(1);
2200
+ });
2201
+ test('`options.watch` should trigger the latest one in child components', () => {
2202
+ const onFirstExtChange = jest.fn();
2203
+ const onSecondExtChange = jest.fn();
2204
+ let onExtChange = onFirstExtChange;
2205
+ const firstButtonText = 'first button';
2206
+ const secondButtonText = 'second button';
2207
+ const A = () => {
2208
+ const _useUseCase56 = useUseCase(fileUseCase, {
2209
+ watch: {
2210
+ ext: onExtChange
2211
+ }
2212
+ }),
2213
+ _useUseCase57 = _slicedToArray(_useUseCase56, 2),
2214
+ setPath = _useUseCase57[1].setPath;
2215
+ const onFirstClick = () => {
2216
+ setPath(PATH_1);
2217
+ onExtChange = onSecondExtChange;
2218
+ };
2219
+ const onSecondClick = () => {
2220
+ setPath('');
2221
+ };
2222
+ return _jsxs(Fragment, {
2223
+ children: [_jsx("button", {
2224
+ onClick: onFirstClick,
2225
+ children: firstButtonText
2226
+ }), _jsx("button", {
2227
+ onClick: onSecondClick,
2228
+ children: secondButtonText
2229
+ })]
1773
2230
  });
1774
- test('when `options` has changed, it should not trigger update', () => {
1775
- const onUpdate = jest.fn();
1776
- const onDeepUpdate = jest.fn();
1777
- const { result } = renderHook(() => {
1778
- const [extraValue, setExtraValue] = useState(0);
1779
- const reducers = useUseCase(mathUseCase, { extraValue });
1780
- useUpdateEffect(() => {
1781
- onUpdate();
1782
- }, [reducers]);
1783
- useDeepCompareUpdate(() => {
1784
- onDeepUpdate();
1785
- }, [reducers]);
1786
- return setExtraValue;
1787
- });
1788
- expect(onUpdate).toHaveBeenCalledTimes(0);
1789
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
1790
- act(() => {
1791
- result.current(3);
1792
- });
1793
- expect(onUpdate).toHaveBeenCalledTimes(0);
1794
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
2231
+ };
2232
+ const B = () => {
2233
+ const _useUseCase58 = useUseCase(defaultFile, fileUseCase),
2234
+ _useUseCase59 = _slicedToArray(_useUseCase58, 3),
2235
+ Provider = _useUseCase59[2];
2236
+ return _jsx(Provider, {
2237
+ children: _jsx(A, {})
1795
2238
  });
1796
- test('when `deps` change, it should update reducers', () => {
1797
- const onUpdate = jest.fn();
1798
- const onDeepUpdate = jest.fn();
1799
- const { result } = renderHook(() => {
1800
- const [extraValue, setExtraValue] = useState(0);
1801
- const reducers = useUseCase(mathUseCase, { extraValue }, [extraValue]);
1802
- useUpdateEffect(() => {
1803
- onUpdate();
1804
- }, [reducers]);
1805
- useDeepCompareUpdate(() => {
1806
- onDeepUpdate();
1807
- }, [reducers]);
1808
- return setExtraValue;
1809
- });
1810
- expect(onUpdate).toHaveBeenCalledTimes(0);
1811
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
1812
- act(() => {
1813
- result.current(3);
1814
- });
1815
- expect(onUpdate).toHaveBeenCalledTimes(1);
1816
- expect(onDeepUpdate).toHaveBeenCalledTimes(1);
2239
+ };
2240
+ render(_jsx(B, {}));
2241
+ expect(onFirstExtChange).toHaveBeenCalledTimes(0);
2242
+ fireEvent.click(screen.getByText(firstButtonText));
2243
+ expect(onFirstExtChange).toHaveBeenCalledTimes(1);
2244
+ expect(onSecondExtChange).toHaveBeenCalledTimes(0);
2245
+ fireEvent.click(screen.getByText(secondButtonText));
2246
+ expect(onFirstExtChange).toHaveBeenCalledTimes(1);
2247
+ expect(onSecondExtChange).toHaveBeenCalledTimes(1);
2248
+ expect(onSecondExtChange).toHaveBeenLastCalledWith({
2249
+ fieldPaths: ['ext'],
2250
+ newEntity: defaultFile,
2251
+ oldEntity: {
2252
+ ...defaultFile,
2253
+ ext: EXT_1,
2254
+ path: PATH_1
2255
+ },
2256
+ newValue: '',
2257
+ oldValue: EXT_1
2258
+ });
2259
+ });
2260
+ });
2261
+ describe('`useUseCase` should work the same as `useReducers`', () => {
2262
+ test('`entity` should equal `defaultFile`', () => {
2263
+ const _renderHook32 = renderHook(() => {
2264
+ return useUseCase(mathUseCase);
2265
+ }),
2266
+ result = _renderHook32.result;
2267
+ const reducers = result.current;
2268
+ expect(Array.isArray(reducers)).toBe(false);
2269
+ });
2270
+ test('returned reducer should work', () => {
2271
+ const _renderHook33 = renderHook(() => {
2272
+ return useUseCase(mathUseCase);
2273
+ }),
2274
+ result = _renderHook33.result;
2275
+ const reducers = result.current;
2276
+ const add = reducers.add;
2277
+ expect(add(1, 2)).toBe(3);
2278
+ });
2279
+ test('`usecase` should be called only once if deps has not provided', () => {
2280
+ const mockUseCase = jest.fn(mathUseCase);
2281
+ const _renderHook34 = renderHook(() => {
2282
+ return useUseCase(mockUseCase);
2283
+ }),
2284
+ rerender = _renderHook34.rerender;
2285
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
2286
+ rerender();
2287
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
2288
+ });
2289
+ test('`usecase` should be called only once if deps has not changed', () => {
2290
+ const mockUseCase = jest.fn(mathUseCase);
2291
+ const _renderHook35 = renderHook(() => {
2292
+ return useUseCase(mockUseCase, {}, [1, 'x']);
2293
+ }),
2294
+ rerender = _renderHook35.rerender;
2295
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
2296
+ rerender();
2297
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
2298
+ });
2299
+ test('`usecase` should be called if deps has changed', () => {
2300
+ let i = 0;
2301
+ const mockUseCase = jest.fn(mathUseCase);
2302
+ const _renderHook36 = renderHook(() => {
2303
+ return useUseCase(mockUseCase, {}, [i++, 'x']);
2304
+ }),
2305
+ rerender = _renderHook36.rerender;
2306
+ expect(mockUseCase).toHaveBeenCalledTimes(1);
2307
+ rerender();
2308
+ expect(mockUseCase).toHaveBeenCalledTimes(2);
2309
+ });
2310
+ test('reducer call should not be cached if component is at rendering phase', () => {
2311
+ const buttonText = 'button';
2312
+ const CacheTestComponent = () => {
2313
+ const _useUseCase60 = useUseCase(mathUseCase),
2314
+ subtraction = _useUseCase60.subtraction;
2315
+ const update = useUpdate();
2316
+ const onClick = () => {
2317
+ update();
2318
+ };
2319
+ subtraction(5, 3);
2320
+ return _jsx("button", {
2321
+ onClick: onClick,
2322
+ children: buttonText
1817
2323
  });
1818
- test('empty `deps` should not update reducers', () => {
1819
- const onUpdate = jest.fn();
1820
- const onDeepUpdate = jest.fn();
1821
- const { result } = renderHook(() => {
1822
- const [extraValue, setExtraValue] = useState(0);
1823
- const reducers = useUseCase(mathUseCase, { extraValue }, []);
1824
- useUpdateEffect(() => {
1825
- onUpdate();
1826
- }, [reducers]);
1827
- useDeepCompareUpdate(() => {
1828
- onDeepUpdate();
1829
- }, [reducers]);
1830
- return setExtraValue;
1831
- });
1832
- expect(onUpdate).toHaveBeenCalledTimes(0);
1833
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
1834
- act(() => {
1835
- result.current(3);
1836
- });
1837
- expect(onUpdate).toHaveBeenCalledTimes(0);
1838
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
2324
+ };
2325
+ render(_jsx(CacheTestComponent, {}));
2326
+ expect(subtractionReducer).toHaveBeenCalledTimes(1);
2327
+ expect(subtractionReducer).toHaveBeenCalledWith(5, 3);
2328
+ expect(subtractionReducer).toHaveReturnedWith(2);
2329
+ fireEvent.click(screen.getByText(buttonText));
2330
+ expect(subtractionReducer).toHaveBeenCalledTimes(2);
2331
+ fireEvent.click(screen.getByText(buttonText));
2332
+ expect(subtractionReducer).toHaveBeenCalledTimes(3);
2333
+ });
2334
+ test('reducer call should not be cached if component is not at rendering phase', () => {
2335
+ const buttonText = 'button';
2336
+ const CacheTestComponent = () => {
2337
+ const _useUseCase61 = useUseCase(mathUseCase),
2338
+ subtraction = _useUseCase61.subtraction;
2339
+ const onClick = () => {
2340
+ subtraction(5, 3);
2341
+ };
2342
+ useMount(() => {
2343
+ subtraction(5, 3);
2344
+ subtraction(5, 3);
1839
2345
  });
1840
- test('should not trigger update', () => {
1841
- const onUpdate = jest.fn();
1842
- render(_jsx(MathParent, { onUpdate: onUpdate }));
1843
- fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
1844
- expect(onUpdate).toHaveBeenCalledTimes(0);
2346
+ return _jsx("button", {
2347
+ onClick: onClick,
2348
+ children: buttonText
1845
2349
  });
2350
+ };
2351
+ render(_jsx(CacheTestComponent, {}));
2352
+ expect(subtractionReducer).toHaveBeenCalledTimes(2);
2353
+ expect(subtractionReducer).toHaveBeenNthCalledWith(1, 5, 3);
2354
+ expect(subtractionReducer).toHaveNthReturnedWith(1, 2);
2355
+ expect(subtractionReducer).toHaveBeenNthCalledWith(2, 5, 3);
2356
+ expect(subtractionReducer).toHaveNthReturnedWith(2, 2);
2357
+ fireEvent.click(screen.getByText(buttonText));
2358
+ expect(subtractionReducer).toHaveBeenCalledTimes(3);
2359
+ expect(subtractionReducer).toHaveBeenNthCalledWith(3, 5, 3);
2360
+ expect(subtractionReducer).toHaveNthReturnedWith(3, 2);
1846
2361
  });
1847
- });
2362
+ test('reducer call should not be cached if parameters have changed', () => {
2363
+ let count = 0;
2364
+ const buttonText = 'button';
2365
+ const StringUseCaseTestComponent = () => {
2366
+ const _useUseCase62 = useUseCase(mathUseCase),
2367
+ subtraction = _useUseCase62.subtraction;
2368
+ const update = useUpdate();
2369
+ subtraction(5, count++);
2370
+ const onUpdate = () => {
2371
+ update();
2372
+ };
2373
+ return _jsx("div", {
2374
+ children: _jsx("button", {
2375
+ onClick: onUpdate,
2376
+ children: buttonText
2377
+ })
2378
+ });
2379
+ };
2380
+ render(_jsx(StringUseCaseTestComponent, {}));
2381
+ expect(subtractionReducer).toHaveBeenCalledTimes(1);
2382
+ expect(subtractionReducer).toHaveBeenCalledWith(5, 0);
2383
+ fireEvent.click(screen.getByText(buttonText));
2384
+ expect(subtractionReducer).toHaveBeenCalledTimes(2);
2385
+ expect(subtractionReducer).toHaveBeenCalledWith(5, 1);
2386
+ expect(subtractionReducer).toHaveReturnedWith(4);
2387
+ });
2388
+ test('`options.extraValue` should be added after call `add` method', () => {
2389
+ const _renderHook37 = renderHook(() => {
2390
+ return useUseCase(mathUseCase, {
2391
+ extraValue: 5
2392
+ });
2393
+ }),
2394
+ result = _renderHook37.result;
2395
+ const reducers = result.current;
2396
+ const add = reducers.add;
2397
+ expect(add(1, 2)).toBe(8);
2398
+ });
2399
+ test('when `options` has changed, it should not trigger update', () => {
2400
+ const onUpdate = jest.fn();
2401
+ const onDeepUpdate = jest.fn();
2402
+ const _renderHook38 = renderHook(() => {
2403
+ const _useState7 = useState(0),
2404
+ _useState8 = _slicedToArray(_useState7, 2),
2405
+ extraValue = _useState8[0],
2406
+ setExtraValue = _useState8[1];
2407
+ const reducers = useUseCase(mathUseCase, {
2408
+ extraValue
2409
+ });
2410
+ useUpdateEffect(() => {
2411
+ onUpdate();
2412
+ }, [reducers]);
2413
+ useDeepCompareUpdate(() => {
2414
+ onDeepUpdate();
2415
+ }, [reducers]);
2416
+ return setExtraValue;
2417
+ }),
2418
+ result = _renderHook38.result;
2419
+ expect(onUpdate).toHaveBeenCalledTimes(0);
2420
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
2421
+ act(() => {
2422
+ result.current(3);
2423
+ });
2424
+ expect(onUpdate).toHaveBeenCalledTimes(0);
2425
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
2426
+ });
2427
+ test('when `deps` change, it should update reducers', () => {
2428
+ const onUpdate = jest.fn();
2429
+ const onDeepUpdate = jest.fn();
2430
+ const _renderHook39 = renderHook(() => {
2431
+ const _useState9 = useState(0),
2432
+ _useState0 = _slicedToArray(_useState9, 2),
2433
+ extraValue = _useState0[0],
2434
+ setExtraValue = _useState0[1];
2435
+ const reducers = useUseCase(mathUseCase, {
2436
+ extraValue
2437
+ }, [extraValue]);
2438
+ useUpdateEffect(() => {
2439
+ onUpdate();
2440
+ }, [reducers]);
2441
+ useDeepCompareUpdate(() => {
2442
+ onDeepUpdate();
2443
+ }, [reducers]);
2444
+ return setExtraValue;
2445
+ }),
2446
+ result = _renderHook39.result;
2447
+ expect(onUpdate).toHaveBeenCalledTimes(0);
2448
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
2449
+ act(() => {
2450
+ result.current(3);
2451
+ });
2452
+ expect(onUpdate).toHaveBeenCalledTimes(1);
2453
+ expect(onDeepUpdate).toHaveBeenCalledTimes(1);
2454
+ });
2455
+ test('empty `deps` should not update reducers', () => {
2456
+ const onUpdate = jest.fn();
2457
+ const onDeepUpdate = jest.fn();
2458
+ const _renderHook40 = renderHook(() => {
2459
+ const _useState1 = useState(0),
2460
+ _useState10 = _slicedToArray(_useState1, 2),
2461
+ extraValue = _useState10[0],
2462
+ setExtraValue = _useState10[1];
2463
+ const reducers = useUseCase(mathUseCase, {
2464
+ extraValue
2465
+ }, []);
2466
+ useUpdateEffect(() => {
2467
+ onUpdate();
2468
+ }, [reducers]);
2469
+ useDeepCompareUpdate(() => {
2470
+ onDeepUpdate();
2471
+ }, [reducers]);
2472
+ return setExtraValue;
2473
+ }),
2474
+ result = _renderHook40.result;
2475
+ expect(onUpdate).toHaveBeenCalledTimes(0);
2476
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
2477
+ act(() => {
2478
+ result.current(3);
2479
+ });
2480
+ expect(onUpdate).toHaveBeenCalledTimes(0);
2481
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
2482
+ });
2483
+ test('should not trigger update', () => {
2484
+ const onUpdate = jest.fn();
2485
+ render(_jsx(MathParent, {
2486
+ onUpdate: onUpdate
2487
+ }));
2488
+ fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
2489
+ expect(onUpdate).toHaveBeenCalledTimes(0);
2490
+ });
2491
+ });
2492
+ });