1
1
import { Component , Type , Injectable } from '@angular/core' ;
2
2
import { ComponentStore } from '../src' ;
3
- import { TestBed , ComponentFixture } from '@angular/core/testing' ;
3
+ import {
4
+ TestBed ,
5
+ ComponentFixture ,
6
+ flushMicrotasks ,
7
+ fakeAsync ,
8
+ tick ,
9
+ } from '@angular/core/testing' ;
4
10
import { CommonModule } from '@angular/common' ;
5
11
import { interval , Observable } from 'rxjs' ;
6
- import { fakeSchedulers } from 'rxjs-marbles/jest' ;
7
12
import { tap } from 'rxjs/operators' ;
8
13
import { By } from '@angular/platform-browser' ;
9
14
10
15
describe ( 'ComponentStore integration' , ( ) => {
11
- jest . useFakeTimers ( ) ;
12
-
13
16
// The same set of tests is run against different versions of how
14
17
// ComponentStore may be used - making sure all of them work.
15
18
function testWith ( setup : ( ) => Promise < SetupData < Child > > ) {
16
- it ( 'does not emit until state is initialized' , async ( ) => {
17
- const state = await setup ( ) ;
19
+ let state : SetupData < Child > ;
20
+ beforeEach ( async ( ) => {
21
+ state = await setup ( ) ;
22
+ } ) ;
18
23
24
+ it ( 'does not emit until state is initialized' , fakeAsync ( ( ) => {
19
25
expect ( state . parent . isChildVisible ) . toBe ( true ) ;
20
26
expect ( state . hasChild ( ) ) . toBe ( true ) ;
21
27
22
28
state . fixture . detectChanges ( ) ;
29
+ flushMicrotasks ( ) ;
30
+
23
31
// No values emitted, 👇 no initial state
24
32
expect ( state . propChanges ) . toEqual ( [ ] ) ;
25
33
expect ( state . prop2Changes ) . toEqual ( [ ] ) ;
26
- } ) ;
27
-
28
- it ( 'gets initial value when state is initialized' , async ( ) => {
29
- const state = await setup ( ) ;
34
+ } ) ) ;
30
35
36
+ it ( 'gets initial value when state is initialized' , fakeAsync ( ( ) => {
31
37
state . child . init ( ) ;
38
+ flushMicrotasks ( ) ;
32
39
// init state👇
33
40
expect ( state . propChanges ) . toEqual ( [ 'initial Value' ] ) ;
34
41
expect ( state . prop2Changes ) . toEqual ( [ undefined ] ) ;
35
- } ) ;
36
42
37
- it (
38
- 'effect updates values' ,
39
- fakeSchedulers ( async ( advance ) => {
40
- const state = await setup ( ) ;
43
+ // clear "Periodic timers in queue"
44
+ state . destroy ( ) ;
45
+ } ) ) ;
41
46
42
- state . child . init ( ) ;
43
-
44
- advance ( 40 ) ;
45
- // New value pushed every 10 ms.
46
- expect ( state . prop2Changes ) . toEqual ( [ undefined , 0 , 1 , 2 , 3 ] ) ;
47
- } )
48
- ) ;
47
+ it ( 'effect updates values' , fakeAsync ( ( ) => {
48
+ state . child . init ( ) ;
49
49
50
- it ( 'updates values imperatively' , async ( ) => {
51
- const state = await setup ( ) ;
50
+ tick ( 40 ) ;
51
+ // New value pushed every 10 ms.
52
+ expect ( state . prop2Changes ) . toEqual ( [ undefined , 0 , 1 , 2 , 3 ] ) ;
52
53
53
- state . child . init ( ) ;
54
+ // clear "Periodic timers in queue"
55
+ state . destroy ( ) ;
56
+ } ) ) ;
54
57
55
- state . child . updateProp ( 'new value' ) ;
56
- state . child . updateProp ( 'yay!!!' ) ;
58
+ it ( 'updates values imperatively' , fakeAsync ( ( ) => {
59
+ state ! . child . init ( ) ;
57
60
58
- expect ( state . propChanges ) . toContain ( 'new value' ) ;
59
- expect ( state . propChanges ) . toContain ( 'yay!!!' ) ;
60
- } ) ;
61
+ state ! . child . updateProp ( 'new value' ) ;
62
+ flushMicrotasks ( ) ;
63
+ state ! . child . updateProp ( 'yay!!!' ) ;
64
+ flushMicrotasks ( ) ;
61
65
62
- it (
63
- 'stops observables when destroyed' ,
64
- fakeSchedulers ( async ( advance ) => {
65
- const state = await setup ( ) ;
66
+ expect ( state ! . propChanges ) . toContain ( 'new value' ) ;
67
+ expect ( state ! . propChanges ) . toContain ( 'yay!!!' ) ;
66
68
67
- state . child . init ( ) ;
69
+ // clear "Periodic timers in queue"
70
+ state . destroy ( ) ;
71
+ } ) ) ;
68
72
69
- advance ( 40 ) ;
70
- // New value pushed every 10 ms.
71
- expect ( state . prop2Changes ) . toEqual ( [ undefined , 0 , 1 , 2 , 3 ] ) ;
73
+ it ( 'stops observables when destroyed' , fakeAsync ( ( ) => {
74
+ state . child . init ( ) ;
72
75
73
- state . parent . isChildVisible = false ;
74
- state . fixture . detectChanges ( ) ;
76
+ tick ( 40 ) ;
77
+ // New value pushed every 10 ms.
78
+ expect ( state . prop2Changes ) . toEqual ( [ undefined , 0 , 1 , 2 , 3 ] ) ;
75
79
76
- advance ( 20 ) ;
77
- // Still at the same values, so effect stopped running
78
- expect ( state . prop2Changes ) . toEqual ( [ undefined , 0 , 1 , 2 , 3 ] ) ;
79
- } )
80
- ) ;
80
+ state . parent . isChildVisible = false ;
81
+ state . fixture . detectChanges ( ) ;
81
82
82
- it ( 'ComponentStore is destroyed' , async ( ) => {
83
- const state = await setup ( ) ;
83
+ tick ( 20 ) ;
84
+ // Still at the same values, so effect stopped running
85
+ expect ( state . prop2Changes ) . toEqual ( [ undefined , 0 , 1 , 2 , 3 ] ) ;
86
+ } ) ) ;
84
87
88
+ it ( 'ComponentStore is destroyed' , ( ) => {
85
89
state . child . init ( ) ;
86
90
87
91
state . parent . isChildVisible = false ;
@@ -130,6 +134,7 @@ describe('ComponentStore integration', () => {
130
134
hasChild : ( ) => boolean ;
131
135
propChanges : string [ ] ;
132
136
prop2Changes : Array < number | undefined > ;
137
+ destroy : ( ) => void ;
133
138
componentStoreDestroySpy : jest . SpyInstance ;
134
139
}
135
140
@@ -143,7 +148,7 @@ describe('ComponentStore integration', () => {
143
148
144
149
async function setupTestBed < T extends Child > (
145
150
childClass : Type < T >
146
- ) : Promise < Omit < SetupData < T > , 'componentStoreDestroySpy' > > {
151
+ ) : Promise < Omit < SetupData < T > , 'componentStoreDestroySpy' | 'destroy' > > {
147
152
await TestBed . configureTestingModule ( {
148
153
declarations : [ ParentComponent , childClass ] ,
149
154
imports : [ CommonModule ] ,
@@ -218,6 +223,7 @@ describe('ComponentStore integration', () => {
218
223
) ;
219
224
return {
220
225
...setup ,
226
+ destroy : ( ) => setup . child . componentStore . ngOnDestroy ( ) ,
221
227
componentStoreDestroySpy,
222
228
} ;
223
229
}
@@ -257,6 +263,7 @@ describe('ComponentStore integration', () => {
257
263
const componentStoreDestroySpy = jest . spyOn ( setup . child , 'ngOnDestroy' ) ;
258
264
return {
259
265
...setup ,
266
+ destroy : ( ) => setup . child . ngOnDestroy ( ) ,
260
267
componentStoreDestroySpy,
261
268
} ;
262
269
}
@@ -314,6 +321,7 @@ describe('ComponentStore integration', () => {
314
321
) ;
315
322
return {
316
323
...setup ,
324
+ destroy : ( ) => setup . child . propsStore . ngOnDestroy ( ) ,
317
325
componentStoreDestroySpy,
318
326
} ;
319
327
}
@@ -363,6 +371,7 @@ describe('ComponentStore integration', () => {
363
371
const componentStoreDestroySpy = jest . spyOn ( setup . child , 'ngOnDestroy' ) ;
364
372
return {
365
373
...setup ,
374
+ destroy : ( ) => setup . child . ngOnDestroy ( ) ,
366
375
componentStoreDestroySpy,
367
376
} ;
368
377
}
0 commit comments