-
-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build(3.4.15): del notify redundant excludedInsKeyDict logic
- Loading branch information
1 parent
6bf8ba3
commit fd5727b
Showing
6 changed files
with
231 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
packages/helux/__tests__/hook-options/_makeArrDepTest.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import { renderHook } from '@testing-library/react'; | ||
import { describe, expect, test } from 'vitest'; | ||
import { atom, useAtom } from '../helux'; | ||
import { dictFictory, getDepKey, noop } from '../util'; | ||
|
||
interface IOptionsBase { | ||
arrIndexDep?: boolean; | ||
arrDep?: boolean; | ||
} | ||
interface IOptions extends IOptionsBase { | ||
getMatchObj: (rootValKey: string) => any; | ||
} | ||
|
||
export function makeTest(options: { label: string; atom: typeof atom; useAtom: typeof useAtom }) { | ||
const { label, atom, useAtom } = options; | ||
|
||
async function testNotReadList(options: IOptionsBase) { | ||
const { arrIndexDep, arrDep } = options; | ||
const [dictAtom, setDictAtom, { rootValKey }] = atom(dictFictory); | ||
const { result } = renderHook(() => { | ||
const [state, , info] = useAtom(dictAtom, { arrIndexDep, arrDep }); | ||
return info.getDeps(); | ||
}); | ||
|
||
expect(result.current).toMatchObject([rootValKey]); | ||
} | ||
|
||
/** arrIndexDep=true by default */ | ||
async function testReadList(options: IOptions) { | ||
const { arrIndexDep, arrDep, getMatchObj } = options; | ||
const [dictAtom, setDictAtom, { rootValKey }] = atom(dictFictory); | ||
const { result } = renderHook(() => { | ||
const [state, , info] = useAtom(dictAtom, { arrIndexDep, arrDep }); | ||
noop(state.extra.list); | ||
noop(state.extra.list[0]); | ||
noop(state.extra.list[1]); | ||
return info.getDeps(); | ||
}); | ||
|
||
expect(result.current).toMatchObject(getMatchObj(rootValKey)); | ||
} | ||
|
||
const getArrDepAndIndexDep = (rootValKey) => [ | ||
getDepKey(rootValKey, 'extra.list'), | ||
getDepKey(rootValKey, 'extra.list.0'), | ||
getDepKey(rootValKey, 'extra.list.1'), | ||
]; | ||
|
||
const getArrDep = (rootValKey) => [getDepKey(rootValKey, 'extra.list')]; | ||
|
||
const getIndexDep = (rootValKey) => [getDepKey(rootValKey, 'extra.list.0'), getDepKey(rootValKey, 'extra.list.1')]; | ||
|
||
describe(`${label} arrDep=undefined`, () => { | ||
test('arrIndexDep=undefined, not read list', async () => { | ||
await testNotReadList({ arrDep: undefined, arrIndexDep: undefined }); | ||
}); | ||
|
||
test('arrIndexDep=true, not read list', async () => { | ||
await testNotReadList({ arrDep: undefined, arrIndexDep: true }); | ||
}); | ||
|
||
test('arrIndexDep=false, not read list', async () => { | ||
await testNotReadList({ arrDep: undefined, arrIndexDep: false }); | ||
}); | ||
|
||
test('arrIndexDep=undefined, read list', async () => { | ||
await testReadList({ | ||
arrDep: undefined, | ||
arrIndexDep: undefined, | ||
getMatchObj: getArrDepAndIndexDep, | ||
}); | ||
}); | ||
|
||
test('arrIndexDep=true, read list', async () => { | ||
await testReadList({ | ||
arrDep: undefined, | ||
arrIndexDep: true, | ||
getMatchObj: getArrDepAndIndexDep, | ||
}); | ||
}); | ||
|
||
test('arrIndexDep=false, read list', async () => { | ||
await testReadList({ | ||
arrDep: undefined, | ||
arrIndexDep: false, | ||
getMatchObj: getArrDep, | ||
}); | ||
}); | ||
}); | ||
|
||
describe(`${label} arrDep=true`, () => { | ||
test('arrIndexDep=undefined, not read list', async () => { | ||
await testNotReadList({ arrDep: true, arrIndexDep: undefined }); | ||
}); | ||
|
||
test('arrIndexDep=true, not read list', async () => { | ||
await testNotReadList({ arrDep: true, arrIndexDep: true }); | ||
}); | ||
|
||
test('arrIndexDep=false, not read list', async () => { | ||
await testNotReadList({ arrDep: true, arrIndexDep: false }); | ||
}); | ||
|
||
test('arrIndexDep=undefined, read list', async () => { | ||
await testReadList({ | ||
arrDep: true, | ||
arrIndexDep: undefined, | ||
getMatchObj: getArrDepAndIndexDep, | ||
}); | ||
}); | ||
|
||
test('arrIndexDep=true, read list', async () => { | ||
await testReadList({ | ||
arrDep: true, | ||
arrIndexDep: true, | ||
getMatchObj: getArrDepAndIndexDep, | ||
}); | ||
}); | ||
|
||
test('arrIndexDep=true, read list', async () => { | ||
await testReadList({ | ||
arrDep: true, | ||
arrIndexDep: false, | ||
getMatchObj: getArrDep, | ||
}); | ||
}); | ||
}); | ||
|
||
describe(`${label} arrDep=false`, () => { | ||
test('arrIndexDep=true, read list', async () => { | ||
await testReadList({ | ||
arrDep: false, | ||
arrIndexDep: true, | ||
getMatchObj: getIndexDep, | ||
}); | ||
}); | ||
|
||
test('arrIndexDep=false, read list', async () => { | ||
await testReadList({ | ||
arrDep: false, | ||
arrIndexDep: false, | ||
getMatchObj: getIndexDep, | ||
}); | ||
}); | ||
|
||
test('arrIndexDep=undefined, read list', async () => { | ||
await testReadList({ | ||
arrDep: false, | ||
arrIndexDep: undefined, | ||
getMatchObj: getIndexDep, | ||
}); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { atom, share, useAtom, useShared } from '../helux'; | ||
import { makeTest } from './_makeArrDepTest'; | ||
|
||
makeTest({ label: 'useAtom', atom, useAtom }); | ||
|
||
makeTest({ label: 'useShared', atom: share as any, useAtom: useShared as any }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { renderHook } from '@testing-library/react'; | ||
import { describe, expect, test } from 'vitest'; | ||
import { atom, useAtom } from '../helux'; | ||
import { dictFictory, getDepKey, noop } from '../util'; | ||
|
||
describe('useAtom options.pure', () => { | ||
test('pure=undefined', async () => { | ||
const [dictAtom, setDictAtom, { rootValKey }] = atom(dictFictory); | ||
|
||
let renderCount = 0; | ||
const { result } = renderHook(() => { | ||
renderCount += 1; | ||
const [state, , info] = useAtom(dictAtom); | ||
return info.getDeps(); | ||
}); | ||
|
||
expect(result.current).toMatchObject([rootValKey]); | ||
expect(renderCount).toBe(1); | ||
|
||
setDictAtom((draft) => { | ||
draft.a.b.c = 100; | ||
}); | ||
expect(renderCount).toBe(1); | ||
}); | ||
|
||
test('pure=undefined, read state.a, update a.b.c', async () => { | ||
const [dictAtom, setDictAtom, { rootValKey }] = atom(dictFictory); | ||
|
||
let renderCount = 0; | ||
const { result } = renderHook(() => { | ||
renderCount += 1; | ||
const [state, , info] = useAtom(dictAtom); | ||
noop(state.a); | ||
return info.getDeps(); | ||
}); | ||
|
||
expect(result.current).toMatchObject([getDepKey(rootValKey, 'a')]); | ||
expect(renderCount).toBe(1); | ||
|
||
setDictAtom((draft) => { | ||
draft.a.b.c = 100; | ||
}); | ||
// 更新 a.b.c ,通过 rootValKey 配合不对称记录机制,能查到依赖 a 的示例并触发更新 | ||
expect(renderCount).toBe(2); | ||
}); | ||
|
||
test('pure=undefined, read state.a.b.c, update a', async () => { | ||
const [dictAtom, setDictAtom, { rootValKey }] = atom(dictFictory); | ||
|
||
let renderCount = 0; | ||
const { result } = renderHook(() => { | ||
renderCount += 1; | ||
const [state, , info] = useAtom(dictAtom); | ||
noop(state.a.b.c); | ||
return info.getDeps(); | ||
}); | ||
|
||
expect(result.current).toMatchObject([getDepKey(rootValKey, 'a.b.c')]); | ||
expect(renderCount).toBe(1); | ||
|
||
setDictAtom((draft) => { | ||
draft.a = { ...draft.a }; | ||
}); | ||
// 更新 a,但 a.b.c 无变化,故实例不会更新 | ||
expect(renderCount).toBe(1); | ||
}); | ||
}); |