@@ -125,6 +125,105 @@ describe('Selectors', () => {
125
125
} ) ;
126
126
} ) ;
127
127
128
+ describe ( 'createSelector with props' , ( ) => {
129
+ it ( 'should deliver the value of selectors to the projection function' , ( ) => {
130
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
131
+
132
+ const selector = createSelector (
133
+ incrementOne ,
134
+ incrementTwo ,
135
+ ( state : any , props : any ) => props . value ,
136
+ projectFn
137
+ ) ;
138
+
139
+ selector ( { } , { value : 47 } ) ;
140
+ expect ( projectFn ) . toHaveBeenCalledWith ( countOne , countTwo , 47 ) ;
141
+ } ) ;
142
+
143
+ it ( 'should be possible to test a projector fn independent from the selectors it is composed of' , ( ) => {
144
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
145
+ const selector = createSelector (
146
+ incrementOne ,
147
+ incrementTwo ,
148
+ ( state : any , props : any ) => {
149
+ fail ( `Shouldn't be called` ) ;
150
+ return props . value ;
151
+ } ,
152
+ projectFn
153
+ ) ;
154
+ selector . projector ( '' , '' , 47 ) ;
155
+
156
+ expect ( incrementOne ) . not . toHaveBeenCalled ( ) ;
157
+ expect ( incrementTwo ) . not . toHaveBeenCalled ( ) ;
158
+ expect ( projectFn ) . toHaveBeenCalledWith ( '' , '' , 47 ) ;
159
+ } ) ;
160
+
161
+ it ( 'should call the projector function when the state changes' , ( ) => {
162
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
163
+ const selector = createSelector (
164
+ incrementOne ,
165
+ ( state : any , props : any ) => props . value ,
166
+ projectFn
167
+ ) ;
168
+
169
+ const firstSate = { first : 'state' } ;
170
+ const props = { foo : 'props' } ;
171
+ selector ( firstSate , props ) ;
172
+ selector ( firstSate , props ) ;
173
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 1 ) ;
174
+
175
+ const secondState = { second : 'state' } ;
176
+ selector ( secondState , props ) ;
177
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 2 ) ;
178
+ } ) ;
179
+
180
+ it ( 'should memoize the function' , ( ) => {
181
+ let counter = 0 ;
182
+
183
+ const firstState = { first : 'state' } ;
184
+ const secondState = { second : 'state' } ;
185
+ const props = { foo : 'props' } ;
186
+
187
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
188
+ const selector = createSelector (
189
+ incrementOne ,
190
+ incrementTwo ,
191
+ ( state : any , props : any ) => {
192
+ counter ++ ;
193
+ return props ;
194
+ } ,
195
+ projectFn
196
+ ) ;
197
+
198
+ selector ( firstState , props ) ;
199
+ selector ( firstState , props ) ;
200
+ selector ( firstState , props ) ;
201
+ selector ( secondState , props ) ;
202
+
203
+ expect ( counter ) . toBe ( 2 ) ;
204
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 2 ) ;
205
+ } ) ;
206
+
207
+ it ( 'should allow you to release memoized arguments' , ( ) => {
208
+ const state = { first : 'state' } ;
209
+ const props = { foo : 'props' } ;
210
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
211
+ const selector = createSelector (
212
+ incrementOne ,
213
+ ( state : any , props : any ) => props ,
214
+ projectFn
215
+ ) ;
216
+
217
+ selector ( state , props ) ;
218
+ selector ( state , props ) ;
219
+ selector . release ( ) ;
220
+ selector ( state , props ) ;
221
+ selector ( state , props ) ;
222
+
223
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 2 ) ;
224
+ } ) ;
225
+ } ) ;
226
+
128
227
describe ( 'createSelector with arrays' , ( ) => {
129
228
it ( 'should deliver the value of selectors to the projection function' , ( ) => {
130
229
const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
@@ -211,6 +310,104 @@ describe('Selectors', () => {
211
310
} ) ;
212
311
} ) ;
213
312
313
+ describe ( 'createSelector with arrays and props' , ( ) => {
314
+ it ( 'should deliver the value of selectors to the projection function' , ( ) => {
315
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
316
+ const selector = createSelector (
317
+ [ incrementOne , incrementTwo , ( state : any , props : any ) => props . value ] ,
318
+ projectFn
319
+ ) ( { } , { value : 47 } ) ;
320
+
321
+ expect ( projectFn ) . toHaveBeenCalledWith ( countOne , countTwo , 47 ) ;
322
+ } ) ;
323
+
324
+ it ( 'should be possible to test a projector fn independent from the selectors it is composed of' , ( ) => {
325
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
326
+ const selector = createSelector (
327
+ [
328
+ incrementOne ,
329
+ incrementTwo ,
330
+ ( state : any , props : any ) => {
331
+ fail ( `Shouldn't be called` ) ;
332
+ return props . value ;
333
+ } ,
334
+ ] ,
335
+ projectFn
336
+ ) ;
337
+
338
+ selector . projector ( '' , '' , 47 ) ;
339
+
340
+ expect ( incrementOne ) . not . toHaveBeenCalled ( ) ;
341
+ expect ( incrementTwo ) . not . toHaveBeenCalled ( ) ;
342
+ expect ( projectFn ) . toHaveBeenCalledWith ( '' , '' , 47 ) ;
343
+ } ) ;
344
+
345
+ it ( 'should call the projector function when the state changes' , ( ) => {
346
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
347
+ const selector = createSelector (
348
+ [ incrementOne , ( state : any , props : any ) => props . value ] ,
349
+ projectFn
350
+ ) ;
351
+
352
+ const firstSate = { first : 'state' } ;
353
+ const props = { foo : 'props' } ;
354
+ selector ( firstSate , props ) ;
355
+ selector ( firstSate , props ) ;
356
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 1 ) ;
357
+
358
+ const secondState = { second : 'state' } ;
359
+ selector ( secondState , props ) ;
360
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 2 ) ;
361
+ } ) ;
362
+
363
+ it ( 'should memoize the function' , ( ) => {
364
+ let counter = 0 ;
365
+
366
+ const firstState = { first : 'state' } ;
367
+ const secondState = { second : 'state' } ;
368
+ const props = { foo : 'props' } ;
369
+
370
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
371
+ const selector = createSelector (
372
+ [
373
+ incrementOne ,
374
+ incrementTwo ,
375
+ ( state : any , props : any ) => {
376
+ counter ++ ;
377
+ return props ;
378
+ } ,
379
+ ] ,
380
+ projectFn
381
+ ) ;
382
+
383
+ selector ( firstState , props ) ;
384
+ selector ( firstState , props ) ;
385
+ selector ( firstState , props ) ;
386
+ selector ( secondState , props ) ;
387
+
388
+ expect ( counter ) . toBe ( 2 ) ;
389
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 2 ) ;
390
+ } ) ;
391
+
392
+ it ( 'should allow you to release memoized arguments' , ( ) => {
393
+ const state = { first : 'state' } ;
394
+ const props = { foo : 'props' } ;
395
+ const projectFn = jasmine . createSpy ( 'projectionFn' ) ;
396
+ const selector = createSelector (
397
+ [ incrementOne , ( state : any , props : any ) => props ] ,
398
+ projectFn
399
+ ) ;
400
+
401
+ selector ( state , props ) ;
402
+ selector ( state , props ) ;
403
+ selector . release ( ) ;
404
+ selector ( state , props ) ;
405
+ selector ( state , props ) ;
406
+
407
+ expect ( projectFn ) . toHaveBeenCalledTimes ( 2 ) ;
408
+ } ) ;
409
+ } ) ;
410
+
214
411
describe ( 'createFeatureSelector' , ( ) => {
215
412
let featureName = '@ngrx/router-store' ;
216
413
let featureSelector : ( state : any ) => number ;
0 commit comments