@@ -18,46 +18,44 @@ import { MOCK_SELECTORS } from './tokens';
18
18
if ( typeof afterEach === 'function' ) {
19
19
afterEach ( ( ) => {
20
20
try {
21
- const store = TestBed . get ( Store ) as MockStore < any > ;
22
- if ( store && 'resetSelectors' in store ) {
23
- store . resetSelectors ( ) ;
21
+ const mockStore : MockStore | undefined = TestBed . inject ( MockStore ) ;
22
+ if ( mockStore ) {
23
+ mockStore . resetSelectors ( ) ;
24
24
}
25
25
} catch { }
26
26
} ) ;
27
27
}
28
28
29
+ type OnlyMemoized < T , Result > = T extends string | MemoizedSelector < any , any >
30
+ ? MemoizedSelector < any , Result >
31
+ : T extends MemoizedSelectorWithProps < any , any , any >
32
+ ? MemoizedSelectorWithProps < any , any , Result >
33
+ : never ;
34
+
35
+ type Memoized < Result > =
36
+ | MemoizedSelector < any , Result >
37
+ | MemoizedSelectorWithProps < any , any , Result > ;
38
+
29
39
@Injectable ( )
30
40
export class MockStore < T = object > extends Store < T > {
31
- static selectors = new Map <
32
- | string
33
- | MemoizedSelector < any , any >
34
- | MemoizedSelectorWithProps < any , any , any > ,
35
- any
36
- > ( ) ;
37
-
38
- scannedActions$ : Observable < Action > ;
41
+ private readonly selectors = new Map < Memoized < any > | string , any > ( ) ;
42
+
43
+ readonly scannedActions$ : Observable < Action > ;
39
44
private lastState ?: T ;
40
45
41
46
constructor (
42
47
private state$ : MockState < T > ,
43
48
actionsObserver : ActionsSubject ,
44
49
reducerManager : ReducerManager ,
45
50
@Inject ( INITIAL_STATE ) private initialState : T ,
46
- @Inject ( MOCK_SELECTORS ) mockSelectors ? : MockSelector [ ]
51
+ @Inject ( MOCK_SELECTORS ) mockSelectors : MockSelector [ ] = [ ]
47
52
) {
48
53
super ( state$ , actionsObserver , reducerManager ) ;
49
54
this . resetSelectors ( ) ;
50
55
this . setState ( this . initialState ) ;
51
56
this . scannedActions$ = actionsObserver . asObservable ( ) ;
52
- if ( mockSelectors ) {
53
- mockSelectors . forEach ( mockSelector => {
54
- const selector = mockSelector . selector ;
55
- if ( typeof selector === 'string' ) {
56
- this . overrideSelector ( selector , mockSelector . value ) ;
57
- } else {
58
- this . overrideSelector ( selector , mockSelector . value ) ;
59
- }
60
- } ) ;
57
+ for ( const mockSelector of mockSelectors ) {
58
+ this . overrideSelector ( mockSelector . selector , mockSelector . value ) ;
61
59
}
62
60
}
63
61
@@ -66,53 +64,45 @@ export class MockStore<T = object> extends Store<T> {
66
64
this . lastState = nextState ;
67
65
}
68
66
69
- overrideSelector < T , Result > (
70
- selector : string ,
71
- value : Result
72
- ) : MemoizedSelector < string , Result > ;
73
- overrideSelector < T , Result > (
74
- selector : MemoizedSelector < T , Result > ,
75
- value : Result
76
- ) : MemoizedSelector < T , Result > ;
77
- overrideSelector < T , Result > (
78
- selector : MemoizedSelectorWithProps < T , any , Result > ,
79
- value : Result
80
- ) : MemoizedSelectorWithProps < T , any , Result > ;
81
- overrideSelector < T , Result > (
82
- selector :
83
- | string
84
- | MemoizedSelector < any , any >
85
- | MemoizedSelectorWithProps < any , any , any > ,
86
- value : any
87
- ) {
88
- MockStore . selectors . set ( selector , value ) ;
89
-
90
- if ( typeof selector === 'string' ) {
91
- const stringSelector = createSelector ( ( ) => { } , ( ) => value ) ;
92
-
93
- return stringSelector ;
94
- }
95
-
96
- selector . setResult ( value ) ;
97
-
98
- return selector ;
67
+ overrideSelector <
68
+ Selector extends Memoized < Result > ,
69
+ Value extends Result ,
70
+ Result = Selector extends MemoizedSelector < any , infer T >
71
+ ? T
72
+ : Selector extends MemoizedSelectorWithProps < any , any , infer U >
73
+ ? U
74
+ : Value
75
+ > (
76
+ selector : Selector | string ,
77
+ value : Value
78
+ ) : OnlyMemoized < typeof selector , Result > {
79
+ this . selectors . set ( selector , value ) ;
80
+
81
+ const resultSelector : Memoized < Result > =
82
+ typeof selector === 'string'
83
+ ? createSelector ( ( ) => { } , ( ) : Result => value )
84
+ : selector ;
85
+
86
+ resultSelector . setResult ( value ) ;
87
+
88
+ return resultSelector as OnlyMemoized < typeof selector , Result > ;
99
89
}
100
90
101
91
resetSelectors ( ) {
102
- MockStore . selectors . forEach ( ( _ , selector ) => {
92
+ for ( const selector of this . selectors . keys ( ) ) {
103
93
if ( typeof selector !== 'string' ) {
104
94
selector . release ( ) ;
105
95
selector . clearResult ( ) ;
106
96
}
107
- } ) ;
97
+ }
108
98
109
- MockStore . selectors . clear ( ) ;
99
+ this . selectors . clear ( ) ;
110
100
}
111
101
112
102
select ( selector : any , prop ?: any ) {
113
- if ( typeof selector === 'string' && MockStore . selectors . has ( selector ) ) {
103
+ if ( typeof selector === 'string' && this . selectors . has ( selector ) ) {
114
104
return new BehaviorSubject < any > (
115
- MockStore . selectors . get ( selector )
105
+ this . selectors . get ( selector )
116
106
) . asObservable ( ) ;
117
107
}
118
108
0 commit comments