1
1
import { rxEffects } from '@rx-angular/state/effects' ;
2
2
import { Component , inject , Injectable , InjectionToken } from '@angular/core' ;
3
- import { of , timer } from 'rxjs' ;
3
+ import { debounceTime , of , Subject , timer } from 'rxjs' ;
4
4
import { TestBed } from '@angular/core/testing' ;
5
5
import { wait } from 'nx-cloud/lib/utilities/waiter' ;
6
6
@@ -9,52 +9,43 @@ type Movie = {};
9
9
@Injectable ( { providedIn : 'root' } )
10
10
export class LocalStorage {
11
11
items = { } ;
12
+
12
13
setItem ( prop : string , value : string ) {
13
14
this . items [ prop ] = value ;
14
15
}
16
+
15
17
removeItem ( prop : string ) {
16
18
delete this . items [ prop ] ;
17
19
}
20
+
18
21
getItem ( prop : string ) {
19
22
return this . items [ prop ] ;
20
23
}
21
24
}
22
25
23
- const BackupInterval = new InjectionToken < number > ( 'BackupInterval' ) ;
24
-
25
26
@Component ( {
26
- template : ` <input name="title" [(ngModel)]="movie" />
27
+ template : ` <input name="title" (change)="change.next(title.value)" #title />
27
28
<button name="save" (click)="save()">Save</button>` ,
28
- providers : [ { provide : BackupInterval , useValue : 40 } ] ,
29
29
} )
30
30
class ListComponent {
31
- protected movie = '' ;
32
- private backupInterval = inject ( BackupInterval ) ;
31
+ private change = new Subject < string > ( ) ;
33
32
private localStorage = inject ( LocalStorage ) ;
34
33
35
34
private ef = rxEffects ( ( { register } ) => {
36
- const updateBackup = ( ) =>
37
- this . localStorage . setItem ( 'editName' , this . movie ) ;
38
- register ( timer ( 0 , this . backupInterval ) , updateBackup ) ;
35
+ const updateBackup = ( title ) => this . localStorage . setItem ( 'title' , title ) ;
36
+ register ( this . change . pipe ( debounceTime ( 300 ) ) , updateBackup ) ;
39
37
} ) ;
40
38
41
39
save ( ) {
42
40
localStorage . removeItem ( 'editName' ) ;
43
41
}
44
-
45
- ngOnInit ( ) {
46
- this . effects . register ( this . util . rotationChanged$ , ( ) => {
47
- console . log ( 'viewport rotation changed' ) ;
48
- } ) ;
49
- }
50
42
}
51
43
52
44
// Test helper code ==========
53
45
54
46
function setupComponent ( ) {
55
47
TestBed . configureTestingModule ( {
56
48
declarations : [ ListComponent ] ,
57
- providers : [ { provide : BackupInterval , useValue : 10 } ] ,
58
49
} ) ;
59
50
60
51
const localStorage = TestBed . inject ( LocalStorage ) ;
@@ -63,7 +54,7 @@ function setupComponent() {
63
54
const component = fixture . componentInstance ;
64
55
65
56
const searchInputElem : HTMLInputElement = fixture . nativeElement . querySelector (
66
- 'input[name="search "]'
57
+ 'input[name="title "]'
67
58
) ;
68
59
const searchInputChange = ( value : string ) => {
69
60
searchInputElem . value = value ;
@@ -86,19 +77,17 @@ describe('effects usage in a component', () => {
86
77
const spyRemoveItem = jest . spyOn ( localStorage , 'removeItem' ) ;
87
78
88
79
expect ( spySetItem ) . toBeCalledTimes ( 0 ) ;
89
- await wait ( 200 ) ;
90
- expect ( spySetItem ) . toBeCalledTimes ( 1 ) ;
91
- expect ( spySetItem ) . toBeCalledWith ( '' ) ;
92
-
80
+ searchInputChange ( 'abc' ) ;
81
+ expect ( spySetItem ) . toBeCalledTimes ( 0 ) ; // debounceed
82
+ await wait ( 350 ) ;
93
83
expect ( spySetItem ) . toBeCalledTimes ( 1 ) ;
94
- expect ( spySetItem ) . toBeCalledWith ( 1 ) ;
84
+ expect ( spySetItem ) . toBeCalledWith ( 'title' , 'abc' ) ;
95
85
} ) ;
96
86
} ) ;
97
87
98
88
function setupComponent2 ( ) {
99
89
TestBed . configureTestingModule ( {
100
90
declarations : [ ListComponent ] ,
101
- providers : [ { provide : BackupInterval , useValue : 10 } ] ,
102
91
} ) ;
103
92
104
93
const localStorage = TestBed . inject ( LocalStorage ) ;
0 commit comments