@@ -23,6 +23,13 @@ type Constructors<T> = {
2323let getDescriptor = ( obj : any , method : string | symbol | number ) =>
2424 Object . getOwnPropertyDescriptor ( obj , method )
2525
26+ let prototype = ( fn : any , val : any ) => {
27+ if ( val != null && typeof val === 'function' && val . prototype != null ) {
28+ // inherit prototype, keep original prototype chain
29+ Object . setPrototypeOf ( fn . prototype , val . prototype )
30+ }
31+ }
32+
2633export function internalSpyOn < T , K extends string & keyof T > (
2734 obj : T ,
2835 methodName : K | { getter : K } | { setter : K } ,
@@ -38,7 +45,10 @@ export function internalSpyOn<T, K extends string & keyof T>(
3845 'cannot spyOn on a primitive value'
3946 )
4047
41- let getMeta = ( ) : [ string | symbol | number , 'value' | 'get' | 'set' ] => {
48+ let [ accessName , accessType ] = ( ( ) : [
49+ string | symbol | number ,
50+ 'value' | 'get' | 'set'
51+ ] => {
4252 if ( ! isType ( 'object' , methodName ) ) {
4353 return [ methodName , 'value' ]
4454 }
@@ -52,9 +62,7 @@ export function internalSpyOn<T, K extends string & keyof T>(
5262 return [ methodName . setter , 'set' ]
5363 }
5464 throw new Error ( 'specify getter or setter to spy on' )
55- }
56-
57- let [ accessName , accessType ] = getMeta ( )
65+ } ) ( )
5866 let objDescriptor = getDescriptor ( obj , accessName )
5967 let proto = Object . getPrototypeOf ( obj )
6068 let protoDescriptor = proto && getDescriptor ( proto , accessName )
@@ -92,6 +100,9 @@ export function internalSpyOn<T, K extends string & keyof T>(
92100 if ( ! mock ) mock = origin
93101
94102 let fn = createInternalSpy ( mock )
103+ if ( accessType === 'value' ) {
104+ prototype ( fn , origin )
105+ }
95106 let reassign = ( cb : any ) => {
96107 let { value, ...desc } = originalDescriptor || {
97108 configurable : true ,
@@ -103,9 +114,10 @@ export function internalSpyOn<T, K extends string & keyof T>(
103114 ; ( desc as PropertyDescriptor ) [ accessType ] = cb
104115 define ( obj , accessName , desc )
105116 }
106- let restore = ( ) => originalDescriptor
107- ? define ( obj , accessName , originalDescriptor )
108- : reassign ( origin )
117+ let restore = ( ) =>
118+ originalDescriptor
119+ ? define ( obj , accessName , originalDescriptor )
120+ : reassign ( origin )
109121 const state = fn [ S ]
110122 defineValue ( state , 'restore' , restore )
111123 defineValue ( state , 'getOriginal' , ( ) => ( ssr ? origin ( ) : origin ) )
@@ -114,7 +126,14 @@ export function internalSpyOn<T, K extends string & keyof T>(
114126 return fn
115127 } )
116128
117- reassign ( ssr ? ( ) => fn : fn )
129+ reassign (
130+ ssr
131+ ? ( ) => {
132+ prototype ( fn , mock )
133+ return fn
134+ }
135+ : fn
136+ )
118137
119138 spies . add ( fn as any )
120139 return fn as any
0 commit comments