@@ -144,6 +144,79 @@ describe( 'Observable', () => {
144144 sinon . assert . notCalled ( spyColor ) ;
145145 } ) ;
146146
147+ it ( 'should fire the "beforeChange" event' , ( ) => {
148+ const spy = sinon . spy ( ) ;
149+ const spyColor = sinon . spy ( ) ;
150+ const spyYear = sinon . spy ( ) ;
151+ const spyWheels = sinon . spy ( ) ;
152+
153+ car . on ( 'beforeChange' , spy ) ;
154+ car . on ( 'beforeChange:color' , spyColor ) ;
155+ car . on ( 'beforeChange:year' , spyYear ) ;
156+ car . on ( 'beforeChange:wheels' , spyWheels ) ;
157+
158+ // Set property in all possible ways.
159+ car . color = 'blue' ;
160+ car . set ( { year : 2003 } ) ;
161+ car . set ( 'wheels' , 4 ) ;
162+
163+ // Check number of calls.
164+ sinon . assert . calledThrice ( spy ) ;
165+ sinon . assert . calledOnce ( spyColor ) ;
166+ sinon . assert . calledOnce ( spyYear ) ;
167+ sinon . assert . calledOnce ( spyWheels ) ;
168+
169+ // Check context.
170+ sinon . assert . alwaysCalledOn ( spy , car ) ;
171+ sinon . assert . calledOn ( spyColor , car ) ;
172+ sinon . assert . calledOn ( spyYear , car ) ;
173+ sinon . assert . calledOn ( spyWheels , car ) ;
174+
175+ // Check params.
176+ sinon . assert . calledWithExactly ( spy , sinon . match . instanceOf ( EventInfo ) , 'color' , 'blue' , 'red' ) ;
177+ sinon . assert . calledWithExactly ( spy , sinon . match . instanceOf ( EventInfo ) , 'year' , 2003 , 2015 ) ;
178+ sinon . assert . calledWithExactly ( spy , sinon . match . instanceOf ( EventInfo ) , 'wheels' , 4 , sinon . match . typeOf ( 'undefined' ) ) ;
179+ sinon . assert . calledWithExactly ( spyColor , sinon . match . instanceOf ( EventInfo ) , 'color' , 'blue' , 'red' ) ;
180+ sinon . assert . calledWithExactly ( spyYear , sinon . match . instanceOf ( EventInfo ) , 'year' , 2003 , 2015 ) ;
181+ sinon . assert . calledWithExactly (
182+ spyWheels , sinon . match . instanceOf ( EventInfo ) ,
183+ 'wheels' , 4 , sinon . match . typeOf ( 'undefined' )
184+ ) ;
185+ } ) ;
186+
187+ it ( 'should use "beforeChange" return value as an observable new value' , ( ) => {
188+ car . color = 'blue' ;
189+
190+ const spy = sinon . spy ( ) ;
191+
192+ car . on ( 'beforeChange:color' , evt => {
193+ evt . stop ( ) ;
194+ evt . return = 'red' ;
195+ } , { priority : 'high' } ) ;
196+
197+ car . on ( 'change:color' , spy ) ;
198+
199+ car . color = 'pink' ;
200+
201+ sinon . assert . calledWithExactly ( spy , sinon . match . instanceOf ( EventInfo ) , 'color' , 'red' , 'blue' ) ;
202+ } ) ;
203+
204+ it ( 'should not fire the "beforeChange" event for the same property value' , ( ) => {
205+ const spy = sinon . spy ( ) ;
206+ const spyColor = sinon . spy ( ) ;
207+
208+ car . on ( 'beforeChange' , spy ) ;
209+ car . on ( 'beforeChange:color' , spyColor ) ;
210+
211+ // Set the "color" property in all possible ways.
212+ car . color = 'red' ;
213+ car . set ( 'color' , 'red' ) ;
214+ car . set ( { color : 'red' } ) ;
215+
216+ sinon . assert . notCalled ( spy ) ;
217+ sinon . assert . notCalled ( spyColor ) ;
218+ } ) ;
219+
147220 it ( 'should throw when overriding already existing property' , ( ) => {
148221 car . normalProperty = 1 ;
149222
0 commit comments