@@ -8,11 +8,15 @@ import {
8
8
PrimitiveState ,
9
9
} from '@test-helpers/rx-angular' ;
10
10
import { of , scheduled , Subject } from 'rxjs' ;
11
+ import { ColdObservable } from 'rxjs/internal/testing/ColdObservable' ;
11
12
import { map , switchMap , take , takeUntil } from 'rxjs/operators' ;
12
13
import { TestScheduler } from 'rxjs/testing' ;
13
14
import { RxState } from '../src/lib/rx-state.service' ;
15
+ import { ReadOnly } from '../src/lib/rx-state.service' ;
14
16
import { createStateChecker } from './fixtures' ;
15
17
18
+ type ReadOnlyPrimitiveState = Pick < RxState < PrimitiveState > , ReadOnly > ;
19
+
16
20
function setupState < T extends object > ( cfg : { initialState ?: T } = { } ) {
17
21
const { initialState } = { ...cfg } ;
18
22
const state = TestBed . inject ( RxState ) ;
@@ -139,25 +143,33 @@ describe('RxStateService', () => {
139
143
it ( 'should return undefined as initial value' , ( ) => {
140
144
const state = setupState ( { initialState : undefined } ) ;
141
145
const val = state . get ( ) ;
146
+ const readOnlyVal = state . asReadOnly ( ) . get ( ) ;
142
147
expect ( val ) . toEqual ( undefined ) ;
148
+ expect ( readOnlyVal ) . toEqual ( undefined ) ;
143
149
} ) ;
144
150
145
151
it ( 'should return undefined for an undefined property' , ( ) => {
146
152
const state = setupState < { num : number } > ( { initialState : undefined } ) ;
147
153
const val = state . get ( 'num' ) ;
154
+ const readOnlyVal = state . asReadOnly ( ) . get ( 'num' ) ;
148
155
expect ( val ) . toEqual ( undefined ) ;
156
+ expect ( readOnlyVal ) . toEqual ( undefined ) ;
149
157
} ) ;
150
158
151
159
it ( 'should return value when keys are provided as params' , ( ) => {
152
160
const state = setupState ( { initialState : initialPrimitiveState } ) ;
153
161
const val = state . get ( 'num' ) ;
162
+ const readOnlyVal = state . asReadOnly ( ) . get ( 'num' ) ;
154
163
expect ( val ) . toEqual ( initialPrimitiveState . num ) ;
164
+ expect ( readOnlyVal ) . toEqual ( initialPrimitiveState . num ) ;
155
165
} ) ;
156
166
157
167
it ( 'should return whole state object when no keys provided' , ( ) => {
158
168
const state = setupState ( { initialState : initialPrimitiveState } ) ;
159
169
const val = state . get ( ) ;
170
+ const readOnlyVal = state . asReadOnly ( ) . get ( ) ;
160
171
expect ( val . num ) . toEqual ( initialPrimitiveState . num ) ;
172
+ expect ( readOnlyVal . num ) . toEqual ( initialPrimitiveState . num ) ;
161
173
} ) ;
162
174
} ) ;
163
175
@@ -166,6 +178,7 @@ describe('RxStateService', () => {
166
178
testScheduler . run ( ( { expectObservable } ) => {
167
179
const state = setupState ( { initialState : undefined } ) ;
168
180
expectObservable ( state . select ( ) ) . toBe ( '-' ) ;
181
+ expectObservable ( state . asReadOnly ( ) . select ( ) ) . toBe ( '-' ) ;
169
182
} ) ;
170
183
} ) ;
171
184
@@ -175,14 +188,18 @@ describe('RxStateService', () => {
175
188
expectObservable ( state . select ( ) ) . toBe ( 's' , {
176
189
s : initialPrimitiveState ,
177
190
} ) ;
191
+ expectObservable ( state . asReadOnly ( ) . select ( ) ) . toBe ( 's' , {
192
+ s : initialPrimitiveState ,
193
+ } ) ;
178
194
} ) ;
179
195
} ) ;
180
196
181
197
it ( 'should throw with wrong params' , ( ) => {
182
198
const state = setupState ( { initialState : initialPrimitiveState } ) ;
183
-
184
- expect ( ( ) => state . select ( true as any ) ) . toThrowError (
185
- 'wrong params passed to select'
199
+ const errorMessage = 'wrong params passed to select' ;
200
+ expect ( ( ) => state . select ( true as any ) ) . toThrowError ( errorMessage ) ;
201
+ expect ( ( ) => state . asReadOnly ( ) . select ( true as any ) ) . toThrowError (
202
+ errorMessage
186
203
) ;
187
204
} ) ;
188
205
@@ -191,6 +208,7 @@ describe('RxStateService', () => {
191
208
testScheduler . run ( ( { expectObservable } ) => {
192
209
const state = setupState ( { } ) ;
193
210
expectObservable ( state . select ( ) ) . toBe ( '' ) ;
211
+ expectObservable ( state . asReadOnly ( ) . select ( ) ) . toBe ( '' ) ;
194
212
} ) ;
195
213
} ) ;
196
214
@@ -202,6 +220,9 @@ describe('RxStateService', () => {
202
220
203
221
state . set ( { num : 42 } ) ;
204
222
expectObservable ( state . select ( 'num' ) ) . toBe ( 's' , { s : 42 } ) ;
223
+ expectObservable ( state . asReadOnly ( ) . select ( 'num' ) ) . toBe ( 's' , {
224
+ s : 42 ,
225
+ } ) ;
205
226
} ) ;
206
227
} ) ;
207
228
} ) ;
@@ -356,6 +377,16 @@ describe('RxStateService', () => {
356
377
state . select ( ) . subscribe ( ( s ) => expect ( s ) . toBe ( { num : 43 } ) ) ;
357
378
} ) ;
358
379
} ) ;
380
+ describe ( 'with read only state' , ( ) => {
381
+ it ( 'should throw error when trying to call set from readOnlyState' , ( ) => {
382
+ const readOnlyState : ReadOnlyPrimitiveState = setupState ( {
383
+ initialState : initialPrimitiveState ,
384
+ } ) . asReadOnly ( ) ;
385
+ expect ( ( ) : void => {
386
+ readOnlyState [ 'set' ] ( 'num' , ( state : PrimitiveState ) => state . num + 1 ) ;
387
+ } ) . toThrowError ( 'readOnlyState.set is not a function' ) ;
388
+ } ) ;
389
+ } ) ;
359
390
} ) ;
360
391
361
392
describe ( 'connect' , ( ) => {
@@ -580,6 +611,24 @@ describe('RxStateService', () => {
580
611
state . ngOnDestroy ( ) ;
581
612
} ) ;
582
613
} ) ;
614
+
615
+ it ( 'should throw error when trying to call connect from readOnlyState' , ( ) => {
616
+ testScheduler . run ( ( ) => {
617
+ const s : { num : number | undefined } = { num : 0 } ;
618
+ const readOnlyState : ReadOnlyPrimitiveState = setupState ( {
619
+ initialState : s ,
620
+ } ) . asReadOnly ( ) ;
621
+ expect ( ( ) : void => {
622
+ readOnlyState [ 'connect' ] (
623
+ scheduled (
624
+ [ { num : undefined } , { num : 43 } , { num : undefined } ] ,
625
+ testScheduler
626
+ ) ,
627
+ ( o , n ) => n
628
+ ) ;
629
+ } ) . toThrowError ( 'readOnlyState.connect is not a function' ) ;
630
+ } ) ;
631
+ } ) ;
583
632
} ) ;
584
633
585
634
describe ( 'setAccumulator' , ( ) => {
@@ -640,6 +689,22 @@ describe('RxStateService', () => {
640
689
expect ( numAcc1Calls ) . toBe ( 1 ) ;
641
690
expect ( numAcc2Calls ) . toBe ( 1 ) ;
642
691
} ) ;
692
+ it ( 'should throw error when trying to call setAccumulator from readOnlyState' , ( ) => {
693
+ let numAccCalls = 0 ;
694
+ const customAcc = < T > ( s : T , sl : Partial < T > ) => {
695
+ ++ numAccCalls ;
696
+ return {
697
+ ...s ,
698
+ ...sl ,
699
+ } ;
700
+ } ;
701
+ const readOnlyState : ReadOnlyPrimitiveState = setupState ( {
702
+ initialState : initialPrimitiveState ,
703
+ } ) . asReadOnly ( ) ;
704
+ expect ( ( ) : void => {
705
+ readOnlyState [ 'setAccumulator' ] ( customAcc ) ;
706
+ } ) . toThrowError ( 'readOnlyState.setAccumulator is not a function' ) ;
707
+ } ) ;
643
708
} ) ;
644
709
645
710
describe ( 'hold' , ( ) => {
@@ -665,5 +730,22 @@ describe('RxStateService', () => {
665
730
state . hold ( of ( 1 , 2 , 3 ) , effect ) ;
666
731
expect ( calls ) . toBe ( 3 ) ;
667
732
} ) ) ;
733
+
734
+ it ( 'should throw error when trying to call hold from readOnlyState' , ( ) => {
735
+ testScheduler . run ( ( { cold, expectSubscriptions } ) => {
736
+ const readOnlyState : ReadOnlyPrimitiveState = setupState ( {
737
+ initialState : initialPrimitiveState ,
738
+ } ) . asReadOnly ( ) ;
739
+ const test$ : ColdObservable < number > = cold ( '(abc)' , {
740
+ a : 1 ,
741
+ b : 2 ,
742
+ c : 3 ,
743
+ } ) ;
744
+ const stop : Subject < void > = new Subject ( ) ;
745
+ expect ( ( ) : void => {
746
+ readOnlyState [ 'hold' ] ( test$ . pipe ( takeUntil ( stop ) ) ) ;
747
+ } ) . toThrowError ( 'readOnlyState.hold is not a function' ) ;
748
+ } ) ;
749
+ } ) ;
668
750
} ) ;
669
751
} ) ;
0 commit comments