@@ -77,6 +77,126 @@ describe('utils', function() {
7777 expect ( desc ! . writable ) . toBeTruthy ( ) ;
7878 expect ( ! desc ! . get ) . toBeTruthy ( ) ;
7979 } ) ;
80+
81+ it ( 'should patch target if it overrides a patched method' , ( ) => {
82+ let args : any [ ] | undefined ;
83+ let childArgs : any [ ] | undefined ;
84+ let self : any ;
85+ let childSelf : any ;
86+ class Type {
87+ method ( ..._args : any [ ] ) {
88+ args = _args ;
89+ self = this ;
90+ return 'OK' ;
91+ }
92+ }
93+ class ChildType extends Type {
94+ method ( ..._args : any [ ] ) {
95+ childArgs = _args ;
96+ childSelf = this ;
97+ return 'ChildOK' ;
98+ }
99+ }
100+
101+ const method = Type . prototype . method ;
102+ const childMethod = ChildType . prototype . method ;
103+ let delegateMethod : Function ;
104+ let delegateSymbol : string ;
105+ let childDelegateMethod : Function ;
106+ let childDelegateSymbol : string ;
107+
108+ const typeInstance = new Type ( ) ;
109+ const childTypeInstance = new ChildType ( ) ;
110+ expect ( patchMethod (
111+ Type . prototype , 'method' ,
112+ ( delegate : Function , symbol : string , name : string ) => {
113+ expect ( name ) . toEqual ( 'method' ) ;
114+ delegateMethod = delegate ;
115+ delegateSymbol = symbol ;
116+ return function ( self , args ) {
117+ return delegate . apply ( self , [ 'patch' , args [ 0 ] ] ) ;
118+ } ;
119+ } ) )
120+ . toBe ( delegateMethod ! ) ;
121+
122+ expect ( patchMethod (
123+ ChildType . prototype , 'method' ,
124+ ( delegate : Function , symbol : string , name : string ) => {
125+ expect ( name ) . toEqual ( 'method' ) ;
126+ childDelegateMethod = delegate ;
127+ childDelegateSymbol = symbol ;
128+ return function ( self , args ) {
129+ return delegate . apply ( self , [ 'child patch' , args [ 0 ] ] ) ;
130+ } ;
131+ } ) )
132+ . toBe ( childDelegateMethod ! ) ;
133+
134+ expect ( typeInstance . method ( 'a0' ) ) . toEqual ( 'OK' ) ;
135+ expect ( childTypeInstance . method ( 'a0' ) ) . toEqual ( 'ChildOK' ) ;
136+ expect ( args ) . toEqual ( [ 'patch' , 'a0' ] ) ;
137+ expect ( childArgs ) . toEqual ( [ 'child patch' , 'a0' ] ) ;
138+ expect ( self ) . toBe ( typeInstance ) ;
139+ expect ( childSelf ) . toBe ( childTypeInstance ) ;
140+ expect ( delegateMethod ! ) . toBe ( method ) ;
141+ expect ( childDelegateMethod ! ) . toBe ( childMethod ) ;
142+ expect ( delegateSymbol ! ) . toEqual ( zoneSymbol ( 'method' ) ) ;
143+ expect ( childDelegateSymbol ! ) . toEqual ( zoneSymbol ( 'method' ) ) ;
144+ expect ( ( Type . prototype as any ) [ delegateSymbol ! ] ) . toBe ( method ) ;
145+ expect ( ( ChildType . prototype as any ) [ delegateSymbol ! ] ) . toBe ( childMethod ) ;
146+ } ) ;
147+
148+ it ( 'should not patch target if does not override a patched method' , ( ) => {
149+ let args : any [ ] | undefined ;
150+ let self : any ;
151+ class Type {
152+ method ( ..._args : any [ ] ) {
153+ args = _args ;
154+ self = this ;
155+ return 'OK' ;
156+ }
157+ }
158+ class ChildType extends Type { }
159+ const method = Type . prototype . method ;
160+ let delegateMethod : Function ;
161+ let delegateSymbol : string ;
162+ let childPatched = false ;
163+
164+ const typeInstance = new Type ( ) ;
165+ const childTypeInstance = new ChildType ( ) ;
166+ expect ( patchMethod (
167+ Type . prototype , 'method' ,
168+ ( delegate : Function , symbol : string , name : string ) => {
169+ expect ( name ) . toEqual ( 'method' ) ;
170+ delegateMethod = delegate ;
171+ delegateSymbol = symbol ;
172+ return function ( self , args ) {
173+ return delegate . apply ( self , [ 'patch' , args [ 0 ] ] ) ;
174+ } ;
175+ } ) )
176+ . toBe ( delegateMethod ! ) ;
177+
178+ expect ( patchMethod (
179+ ChildType . prototype , 'method' ,
180+ ( delegate : Function , symbol : string , name : string ) => {
181+ childPatched = true ;
182+ return function ( self , args ) {
183+ return delegate . apply ( self , [ 'child patch' , args [ 0 ] ] ) ;
184+ } ;
185+ } ) )
186+ . toBe ( delegateMethod ! ) ;
187+
188+ expect ( childPatched ) . toBe ( false ) ;
189+ expect ( typeInstance . method ( 'a0' ) ) . toEqual ( 'OK' ) ;
190+ expect ( args ) . toEqual ( [ 'patch' , 'a0' ] ) ;
191+ expect ( self ) . toBe ( typeInstance ) ;
192+ expect ( delegateMethod ! ) . toBe ( method ) ;
193+ expect ( delegateSymbol ! ) . toEqual ( zoneSymbol ( 'method' ) ) ;
194+ expect ( ( Type . prototype as any ) [ delegateSymbol ! ] ) . toBe ( method ) ;
195+ expect ( childTypeInstance . method ( 'a0' ) ) . toEqual ( 'OK' ) ;
196+ expect ( args ) . toEqual ( [ 'patch' , 'a0' ] ) ;
197+ expect ( self ) . toBe ( childTypeInstance ) ;
198+ expect ( ( ChildType . prototype as any ) [ delegateSymbol ! ] ) . toBe ( method ) ;
199+ } ) ;
80200 } ) ;
81201
82202 describe ( 'patchPrototype' , ( ) => {
0 commit comments