mirror of https://github.com/vuejs/core.git
test: port tests
This commit is contained in:
parent
a103715cfb
commit
c6e3fab3de
|
@ -686,5 +686,222 @@ describe('VaporKeepAlive', () => {
|
|||
test('include + exclude', async () => {
|
||||
await assertNameMatch({ include: () => 'one,two', exclude: () => 'two' })
|
||||
})
|
||||
|
||||
test('max', async () => {
|
||||
const spyAC = vi.fn()
|
||||
const spyBC = vi.fn()
|
||||
const spyCC = vi.fn()
|
||||
const spyAA = vi.fn()
|
||||
const spyBA = vi.fn()
|
||||
const spyCA = vi.fn()
|
||||
const spyADA = vi.fn()
|
||||
const spyBDA = vi.fn()
|
||||
const spyCDA = vi.fn()
|
||||
const spyAUM = vi.fn()
|
||||
const spyBUM = vi.fn()
|
||||
const spyCUM = vi.fn()
|
||||
|
||||
function assertCount(calls: number[]) {
|
||||
expect([
|
||||
spyAC.mock.calls.length,
|
||||
spyAA.mock.calls.length,
|
||||
spyADA.mock.calls.length,
|
||||
spyAUM.mock.calls.length,
|
||||
spyBC.mock.calls.length,
|
||||
spyBA.mock.calls.length,
|
||||
spyBDA.mock.calls.length,
|
||||
spyBUM.mock.calls.length,
|
||||
spyCC.mock.calls.length,
|
||||
spyCA.mock.calls.length,
|
||||
spyCDA.mock.calls.length,
|
||||
spyCUM.mock.calls.length,
|
||||
]).toEqual(calls)
|
||||
}
|
||||
const viewRef = ref('a')
|
||||
const views: Record<string, VaporComponent> = {
|
||||
a: defineVaporComponent({
|
||||
name: 'a',
|
||||
setup() {
|
||||
onBeforeMount(() => spyAC())
|
||||
onActivated(() => spyAA())
|
||||
onDeactivated(() => spyADA())
|
||||
onUnmounted(() => spyAUM())
|
||||
return template(`one`)()
|
||||
},
|
||||
}),
|
||||
b: defineVaporComponent({
|
||||
name: 'b',
|
||||
setup() {
|
||||
onBeforeMount(() => spyBC())
|
||||
onActivated(() => spyBA())
|
||||
onDeactivated(() => spyBDA())
|
||||
onUnmounted(() => spyBUM())
|
||||
return template(`two`)()
|
||||
},
|
||||
}),
|
||||
c: defineVaporComponent({
|
||||
name: 'c',
|
||||
setup() {
|
||||
onBeforeMount(() => spyCC())
|
||||
onActivated(() => spyCA())
|
||||
onDeactivated(() => spyCDA())
|
||||
onUnmounted(() => spyCUM())
|
||||
return template(`three`)()
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
define({
|
||||
setup() {
|
||||
return createComponent(
|
||||
VaporKeepAlive,
|
||||
{ max: () => 2 },
|
||||
{
|
||||
default: () => createDynamicComponent(() => views[viewRef.value]),
|
||||
},
|
||||
)
|
||||
},
|
||||
}).render()
|
||||
assertCount([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
|
||||
viewRef.value = 'b'
|
||||
await nextTick()
|
||||
assertCount([1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0])
|
||||
|
||||
viewRef.value = 'c'
|
||||
await nextTick()
|
||||
// should prune A because max cache reached
|
||||
assertCount([1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0])
|
||||
|
||||
viewRef.value = 'b'
|
||||
await nextTick()
|
||||
// B should be reused, and made latest
|
||||
assertCount([1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0])
|
||||
|
||||
viewRef.value = 'a'
|
||||
await nextTick()
|
||||
// C should be pruned because B was used last so C is the oldest cached
|
||||
assertCount([2, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 1])
|
||||
})
|
||||
})
|
||||
|
||||
describe('cache invalidation', () => {
|
||||
function setup() {
|
||||
const viewRef = ref('one')
|
||||
const includeRef = ref('one,two')
|
||||
define({
|
||||
setup() {
|
||||
return createComponent(
|
||||
VaporKeepAlive,
|
||||
{ include: () => includeRef.value },
|
||||
{
|
||||
default: () => createDynamicComponent(() => views[viewRef.value]),
|
||||
},
|
||||
)
|
||||
},
|
||||
}).render()
|
||||
return { viewRef, includeRef }
|
||||
}
|
||||
|
||||
function setupExclude() {
|
||||
const viewRef = ref('one')
|
||||
const excludeRef = ref('')
|
||||
define({
|
||||
setup() {
|
||||
return createComponent(
|
||||
VaporKeepAlive,
|
||||
{ exclude: () => excludeRef.value },
|
||||
{
|
||||
default: () => createDynamicComponent(() => views[viewRef.value]),
|
||||
},
|
||||
)
|
||||
},
|
||||
}).render()
|
||||
return { viewRef, excludeRef }
|
||||
}
|
||||
|
||||
test('on include change', async () => {
|
||||
const { viewRef, includeRef } = setup()
|
||||
|
||||
viewRef.value = 'two'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 1, 0])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 0, 0])
|
||||
|
||||
includeRef.value = 'two'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 1, 1])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 0, 0])
|
||||
|
||||
viewRef.value = 'one'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [2, 2, 1, 1, 1])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 1, 0])
|
||||
})
|
||||
|
||||
test('on exclude change', async () => {
|
||||
const { viewRef, excludeRef } = setupExclude()
|
||||
|
||||
viewRef.value = 'two'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 1, 0])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 0, 0])
|
||||
|
||||
excludeRef.value = 'one'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 1, 1])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 0, 0])
|
||||
|
||||
viewRef.value = 'one'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [2, 2, 1, 1, 1])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 1, 0])
|
||||
})
|
||||
|
||||
test('on include change + view switch', async () => {
|
||||
const { viewRef, includeRef } = setup()
|
||||
|
||||
viewRef.value = 'two'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 1, 0])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 0, 0])
|
||||
|
||||
includeRef.value = 'one'
|
||||
viewRef.value = 'one'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 2, 1, 0])
|
||||
// two should be pruned
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 1, 1])
|
||||
})
|
||||
|
||||
test('on exclude change + view switch', async () => {
|
||||
const { viewRef, excludeRef } = setupExclude()
|
||||
|
||||
viewRef.value = 'two'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 1, 0])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 0, 0])
|
||||
|
||||
excludeRef.value = 'two'
|
||||
viewRef.value = 'one'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 2, 1, 0])
|
||||
// two should be pruned
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 1, 1])
|
||||
})
|
||||
|
||||
test('should not prune current active instance', async () => {
|
||||
const { viewRef, includeRef } = setup()
|
||||
|
||||
includeRef.value = 'two'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 0, 0])
|
||||
assertHookCalls(twoHooks, [0, 0, 0, 0, 0])
|
||||
|
||||
viewRef.value = 'two'
|
||||
await nextTick()
|
||||
assertHookCalls(oneHooks, [1, 1, 1, 0, 1])
|
||||
assertHookCalls(twoHooks, [1, 1, 1, 0, 0])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -62,9 +62,8 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
;(keepAliveInstance as any).__v_cache = cache
|
||||
}
|
||||
|
||||
const { include, exclude, max } = props
|
||||
|
||||
function shouldCache(instance: VaporComponentInstance) {
|
||||
const { include, exclude } = props
|
||||
const name = getComponentName(instance.type)
|
||||
return !(
|
||||
(include && (!name || !matches(include, name))) ||
|
||||
|
@ -73,6 +72,7 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
}
|
||||
|
||||
function cacheBlock() {
|
||||
const { max } = props
|
||||
// TODO suspense
|
||||
const currentBlock = keepAliveInstance.block!
|
||||
if (!isValidBlock(currentBlock)) return
|
||||
|
@ -119,15 +119,6 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
instance.shapeFlag! |= ShapeFlags.COMPONENT_KEPT_ALIVE
|
||||
}
|
||||
|
||||
// const name = getComponentName(instance.type)
|
||||
// if (
|
||||
// !(
|
||||
// (include && (!name || !matches(include, name))) ||
|
||||
// (exclude && name && matches(exclude, name))
|
||||
// )
|
||||
// ) {
|
||||
// instance.shapeFlag! |= ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
|
||||
// }
|
||||
if (shouldCache(instance)) {
|
||||
instance.shapeFlag! |= ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
|
||||
}
|
||||
|
@ -138,7 +129,7 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
parentNode: ParentNode,
|
||||
anchor: Node,
|
||||
) => {
|
||||
const cachedBlock = cache.get(instance.type)!
|
||||
const cachedBlock = (current = cache.get(instance.type)!)
|
||||
insert((instance.block = cachedBlock.block), parentNode, anchor)
|
||||
queuePostFlushCb(() => {
|
||||
instance.isDeactivated = false
|
||||
|
@ -182,7 +173,10 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
function pruneCacheEntry(key: CacheKey) {
|
||||
const cached = cache.get(key)
|
||||
if (cached) {
|
||||
unmountComponent(cached)
|
||||
resetShapeFlag(cached)
|
||||
if (cached !== current) {
|
||||
unmountComponent(cached)
|
||||
}
|
||||
}
|
||||
cache.delete(key)
|
||||
keys.delete(key)
|
||||
|
|
Loading…
Reference in New Issue