muya 1.0.1 → 1.0.3
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.
- package/README.md +99 -14
- package/cjs/index.js +1 -1
- package/esm/__tests__/common.test.js +1 -0
- package/esm/__tests__/is.test.js +1 -0
- package/esm/__tests__/merge.test.js +1 -0
- package/esm/__tests__/shallow.test.js +1 -0
- package/esm/__tests__/test-utils.js +1 -0
- package/esm/__tests__/types.test.js +1 -0
- package/esm/common.js +1 -1
- package/esm/create-base-state.js +1 -1
- package/esm/create-getter-state.js +1 -1
- package/esm/create.js +1 -1
- package/esm/is.js +1 -1
- package/esm/merge.js +1 -1
- package/esm/shallow.js +1 -1
- package/esm/types.js +1 -1
- package/esm/use-state-value.js +1 -1
- package/package.json +4 -1
- package/src/__tests__/common.test.ts +63 -0
- package/src/__tests__/create.test.tsx +84 -0
- package/src/__tests__/is.test.ts +103 -0
- package/src/__tests__/merge.test.ts +78 -0
- package/src/__tests__/shallow.test.ts +418 -0
- package/src/{state.test.tsx → __tests__/state.test.tsx} +2 -30
- package/src/__tests__/test-utils.ts +40 -0
- package/src/__tests__/types.test.ts +17 -0
- package/src/common.ts +32 -0
- package/src/create-base-state.ts +1 -5
- package/src/create-getter-state.ts +0 -1
- package/src/create.ts +33 -8
- package/src/is.ts +9 -0
- package/src/merge.ts +11 -14
- package/src/shallow.ts +0 -3
- package/src/types.ts +1 -1
- package/src/use-state-value.ts +4 -1
- package/types/__tests__/test-utils.d.ts +20 -0
- package/types/common.d.ts +10 -0
- package/types/is.d.ts +2 -0
- package/types/merge.d.ts +3 -1
- package/types/types.d.ts +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { create } from '../create'
|
|
2
|
+
import { renderHook, act } from '@testing-library/react'
|
|
3
|
+
import { merge } from '../merge'
|
|
4
|
+
|
|
5
|
+
describe('merge', () => {
|
|
6
|
+
it('should test merge multiple-state', () => {
|
|
7
|
+
const state1 = create(1)
|
|
8
|
+
const state2 = create(1)
|
|
9
|
+
const state3 = create(3)
|
|
10
|
+
|
|
11
|
+
const useMerged = merge([state1, state2, state3], (value1, value2, value3) => {
|
|
12
|
+
expect(value1).toBe(1)
|
|
13
|
+
expect(value2).toBe(1)
|
|
14
|
+
expect(value3).toBe(3)
|
|
15
|
+
return `${value1} ${value2} ${value3}`
|
|
16
|
+
})
|
|
17
|
+
const result = renderHook(() => useMerged())
|
|
18
|
+
expect(result.result.current).toBe('1 1 3')
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should test merge multiple-state with isEqual', () => {
|
|
22
|
+
const state1 = create(1)
|
|
23
|
+
const state2 = create(1)
|
|
24
|
+
const state3 = create(3)
|
|
25
|
+
|
|
26
|
+
const useMerged = merge(
|
|
27
|
+
[state1, state2, state3],
|
|
28
|
+
(value1, value2, value3) => {
|
|
29
|
+
expect(value1).toBe(1)
|
|
30
|
+
expect(value2).toBe(1)
|
|
31
|
+
expect(value3).toBe(3)
|
|
32
|
+
return `${value1} ${value2} ${value3}`
|
|
33
|
+
},
|
|
34
|
+
(a, b) => a === b,
|
|
35
|
+
)
|
|
36
|
+
const result = renderHook(() => useMerged())
|
|
37
|
+
expect(result.result.current).toBe('1 1 3')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('should test merge multiple-state with different type', () => {
|
|
41
|
+
const state1 = create(1)
|
|
42
|
+
const state2 = create('1')
|
|
43
|
+
const state3 = create({ value: 3 })
|
|
44
|
+
const state4 = create([1, 2, 3])
|
|
45
|
+
|
|
46
|
+
const useMerged = merge([state1, state2, state3, state4], (value1, value2, value3, value4) => {
|
|
47
|
+
expect(value1).toBe(1)
|
|
48
|
+
expect(value2).toBe('1')
|
|
49
|
+
expect(value3).toStrictEqual({ value: 3 })
|
|
50
|
+
expect(value4).toStrictEqual([1, 2, 3])
|
|
51
|
+
return `${value1} ${value2} ${value3.value} ${value4.join(' ')}`
|
|
52
|
+
})
|
|
53
|
+
const result = renderHook(() => useMerged())
|
|
54
|
+
expect(result.result.current).toBe('1 1 3 1 2 3')
|
|
55
|
+
})
|
|
56
|
+
it('should test merge with reset', () => {
|
|
57
|
+
const state1 = create(1)
|
|
58
|
+
const state2 = create(1)
|
|
59
|
+
const state3 = create(3)
|
|
60
|
+
|
|
61
|
+
const useMerged = merge([state1, state2, state3], (value1, value2, value3) => {
|
|
62
|
+
return `${value1} ${value2} ${value3}`
|
|
63
|
+
})
|
|
64
|
+
const result = renderHook(() => useMerged())
|
|
65
|
+
|
|
66
|
+
act(() => {
|
|
67
|
+
state1.setState(2)
|
|
68
|
+
state2.setState(2)
|
|
69
|
+
state3.setState(4)
|
|
70
|
+
})
|
|
71
|
+
expect(result.result.current).toBe('2 2 4')
|
|
72
|
+
|
|
73
|
+
act(() => {
|
|
74
|
+
useMerged.reset()
|
|
75
|
+
})
|
|
76
|
+
expect(result.result.current).toBe('1 1 3')
|
|
77
|
+
})
|
|
78
|
+
})
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import { shallow } from '../shallow'
|
|
2
|
+
|
|
3
|
+
describe('shallow', () => {
|
|
4
|
+
it('should return true for identical primitive values', () => {
|
|
5
|
+
expect(shallow(1, 1)).toBe(true)
|
|
6
|
+
expect(shallow('a', 'a')).toBe(true)
|
|
7
|
+
expect(shallow(true, true)).toBe(true)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('should return false for different primitive values', () => {
|
|
11
|
+
expect(shallow(1, 2)).toBe(false)
|
|
12
|
+
expect(shallow('a', 'b')).toBe(false)
|
|
13
|
+
expect(shallow(true, false)).toBe(false)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('should return true for identical objects', () => {
|
|
17
|
+
const object = { a: 1 }
|
|
18
|
+
expect(shallow(object, object)).toBe(true)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should return false for different objects with diff properties', () => {
|
|
22
|
+
expect(shallow({ a: 1 }, { a: 2 })).toBe(false)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('should return true for identical arrays', () => {
|
|
26
|
+
const array = [1, 2, 3]
|
|
27
|
+
expect(shallow(array, array)).toBe(true)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('should return true for different arrays with same elements', () => {
|
|
31
|
+
expect(shallow([1, 2, 3], [1, 2, 3])).toBe(true)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('should return true for identical Maps', () => {
|
|
35
|
+
const map = new Map([['a', 1]])
|
|
36
|
+
expect(shallow(map, map)).toBe(true)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('should return true for different Maps with same entries', () => {
|
|
40
|
+
expect(shallow(new Map([['a', 1]]), new Map([['a', 1]]))).toBe(true)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('should return true for identical Sets', () => {
|
|
44
|
+
const set = new Set([1, 2, 3])
|
|
45
|
+
expect(shallow(set, set)).toBe(true)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('should return true for different Sets with same elements', () => {
|
|
49
|
+
expect(shallow(new Set([1, 2, 3]), new Set([1, 2, 3]))).toBe(true)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('should return true for objects with same reference', () => {
|
|
53
|
+
const object = { a: 1 }
|
|
54
|
+
expect(shallow(object, object)).toBe(true)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('should return true for objects with different references', () => {
|
|
58
|
+
expect(shallow({ a: 1 }, { a: 1 })).toBe(true)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('should return true for arrays with same reference', () => {
|
|
62
|
+
const array = [1, 2, 3]
|
|
63
|
+
expect(shallow(array, array)).toBe(true)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should return true for arrays with different references', () => {
|
|
67
|
+
expect(shallow([1, 2, 3], [1, 2, 3])).toBe(true)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('should return true for Maps with same reference', () => {
|
|
71
|
+
const map = new Map([['a', 1]])
|
|
72
|
+
expect(shallow(map, map)).toBe(true)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('should return true for Maps with different references', () => {
|
|
76
|
+
expect(shallow(new Map([['a', 1]]), new Map([['a', 1]]))).toBe(true)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('should return true for Sets with same reference', () => {
|
|
80
|
+
const set = new Set([1, 2, 3])
|
|
81
|
+
expect(shallow(set, set)).toBe(true)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('should return true for Sets with different references', () => {
|
|
85
|
+
expect(shallow(new Set([1, 2, 3]), new Set([1, 2, 3]))).toBe(true)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should return true for objects with same keys and values', () => {
|
|
89
|
+
const objectA = { a: 1, b: 2 }
|
|
90
|
+
const objectB = { a: 1, b: 2 }
|
|
91
|
+
expect(shallow(objectA, objectB)).toBe(true)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('should return false for objects with different keys or values', () => {
|
|
95
|
+
const objectA = { a: 1, b: 2 }
|
|
96
|
+
const objectB = { a: 1, b: 3 }
|
|
97
|
+
expect(shallow(objectA, objectB)).toBe(false)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should return true for arrays with same elements', () => {
|
|
101
|
+
const arrayA = [1, 2, 3]
|
|
102
|
+
const arrayB = [1, 2, 3]
|
|
103
|
+
expect(shallow(arrayA, arrayB)).toBe(true)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('should return false for arrays with different elements', () => {
|
|
107
|
+
const arrayA = [1, 2, 3]
|
|
108
|
+
const arrayB = [1, 2, 4]
|
|
109
|
+
expect(shallow(arrayA, arrayB)).toBe(false)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('should return true for Maps with same entries', () => {
|
|
113
|
+
const mapA = new Map([
|
|
114
|
+
['a', 1],
|
|
115
|
+
['b', 2],
|
|
116
|
+
])
|
|
117
|
+
const mapB = new Map([
|
|
118
|
+
['a', 1],
|
|
119
|
+
['b', 2],
|
|
120
|
+
])
|
|
121
|
+
expect(shallow(mapA, mapB)).toBe(true)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('should return false for Maps with different entries', () => {
|
|
125
|
+
const mapA = new Map([
|
|
126
|
+
['a', 1],
|
|
127
|
+
['b', 2],
|
|
128
|
+
])
|
|
129
|
+
const mapB = new Map([
|
|
130
|
+
['a', 1],
|
|
131
|
+
['b', 3],
|
|
132
|
+
])
|
|
133
|
+
expect(shallow(mapA, mapB)).toBe(false)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('should return true for Sets with same elements', () => {
|
|
137
|
+
const setA = new Set([1, 2, 3])
|
|
138
|
+
const setB = new Set([1, 2, 3])
|
|
139
|
+
expect(shallow(setA, setB)).toBe(true)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it('should return false for Sets with different elements', () => {
|
|
143
|
+
const setA = new Set([1, 2, 3])
|
|
144
|
+
const setB = new Set([1, 2, 4])
|
|
145
|
+
expect(shallow(setA, setB)).toBe(false)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('should return false for different objects with same properties', () => {
|
|
149
|
+
expect(shallow({ a: 1 }, { a: 2 })).toBe(false)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should return false for different arrays with same elements', () => {
|
|
153
|
+
expect(shallow([1, 2, 3], [1, 2, 4])).toBe(false)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('should return false for different Maps with same entries', () => {
|
|
157
|
+
expect(shallow(new Map([['a', 1]]), new Map([['a', 2]]))).toBe(false)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('should return false for different Sets with same elements', () => {
|
|
161
|
+
expect(shallow(new Set([1, 2, 3]), new Set([1, 2, 4]))).toBe(false)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it('should return false for objects with different reference', () => {
|
|
165
|
+
expect(shallow({ a: 1 }, { a: 2 })).toBe(false)
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('should return false for arrays with different reference', () => {
|
|
169
|
+
expect(shallow([1, 2, 3], [1, 2, 4])).toBe(false)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('should return false for Maps with different reference', () => {
|
|
173
|
+
expect(shallow(new Map([['a', 1]]), new Map([['a', 2]]))).toBe(false)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('should return false for Sets with different reference', () => {
|
|
177
|
+
expect(shallow(new Set([1, 2, 3]), new Set([1, 2, 4]))).toBe(false)
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('should return false for objects with different keys or values in', () => {
|
|
181
|
+
const objectA = { a: 1, b: 2 }
|
|
182
|
+
const objectB = { a: 1, b: 3 }
|
|
183
|
+
expect(shallow(objectA, objectB)).toBe(false)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('should return false for arrays with different elements', () => {
|
|
187
|
+
const arrayA = [1, 2, 3]
|
|
188
|
+
const arrayB = [1, 2, 4]
|
|
189
|
+
expect(shallow(arrayA, arrayB)).toBe(false)
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('should return false for Maps with different entries', () => {
|
|
193
|
+
const mapA = new Map([
|
|
194
|
+
['a', 1],
|
|
195
|
+
['b', 2],
|
|
196
|
+
])
|
|
197
|
+
const mapB = new Map([
|
|
198
|
+
['a', 1],
|
|
199
|
+
['b', 3],
|
|
200
|
+
])
|
|
201
|
+
expect(shallow(mapA, mapB)).toBe(false)
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
it('should return false for Sets with different elements', () => {
|
|
205
|
+
const setA = new Set([1, 2, 3])
|
|
206
|
+
const setB = new Set([1, 2, 4])
|
|
207
|
+
expect(shallow(setA, setB)).toBe(false)
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
it('should return false for objects with different keys or values', () => {
|
|
211
|
+
const objectA = { a: 1, b: 2 }
|
|
212
|
+
const objectB = { a: 1, b: 3 }
|
|
213
|
+
expect(shallow(objectA, objectB)).toBe(false)
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
it('should return false for arrays with different elements', () => {
|
|
217
|
+
const arrayA = [1, 2, 3]
|
|
218
|
+
const arrayB = [1, 2, 4]
|
|
219
|
+
expect(shallow(arrayA, arrayB)).toBe(false)
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('should return false for Maps with different entries', () => {
|
|
223
|
+
const mapA = new Map([
|
|
224
|
+
['a', 1],
|
|
225
|
+
['b', 2],
|
|
226
|
+
])
|
|
227
|
+
const mapB = new Map([
|
|
228
|
+
['a', 1],
|
|
229
|
+
['b', 3],
|
|
230
|
+
])
|
|
231
|
+
expect(shallow(mapA, mapB)).toBe(false)
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
it('should return false for Sets with different elements', () => {
|
|
235
|
+
const setA = new Set([1, 2, 3])
|
|
236
|
+
const setB = new Set([1, 2, 4])
|
|
237
|
+
expect(shallow(setA, setB)).toBe(false)
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
it('should return false for objects with different keys or values', () => {
|
|
241
|
+
const objectA = { a: 1, b: 2 }
|
|
242
|
+
const objectB = { a: 1, b: 3 }
|
|
243
|
+
expect(shallow(objectA, objectB)).toBe(false)
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
it('should return false for arrays with different elements', () => {
|
|
247
|
+
const arrayA = [1, 2, 3]
|
|
248
|
+
const arrayB = [1, 2, 4]
|
|
249
|
+
expect(shallow(arrayA, arrayB)).toBe(false)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('should return false for Maps with different entries', () => {
|
|
253
|
+
const mapA = new Map([
|
|
254
|
+
['a', 1],
|
|
255
|
+
['b', 2],
|
|
256
|
+
])
|
|
257
|
+
const mapB = new Map([
|
|
258
|
+
['a', 1],
|
|
259
|
+
['b', 3],
|
|
260
|
+
])
|
|
261
|
+
expect(shallow(mapA, mapB)).toBe(false)
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
it('should return false for Sets with different elements', () => {
|
|
265
|
+
const setA = new Set([1, 2, 3])
|
|
266
|
+
const setB = new Set([1, 2, 4])
|
|
267
|
+
expect(shallow(setA, setB)).toBe(false)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
it('should return false for objects with different keys or values', () => {
|
|
271
|
+
const objectA = { a: 1, b: 2 }
|
|
272
|
+
const objectB = { a: 1, b: 3 }
|
|
273
|
+
expect(shallow(objectA, objectB)).toBe(false)
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
it('should return false for arrays with different elements', () => {
|
|
277
|
+
const arrayA = [1, 2, 3]
|
|
278
|
+
const arrayB = [1, 2, 4]
|
|
279
|
+
expect(shallow(arrayA, arrayB)).toBe(false)
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
it('should return false for Maps with different entries', () => {
|
|
283
|
+
const mapA = new Map([
|
|
284
|
+
['a', 1],
|
|
285
|
+
['b', 2],
|
|
286
|
+
])
|
|
287
|
+
const mapB = new Map([
|
|
288
|
+
['a', 1],
|
|
289
|
+
['b', 3],
|
|
290
|
+
])
|
|
291
|
+
expect(shallow(mapA, mapB)).toBe(false)
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
it('should return false for Sets with different elements', () => {
|
|
295
|
+
const setA = new Set([1, 2, 3])
|
|
296
|
+
const setB = new Set([1, 2, 4])
|
|
297
|
+
expect(shallow(setA, setB)).toBe(false)
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
it('should return false for objects with different keys or values', () => {
|
|
301
|
+
const objectA = { a: 1, b: 2 }
|
|
302
|
+
const objectB = { a: 1, b: 3 }
|
|
303
|
+
expect(shallow(objectA, objectB)).toBe(false)
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
it('should return false for arrays with different elements', () => {
|
|
307
|
+
const arrayA = [1, 2, 3]
|
|
308
|
+
const arrayB = [1, 2, 4]
|
|
309
|
+
expect(shallow(arrayA, arrayB)).toBe(false)
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
it('should return false for Maps with different entries', () => {
|
|
313
|
+
const mapA = new Map([
|
|
314
|
+
['a', 1],
|
|
315
|
+
['b', 2],
|
|
316
|
+
])
|
|
317
|
+
const mapB = new Map([
|
|
318
|
+
['a', 1],
|
|
319
|
+
['b', 3],
|
|
320
|
+
])
|
|
321
|
+
expect(shallow(mapA, mapB)).toBe(false)
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
it('should return false for Sets with different elements', () => {
|
|
325
|
+
const setA = new Set([1, 2, 3])
|
|
326
|
+
const setB = new Set([1, 2, 4])
|
|
327
|
+
expect(shallow(setA, setB)).toBe(false)
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
it('should return false for objects with different keys or values', () => {
|
|
331
|
+
const objectA = { a: 1, b: 2 }
|
|
332
|
+
const objectB = { a: 1, b: 3 }
|
|
333
|
+
expect(shallow(objectA, objectB)).toBe(false)
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
it('should return false for arrays with different elements', () => {
|
|
337
|
+
const arrayA = [1, 2, 3]
|
|
338
|
+
const arrayB = [1, 2, 4]
|
|
339
|
+
expect(shallow(arrayA, arrayB)).toBe(false)
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
it('should return false for Maps with different entries', () => {
|
|
343
|
+
const mapA = new Map([
|
|
344
|
+
['a', 1],
|
|
345
|
+
['b', 2],
|
|
346
|
+
])
|
|
347
|
+
const mapB = new Map([
|
|
348
|
+
['a', 1],
|
|
349
|
+
['b', 3],
|
|
350
|
+
])
|
|
351
|
+
expect(shallow(mapA, mapB)).toBe(false)
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
it('should return false for Sets with different elements', () => {
|
|
355
|
+
const setA = new Set([1, 2, 3])
|
|
356
|
+
const setB = new Set([1, 2, 4])
|
|
357
|
+
expect(shallow(setA, setB)).toBe(false)
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
it('should return false for null and non-null values', () => {
|
|
361
|
+
expect(shallow(null, {})).toBe(false)
|
|
362
|
+
expect(shallow({}, null)).toBe(false)
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
it('should return false for objects with different number of keys', () => {
|
|
366
|
+
expect(shallow({ a: 1 }, { a: 1, b: 2 })).toBe(false)
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
it('should return false for objects with different keys', () => {
|
|
370
|
+
expect(shallow({ a: 1 }, { b: 1 })).toBe(false)
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
it('should return false for objects with different values', () => {
|
|
374
|
+
expect(shallow({ a: 1 }, { a: 2 })).toBe(false)
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
it('should return false for arrays with different lengths', () => {
|
|
378
|
+
expect(shallow([1, 2], [1, 2, 3])).toBe(false)
|
|
379
|
+
})
|
|
380
|
+
|
|
381
|
+
it('should return false for arrays with different elements', () => {
|
|
382
|
+
expect(shallow([1, 2, 3], [1, 2, 4])).toBe(false)
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
it('should return false for Maps with different sizes', () => {
|
|
386
|
+
expect(
|
|
387
|
+
shallow(
|
|
388
|
+
new Map([['a', 1]]),
|
|
389
|
+
new Map([
|
|
390
|
+
['a', 1],
|
|
391
|
+
['b', 2],
|
|
392
|
+
]),
|
|
393
|
+
),
|
|
394
|
+
).toBe(false)
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
it('should return false for Maps with different keys', () => {
|
|
398
|
+
expect(shallow(new Map([['a', 1]]), new Map([['b', 1]]))).toBe(false)
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
it('should return false for Maps with different values', () => {
|
|
402
|
+
expect(shallow(new Map([['a', 1]]), new Map([['a', 2]]))).toBe(false)
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
it('should return false for Sets with different sizes', () => {
|
|
406
|
+
expect(shallow(new Set([1, 2]), new Set([1, 2, 3]))).toBe(false)
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
it('should return false for Sets with different elements', () => {
|
|
410
|
+
expect(shallow(new Set([1, 2, 3]), new Set([1, 2, 4]))).toBe(false)
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
it('should return true compare simple values', () => {
|
|
414
|
+
expect(shallow(1, 1)).toBe(true)
|
|
415
|
+
expect(shallow('a', 'a')).toBe(true)
|
|
416
|
+
expect(shallow(true, true)).toBe(true)
|
|
417
|
+
})
|
|
418
|
+
})
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-shadow */
|
|
2
2
|
/* eslint-disable no-shadow */
|
|
3
3
|
import { Suspense } from 'react'
|
|
4
|
-
import { create } from '
|
|
4
|
+
import { create } from '../create'
|
|
5
5
|
import { renderHook, act, waitFor, render, screen } from '@testing-library/react'
|
|
6
|
-
import { shallow } from '
|
|
6
|
+
import { shallow } from '../shallow'
|
|
7
7
|
describe('state', () => {
|
|
8
8
|
it('should test state', () => {
|
|
9
9
|
const appState = create({ count: 0 })
|
|
@@ -485,34 +485,6 @@ describe('state', () => {
|
|
|
485
485
|
})
|
|
486
486
|
expect(renderCount.current).toEqual(1)
|
|
487
487
|
})
|
|
488
|
-
it('should use merge states', () => {
|
|
489
|
-
const state1 = create(3)
|
|
490
|
-
const state2 = create(2)
|
|
491
|
-
const mergedState = state1.merge(state2, (s1, s2) => s1 + s2)
|
|
492
|
-
const result = renderHook(() => mergedState())
|
|
493
|
-
expect(result.result.current).toEqual(5)
|
|
494
|
-
act(() => {
|
|
495
|
-
state1.setState(5)
|
|
496
|
-
})
|
|
497
|
-
expect(result.result.current).toEqual(7)
|
|
498
|
-
act(() => {
|
|
499
|
-
state2.setState(3)
|
|
500
|
-
})
|
|
501
|
-
expect(result.result.current).toEqual(8)
|
|
502
|
-
})
|
|
503
|
-
|
|
504
|
-
it('should use merge states nested', () => {
|
|
505
|
-
const useName = create(() => 'John')
|
|
506
|
-
const useAge = create(() => 30)
|
|
507
|
-
const useUser = useName.merge(useAge, (name, age) => ({ name, age }), shallow)
|
|
508
|
-
const result = renderHook(() => useUser())
|
|
509
|
-
expect(result.result.current).toEqual({ name: 'John', age: 30 })
|
|
510
|
-
|
|
511
|
-
act(() => {
|
|
512
|
-
useName.setState('Jane')
|
|
513
|
-
})
|
|
514
|
-
expect(result.result.current).toEqual({ name: 'Jane', age: 30 })
|
|
515
|
-
})
|
|
516
488
|
|
|
517
489
|
it('should use slice with new reference', () => {
|
|
518
490
|
const useName = create(() => 'John')
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Component } from 'react'
|
|
2
|
+
|
|
3
|
+
export function longPromise(time = 200): Promise<number> {
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
setTimeout(() => {
|
|
6
|
+
resolve(0)
|
|
7
|
+
}, time)
|
|
8
|
+
})
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// ErrorBoundary Component
|
|
12
|
+
export class ErrorBoundary extends Component<
|
|
13
|
+
{ fallback: React.ReactNode; children: React.ReactNode },
|
|
14
|
+
{ hasError: boolean; error: Error | null }
|
|
15
|
+
> {
|
|
16
|
+
constructor(props: { fallback: React.ReactNode; children: React.ReactNode }) {
|
|
17
|
+
super(props)
|
|
18
|
+
this.state = { hasError: false, error: null }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static getDerivedStateFromError(error: Error) {
|
|
22
|
+
// Update state so the next render shows the fallback UI.
|
|
23
|
+
return { hasError: true, error }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
|
27
|
+
// You can log the error to an error reporting service here
|
|
28
|
+
// eslint-disable-next-line no-console
|
|
29
|
+
console.error('ErrorBoundary caught an error:', error, errorInfo)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
render() {
|
|
33
|
+
if (this.state.hasError) {
|
|
34
|
+
// Render fallback UI
|
|
35
|
+
return this.props.fallback
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return this.props.children
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getDefaultValue } from '../types'
|
|
2
|
+
|
|
3
|
+
describe('getDefaultValue', () => {
|
|
4
|
+
it('should return the value if it is not a function or promise', () => {
|
|
5
|
+
expect(getDefaultValue(123)).toBe(123)
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
it('should return the resolved value if it is a function', () => {
|
|
9
|
+
expect(getDefaultValue(() => 123)).toBe(123)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('should return the promise if it is a promise', () => {
|
|
13
|
+
const promise = Promise.resolve(123)
|
|
14
|
+
expect(getDefaultValue(promise)).toBe(promise)
|
|
15
|
+
expect(getDefaultValue(() => promise)).toBe(promise)
|
|
16
|
+
})
|
|
17
|
+
})
|
package/src/common.ts
CHANGED
|
@@ -26,3 +26,35 @@ export function useSyncExternalStore<T, S>(
|
|
|
26
26
|
useDebugValue(value)
|
|
27
27
|
return value
|
|
28
28
|
}
|
|
29
|
+
// eslint-disable-next-line no-shadow
|
|
30
|
+
export enum Abort {
|
|
31
|
+
Error = 'StateAbortError',
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Cancelable promise function, return promise and controller
|
|
35
|
+
*/
|
|
36
|
+
export function cancelablePromise<T>(
|
|
37
|
+
promise: Promise<T>,
|
|
38
|
+
previousController?: AbortController,
|
|
39
|
+
): {
|
|
40
|
+
promise: Promise<T>
|
|
41
|
+
controller: AbortController
|
|
42
|
+
} {
|
|
43
|
+
if (previousController) {
|
|
44
|
+
previousController.abort()
|
|
45
|
+
}
|
|
46
|
+
const controller = new AbortController()
|
|
47
|
+
const { signal } = controller
|
|
48
|
+
|
|
49
|
+
const cancelable = new Promise<T>((resolve, reject) => {
|
|
50
|
+
// Listen for the abort event
|
|
51
|
+
signal.addEventListener('abort', () => {
|
|
52
|
+
reject(new DOMException('Promise was aborted', Abort.Error))
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// When the original promise settles, resolve or reject accordingly
|
|
56
|
+
promise.then(resolve).catch(reject)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
return { promise: cancelable, controller }
|
|
60
|
+
}
|
package/src/create-base-state.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Emitter } from './create-emitter'
|
|
2
|
-
import { merge } from './merge'
|
|
3
2
|
import { select } from './select'
|
|
4
3
|
import type { BaseState, GetterState } from './types'
|
|
5
4
|
|
|
@@ -18,10 +17,7 @@ export function createBaseState<T>(options: Options<T>): BaseState<T> {
|
|
|
18
17
|
const state = getGetterState()
|
|
19
18
|
return select(state, selector, isSame)
|
|
20
19
|
},
|
|
21
|
-
|
|
22
|
-
const state = getGetterState()
|
|
23
|
-
return merge(state, state2, selector, isEqualHook)
|
|
24
|
-
},
|
|
20
|
+
|
|
25
21
|
__internal: {
|
|
26
22
|
emitter,
|
|
27
23
|
},
|
|
@@ -13,7 +13,6 @@ export function createGetterState<T>(options: Options<T>): GetterState<T> {
|
|
|
13
13
|
useSliceState.getState = baseState.getState
|
|
14
14
|
useSliceState.reset = baseState.reset
|
|
15
15
|
useSliceState.select = baseState.select
|
|
16
|
-
useSliceState.merge = baseState.merge
|
|
17
16
|
useSliceState.subscribe = baseState.subscribe
|
|
18
17
|
return useSliceState
|
|
19
18
|
}
|