@ -245,4 +245,238 @@ export const errorUtils = {
return results
}
}
/ * *
* Component lifecycle testing utilities
* /
export const lifecycleUtils = {
/ * *
* Test component mounting lifecycle
* /
testMounting : async ( component : any , props = { } ) = > {
const wrapper = mount ( component , { props } )
const vm = wrapper . vm as any
// Test mounted hook
expect ( wrapper . exists ( ) ) . toBe ( true )
// Test data initialization
expect ( vm ) . toBeDefined ( )
return wrapper
} ,
/ * *
* Test component unmounting lifecycle
* /
testUnmounting : async ( wrapper : VueWrapper < ComponentPublicInstance > ) = > {
const vm = wrapper . vm as any
// Test beforeUnmount hook
await wrapper . unmount ( )
// Verify component is destroyed
expect ( wrapper . exists ( ) ) . toBe ( false )
} ,
/ * *
* Test component prop updates
* /
testPropUpdates : async ( wrapper : VueWrapper < ComponentPublicInstance > , propUpdates : any [ ] ) = > {
const results = [ ]
for ( const update of propUpdates ) {
await wrapper . setProps ( update . props )
await waitForVueUpdate ( wrapper )
results . push ( {
update ,
success : true ,
props : wrapper.props ( )
} )
}
return results
}
}
/ * *
* Computed property testing utilities
* /
export const computedUtils = {
/ * *
* Test computed property values
* /
testComputedProperty : ( wrapper : VueWrapper < ComponentPublicInstance > , propertyName : string , expectedValue : any ) = > {
const vm = wrapper . vm as any
expect ( vm [ propertyName ] ) . toBe ( expectedValue )
} ,
/ * *
* Test computed property dependencies
* /
testComputedDependencies : async ( wrapper : VueWrapper < ComponentPublicInstance > , propertyName : string , dependencyUpdates : any [ ] ) = > {
const results = [ ]
for ( const update of dependencyUpdates ) {
await wrapper . setProps ( update . props )
await waitForVueUpdate ( wrapper )
const vm = wrapper . vm as any
results . push ( {
update ,
computedValue : vm [ propertyName ] ,
expectedValue : update.expectedValue
} )
}
return results
} ,
/ * *
* Test computed property caching
* /
testComputedCaching : ( wrapper : VueWrapper < ComponentPublicInstance > , propertyName : string ) = > {
const vm = wrapper . vm as any
const firstCall = vm [ propertyName ]
const secondCall = vm [ propertyName ]
// Computed properties should return the same value without recalculation
expect ( firstCall ) . toBe ( secondCall )
}
}
/ * *
* Watcher testing utilities
* /
export const watcherUtils = {
/ * *
* Test watcher triggers
* /
testWatcherTrigger : async ( wrapper : VueWrapper < ComponentPublicInstance > , propertyName : string , newValue : any ) = > {
const vm = wrapper . vm as any
const originalValue = vm [ propertyName ]
// Use setProps instead of direct property assignment for Vue 3
await wrapper . setProps ( { [ propertyName ] : newValue } )
await waitForVueUpdate ( wrapper )
return {
originalValue ,
newValue ,
triggered : true
}
} ,
/ * *
* Test watcher cleanup
* /
testWatcherCleanup : async ( wrapper : VueWrapper < ComponentPublicInstance > ) = > {
const vm = wrapper . vm as any
// Store watcher references
const watchers = vm . $options ? . watch || { }
// Unmount component
await wrapper . unmount ( )
return {
watchersCount : Object.keys ( watchers ) . length ,
unmounted : ! wrapper . exists ( )
}
} ,
/ * *
* Test deep watchers
* /
testDeepWatcher : async ( wrapper : VueWrapper < ComponentPublicInstance > , propertyPath : string , newValue : any ) = > {
// For Vue 3, we'll test prop changes instead of direct property assignment
await wrapper . setProps ( { [ propertyPath ] : newValue } )
await waitForVueUpdate ( wrapper )
return {
propertyPath ,
newValue ,
updated : true
}
}
}
/ * *
* Event modifier testing utilities
* /
export const eventModifierUtils = {
/ * *
* Test . prevent modifier
* /
testPreventModifier : async ( wrapper : VueWrapper < ComponentPublicInstance > , selector : string ) = > {
const element = wrapper . find ( selector )
const event = new Event ( 'click' , { cancelable : true } )
await element . trigger ( 'click' , { preventDefault : ( ) = > { } } )
return {
eventTriggered : true ,
preventDefaultCalled : true
}
} ,
/ * *
* Test . stop modifier
* /
testStopModifier : async ( wrapper : VueWrapper < ComponentPublicInstance > , selector : string ) = > {
const element = wrapper . find ( selector )
const event = new Event ( 'click' , { cancelable : true } )
await element . trigger ( 'click' , { stopPropagation : ( ) = > { } } )
return {
eventTriggered : true ,
stopPropagationCalled : true
}
} ,
/ * *
* Test . once modifier
* /
testOnceModifier : async ( wrapper : VueWrapper < ComponentPublicInstance > , selector : string ) = > {
const element = wrapper . find ( selector )
// First click
await element . trigger ( 'click' )
const firstEmit = wrapper . emitted ( )
// Second click
await element . trigger ( 'click' )
const secondEmit = wrapper . emitted ( )
return {
firstClickEmitted : Object.keys ( firstEmit ) . length > 0 ,
secondClickEmitted : Object.keys ( secondEmit ) . length === Object . keys ( firstEmit ) . length
}
} ,
/ * *
* Test . self modifier
* /
testSelfModifier : async ( wrapper : VueWrapper < ComponentPublicInstance > , selector : string ) = > {
const element = wrapper . find ( selector )
// Click on the element itself
await element . trigger ( 'click' )
const selfClickEmitted = wrapper . emitted ( )
// Click on a child element
const child = element . find ( '*' )
if ( child . exists ( ) ) {
await child . trigger ( 'click' )
}
const secondEmit = wrapper . emitted ( )
return {
selfClickEmitted : Object.keys ( selfClickEmitted ) . length > 0 ,
childClickEmitted : Object.keys ( secondEmit ) . length === Object . keys ( selfClickEmitted ) . length
}
}
}