1+ import { inspect } from 'util'
12import { ContextState } from "./states/ContextState" ;
23import { InitialState } from "./states/InitialState" ;
34import { HandlerKey } from "./Substitute" ;
45import { Type } from "./Utilities" ;
56import { SetPropertyState } from "./states/SetPropertyState" ;
6-
7- class SubstituteJS { }
7+ import { SubstituteJS as SubstituteBase , SubstituteException } from './SubstituteBase'
88
99export class Context {
1010 private _initialState : InitialState ;
@@ -19,24 +19,22 @@ export class Context {
1919
2020 constructor ( ) {
2121 this . _initialState = new InitialState ( ) ;
22- this . _setState = this . _initialState
22+ this . _setState = this . _initialState ;
2323 this . _getState = this . _initialState ;
2424
25- this . _proxy = new Proxy ( SubstituteJS , {
25+ this . _proxy = new Proxy ( SubstituteBase , {
2626 apply : ( _target , _this , args ) => this . apply ( _target , _this , args ) ,
2727 set : ( _target , property , value ) => ( this . set ( _target , property , value ) , true ) ,
28- get : ( _target , property ) => this . get ( _target , property ) ,
29- getOwnPropertyDescriptor : ( obj , prop ) => prop === 'constructor' ?
30- { value : obj , configurable : true } : Reflect . getOwnPropertyDescriptor ( obj , prop )
28+ get : ( _target , property ) => this . _filterAndReturnProperty ( _target , property , this . get )
3129 } ) ;
3230
33- this . _rootProxy = new Proxy ( SubstituteJS , {
31+ this . _rootProxy = new Proxy ( SubstituteBase , {
3432 apply : ( _target , _this , args ) => this . initialState . apply ( this , args ) ,
3533 set : ( _target , property , value ) => ( this . initialState . set ( this , property , value ) , true ) ,
36- get : ( _target , property ) => this . initialState . get ( this , property )
34+ get : ( _target , property ) => this . _filterAndReturnProperty ( _target , property , this . rootGet )
3735 } ) ;
3836
39- this . _receivedProxy = new Proxy ( SubstituteJS , {
37+ this . _receivedProxy = new Proxy ( SubstituteBase , {
4038 apply : ( _target , _this , args ) => this . _receivedState === void 0 ? void 0 : this . _receivedState . apply ( this , args ) ,
4139 set : ( _target , property , value ) => ( this . set ( _target , property , value ) , true ) ,
4240 get : ( _target , property ) => {
@@ -50,12 +48,40 @@ export class Context {
5048 } ) ;
5149 }
5250
51+ private _filterAndReturnProperty ( target : typeof SubstituteBase , property : PropertyKey , defaultGet : Context [ 'get' ] ) {
52+ switch ( property ) {
53+ case 'constructor' :
54+ case 'valueOf' :
55+ case '$$typeof' :
56+ case 'length' :
57+ case 'toString' :
58+ case 'inspect' :
59+ case 'lastRegisteredSubstituteJSMethodOrProperty' :
60+ return target . prototype [ property ] ;
61+ case Symbol . toPrimitive :
62+ return target . prototype [ Symbol . toPrimitive ] ;
63+ case inspect . custom :
64+ return target . prototype [ inspect . custom ] ;
65+ case Symbol . iterator :
66+ return target . prototype [ Symbol . iterator ] ;
67+ case Symbol . toStringTag :
68+ return target . prototype [ Symbol . toStringTag ] ;
69+ default :
70+ target . prototype . lastRegisteredSubstituteJSMethodOrProperty = property . toString ( )
71+ return defaultGet . bind ( this ) ( target , property ) ;
72+ }
73+ }
74+
5375 private handleNotFoundState ( property : PropertyKey ) {
5476 if ( this . initialState . hasExpectations && this . initialState . expectedCount !== null ) {
5577 this . initialState . assertCallCountMatchesExpectations ( [ ] , 0 , Type . property , property , [ ] ) ;
5678 return this . receivedProxy ;
5779 }
58- throw new Error ( `there is no mock for property: ${ String ( property ) } ` ) ;
80+ throw SubstituteException . forPropertyNotMocked ( property ) ;
81+ }
82+
83+ rootGet ( _target : any , property : PropertyKey ) {
84+ return this . initialState . get ( this , property ) ;
5985 }
6086
6187 apply ( _target : any , _this : any , args : any [ ] ) {
0 commit comments