Skip to content

Commit

Permalink
fix(stub): re-render of recursive component using wrong cached stub
Browse files Browse the repository at this point in the history
  • Loading branch information
freakzlike committed May 18, 2023
1 parent b8db811 commit 8ae1ddd
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/createInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ export function createInstance(
// stub out Transition and Transition Group by default.
transformVNodeArgs(
createVNodeTransformer({
rootComponents,
transformers: [
createStubComponentsTransformer({
rootComponents,
Expand Down
17 changes: 8 additions & 9 deletions src/vnodeTransformers/stubComponentsTransformer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { isKeepAlive, isTeleport, VTUVNodeTypeTransformer } from './util'
import {
isKeepAlive,
isRootComponent,
isTeleport,
VTUVNodeTypeTransformer
} from './util'
import {
Transition,
TransitionGroup,
Expand Down Expand Up @@ -177,14 +182,8 @@ export function createStubComponentsTransformer({
})
}

if (
// Don't stub VTU_ROOT component
!instance ||
// Don't stub mounted component on root level
(rootComponents.component === type && !instance?.parent) ||
// Don't stub component with compat wrapper
(rootComponents.functional && rootComponents.functional === type)
) {
// Don't stub root components
if (isRootComponent(rootComponents, type, instance)) {
return type
}

Expand Down
33 changes: 29 additions & 4 deletions src/vnodeTransformers/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isComponent } from '../utils'
import { registerStub } from '../stubs'
import { ConcreteComponent, transformVNodeArgs } from 'vue'
import { Component, ConcreteComponent, transformVNodeArgs } from 'vue'

type VNodeArgsTransformerFn = NonNullable<
Parameters<typeof transformVNodeArgs>[0]
Expand All @@ -23,9 +23,30 @@ export type VTUVNodeTypeTransformer = (
export const isTeleport = (type: any): boolean => type.__isTeleport
export const isKeepAlive = (type: any): boolean => type.__isKeepAlive

export interface RootComponents {
// Component which has been passed to mount. For functional components it contains a wrapper
component?: Component
// If component is functional then contains the original component otherwise empty
functional?: Component
}
export const isRootComponent = (
rootComponents: RootComponents,
type: VNodeTransformerInputComponentType,
instance: InstanceArgsType
): boolean =>
!!(
!instance ||
// Don't stub mounted component on root level
(rootComponents.component === type && !instance?.parent) ||
// Don't stub component with compat wrapper
(rootComponents.functional && rootComponents.functional === type)
)

export const createVNodeTransformer = ({
rootComponents,
transformers
}: {
rootComponents: RootComponents
transformers: VTUVNodeTypeTransformer[]
}): VNodeArgsTransformerFn => {
const transformationCache: WeakMap<
Expand All @@ -40,8 +61,14 @@ export const createVNodeTransformer = ({
return [originalType, props, children, ...restVNodeArgs]
}

const componentType: VNodeTransformerInputComponentType = originalType

const cachedTransformation = transformationCache.get(originalType)
if (cachedTransformation) {
if (
cachedTransformation &&
// Don't use cache for root component, as it could use stubbed recursive component
!isRootComponent(rootComponents, componentType, instance)
) {
// https://github.com/vuejs/test-utils/issues/1829 & https://github.com/vuejs/test-utils/issues/1888
// Teleport/KeepAlive should return child nodes as a function
if (isTeleport(originalType) || isKeepAlive(originalType)) {
Expand All @@ -50,8 +77,6 @@ export const createVNodeTransformer = ({
return [cachedTransformation, props, children, ...restVNodeArgs]
}

const componentType: VNodeTransformerInputComponentType = originalType

const transformedType = transformers.reduce(
(type, transformer) => transformer(type, instance),
componentType
Expand Down

0 comments on commit 8ae1ddd

Please sign in to comment.