Skip to content

Commit d96883c

Browse files
authored
test(reactivity): test for verifying no unnecessary calls of reactive array identity methods (#11328)
related: #9511
1 parent 1ae545a commit d96883c

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

packages/reactivity/__tests__/reactiveArray.spec.ts

+74
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,80 @@ describe('reactivity/reactive/Array', () => {
8989
expect(index).toBe(1)
9090
})
9191

92+
// only non-existent reactive will try to search by using its raw value
93+
describe('Array identity methods have been called times', () => {
94+
const identityMethods = ['includes', 'indexOf', 'lastIndexOf'] as const
95+
function instrumentArr(rawTarget: any[]) {
96+
identityMethods.forEach(key => {
97+
const spy = vi.fn(rawTarget[key] as any)
98+
rawTarget[key] = spy
99+
})
100+
}
101+
function searchValue(target: any[], ...args: unknown[]) {
102+
return identityMethods.map(key => (target[key] as any)(...args))
103+
}
104+
function unInstrumentArr(rawTarget: any[]) {
105+
identityMethods.forEach(key => {
106+
;(rawTarget[key] as any).mockClear()
107+
// relink to prototype method
108+
rawTarget[key] = Array.prototype[key] as any
109+
})
110+
}
111+
function expectHaveBeenCalledTimes(rawTarget: any[], times: number) {
112+
identityMethods.forEach(key => {
113+
expect(rawTarget[key]).toHaveBeenCalledTimes(times)
114+
})
115+
}
116+
117+
test('should be called once with a non-existent raw value', () => {
118+
const reactiveArr = reactive([])
119+
instrumentArr(toRaw(reactiveArr))
120+
const searchResult = searchValue(reactiveArr, {})
121+
122+
expectHaveBeenCalledTimes(toRaw(reactiveArr), 1)
123+
expect(searchResult).toStrictEqual([false, -1, -1])
124+
125+
unInstrumentArr(toRaw(reactiveArr))
126+
})
127+
128+
test('should be called once with an existent reactive value', () => {
129+
const existReactiveValue = reactive({})
130+
const reactiveArr = reactive([existReactiveValue, existReactiveValue])
131+
132+
instrumentArr(toRaw(reactiveArr))
133+
const searchResult = searchValue(reactiveArr, existReactiveValue)
134+
135+
expectHaveBeenCalledTimes(toRaw(reactiveArr), 1)
136+
expect(searchResult).toStrictEqual([true, 0, 1])
137+
138+
unInstrumentArr(toRaw(reactiveArr))
139+
})
140+
141+
test('should be called twice with a non-existent reactive value', () => {
142+
const reactiveArr = reactive([])
143+
instrumentArr(toRaw(reactiveArr))
144+
const searchResult = searchValue(reactiveArr, reactive({}))
145+
146+
expectHaveBeenCalledTimes(toRaw(reactiveArr), 2)
147+
expect(searchResult).toStrictEqual([false, -1, -1])
148+
149+
unInstrumentArr(toRaw(reactiveArr))
150+
})
151+
152+
test('should be called twice with a non-existent reactive value, but the raw value exists', () => {
153+
const existRaw = {}
154+
const reactiveArr = reactive([existRaw, existRaw])
155+
156+
instrumentArr(toRaw(reactiveArr))
157+
const searchResult = searchValue(reactiveArr, reactive(existRaw))
158+
159+
expectHaveBeenCalledTimes(toRaw(reactiveArr), 2)
160+
expect(searchResult).toStrictEqual([true, 0, 1])
161+
162+
unInstrumentArr(toRaw(reactiveArr))
163+
})
164+
})
165+
92166
test('delete on Array should not trigger length dependency', () => {
93167
const arr = reactive([1, 2, 3])
94168
const fn = vi.fn()

0 commit comments

Comments
 (0)