describe('KeepAlive', () => {
let one: ComponentOptions
let two: ComponentOptions
+ let oneTest: ComponentOptions
let views: Record<string, ComponentOptions>
let root: TestElement
deactivated: vi.fn(),
unmounted: vi.fn(),
}
+ oneTest = {
+ name: 'oneTest',
+ data: () => ({ msg: 'oneTest' }),
+ render(this: any) {
+ return h('div', this.msg)
+ },
+ created: vi.fn(),
+ mounted: vi.fn(),
+ activated: vi.fn(),
+ deactivated: vi.fn(),
+ unmounted: vi.fn(),
+ }
two = {
name: 'two',
data: () => ({ msg: 'two' }),
}
views = {
one,
+ oneTest,
two,
}
})
assertHookCalls(two, [2, 2, 0, 0, 2])
}
+ async function assertNameMatchWithFlag(props: KeepAliveProps) {
+ const outerRef = ref(true)
+ const viewRef = ref('one')
+ const App = {
+ render() {
+ return outerRef.value
+ ? h(KeepAlive, props, () => h(views[viewRef.value]))
+ : null
+ },
+ }
+ render(h(App), root)
+
+ expect(serializeInner(root)).toBe(`<div>one</div>`)
+ assertHookCalls(one, [1, 1, 1, 0, 0])
+ assertHookCalls(oneTest, [0, 0, 0, 0, 0])
+ assertHookCalls(two, [0, 0, 0, 0, 0])
+
+ viewRef.value = 'oneTest'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>oneTest</div>`)
+ assertHookCalls(one, [1, 1, 1, 1, 0])
+ assertHookCalls(oneTest, [1, 1, 1, 0, 0])
+ assertHookCalls(two, [0, 0, 0, 0, 0])
+
+ viewRef.value = 'two'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>two</div>`)
+ assertHookCalls(one, [1, 1, 1, 1, 0])
+ assertHookCalls(oneTest, [1, 1, 1, 1, 0])
+ assertHookCalls(two, [1, 1, 0, 0, 0])
+
+ viewRef.value = 'one'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>one</div>`)
+ assertHookCalls(one, [1, 1, 2, 1, 0])
+ assertHookCalls(oneTest, [1, 1, 1, 1, 0])
+ assertHookCalls(two, [1, 1, 0, 0, 1])
+
+ viewRef.value = 'oneTest'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>oneTest</div>`)
+ assertHookCalls(one, [1, 1, 2, 2, 0])
+ assertHookCalls(oneTest, [1, 1, 2, 1, 0])
+ assertHookCalls(two, [1, 1, 0, 0, 1])
+
+ viewRef.value = 'two'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>two</div>`)
+ assertHookCalls(one, [1, 1, 2, 2, 0])
+ assertHookCalls(oneTest, [1, 1, 2, 2, 0])
+ assertHookCalls(two, [2, 2, 0, 0, 1])
+
+ // teardown
+ outerRef.value = false
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<!---->`)
+ assertHookCalls(one, [1, 1, 2, 2, 1])
+ assertHookCalls(oneTest, [1, 1, 2, 2, 1])
+ assertHookCalls(two, [2, 2, 0, 0, 2])
+ }
+
+ async function assertNameMatchWithFlagExclude(props: KeepAliveProps) {
+ const outerRef = ref(true)
+ const viewRef = ref('one')
+ const App = {
+ render() {
+ return outerRef.value
+ ? h(KeepAlive, props, () => h(views[viewRef.value]))
+ : null
+ },
+ }
+ render(h(App), root)
+
+ expect(serializeInner(root)).toBe(`<div>one</div>`)
+ assertHookCalls(one, [1, 1, 0, 0, 0])
+ assertHookCalls(oneTest, [0, 0, 0, 0, 0])
+ assertHookCalls(two, [0, 0, 0, 0, 0])
+
+ viewRef.value = 'oneTest'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>oneTest</div>`)
+ assertHookCalls(one, [1, 1, 0, 0, 1])
+ assertHookCalls(oneTest, [1, 1, 0, 0, 0])
+ assertHookCalls(two, [0, 0, 0, 0, 0])
+
+ viewRef.value = 'two'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>two</div>`)
+ assertHookCalls(one, [1, 1, 0, 0, 1])
+ assertHookCalls(oneTest, [1, 1, 0, 0, 1])
+ assertHookCalls(two, [1, 1, 1, 0, 0])
+
+ viewRef.value = 'one'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>one</div>`)
+ assertHookCalls(one, [2, 2, 0, 0, 1])
+ assertHookCalls(oneTest, [1, 1, 0, 0, 1])
+ assertHookCalls(two, [1, 1, 1, 1, 0])
+
+ viewRef.value = 'oneTest'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>oneTest</div>`)
+ assertHookCalls(one, [2, 2, 0, 0, 2])
+ assertHookCalls(oneTest, [2, 2, 0, 0, 1])
+ assertHookCalls(two, [1, 1, 1, 1, 0])
+
+ viewRef.value = 'two'
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<div>two</div>`)
+ assertHookCalls(one, [2, 2, 0, 0, 2])
+ assertHookCalls(oneTest, [2, 2, 0, 0, 2])
+ assertHookCalls(two, [1, 1, 2, 1, 0])
+
+ // teardown
+ outerRef.value = false
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<!---->`)
+ assertHookCalls(one, [2, 2, 0, 0, 2])
+ assertHookCalls(oneTest, [2, 2, 0, 0, 2])
+ assertHookCalls(two, [1, 1, 2, 2, 1])
+ }
+
describe('props', () => {
test('include (string)', async () => {
await assertNameMatch({ include: 'one' })
await assertNameMatch({ include: /^one$/ })
})
+ test('include (regex with g flag)', async () => {
+ await assertNameMatchWithFlag({ include: /one/g })
+ })
+
test('include (array)', async () => {
await assertNameMatch({ include: ['one'] })
})
await assertNameMatch({ exclude: /^two$/ })
})
+ test('exclude (regex with a flag)', async () => {
+ await assertNameMatchWithFlagExclude({ exclude: /one/g })
+ })
+
test('exclude (array)', async () => {
await assertNameMatch({ exclude: ['two'] })
})