1
1
import { Notification } from 'rxjs/Notification' ;
2
+ import { ColdObservable } from 'rxjs/testing/ColdObservable' ;
2
3
import { TestMessage } from '../message/TestMessage' ;
3
4
import { TestMessageValue } from '../message/TestMessageValue' ;
4
5
import { ObservableMarbleToken } from './ObservableMarbleToken' ;
@@ -12,7 +13,7 @@ interface TokenParseAccumulator<T> {
12
13
/**
13
14
* Meta values emitted by marbles (value, error, complete)
14
15
*/
15
- messages : Array < TestMessage < T > > ;
16
+ messages : Array < TestMessage < T | Array < TestMessage < T > > > > ;
16
17
/**
17
18
* Flag indicate values are grouped `()` and emitted simultaneously
18
19
*/
@@ -27,11 +28,29 @@ interface TokenParseAccumulator<T> {
27
28
expandingValue : Array < string > ;
28
29
}
29
30
30
- const marbleTokenParseReducer = < T > ( value ?: { [ key : string ] : T } | null , error ?: any , frameTimeFactor : number = 1 ) => (
31
- acc : TokenParseAccumulator < T > ,
32
- token : any
31
+ /**
32
+ * Translate single token in marble diagram to correct metadata
33
+ * @param {any } token Single char in marble diagram
34
+ * @param {{ [key: string]: T } } [value] Custom value for marble value
35
+ * @param {boolean } [materializeInnerObservables] Flatten inner observables in cold observable. False by default.
36
+ */
37
+ const getMarbleTokenValue = < T > (
38
+ token : any ,
39
+ value ?: { [ key : string ] : T } | null ,
40
+ materializeInnerObservables : boolean = false
33
41
) => {
34
- let message : TestMessage < T > | null = null ;
42
+ const customValue = value && value [ token ] ? value [ token ] : token ;
43
+
44
+ return materializeInnerObservables && customValue instanceof ColdObservable ? customValue . messages : customValue ;
45
+ } ;
46
+
47
+ const marbleTokenParseReducer = < T > (
48
+ value ?: { [ key : string ] : T } | null ,
49
+ error ?: any ,
50
+ materializeInnerObservables : boolean = false ,
51
+ frameTimeFactor : number = 1
52
+ ) => ( acc : TokenParseAccumulator < T > , token : any ) => {
53
+ let message : TestMessage < T | Array < TestMessage < T > > > | null = null ;
35
54
36
55
switch ( token ) {
37
56
case ObservableMarbleToken . TIMEFRAME :
@@ -80,8 +99,11 @@ const marbleTokenParseReducer = <T>(value?: { [key: string]: T } | null, error?:
80
99
if ( acc . expandingTokenCount > 0 ) {
81
100
acc . expandingValue . push ( token ) ;
82
101
} else {
83
- const customValue = value && value [ token ] ? value [ token ] : token ;
84
- message = new TestMessageValue < T > ( acc . currentTimeframe , Notification . createNext < T > ( customValue ) ) ;
102
+ const tokenValue = getMarbleTokenValue ( token , value , materializeInnerObservables ) ;
103
+ message = new TestMessageValue < T | Array < TestMessage < T > > > (
104
+ acc . currentTimeframe ,
105
+ Notification . createNext < T | Array < TestMessage < T > > > ( tokenValue )
106
+ ) ;
85
107
}
86
108
}
87
109
@@ -94,6 +116,7 @@ const marbleTokenParseReducer = <T>(value?: { [key: string]: T } | null, error?:
94
116
95
117
return acc ;
96
118
} ;
119
+
97
120
/**
98
121
* Parse marble DSL diagram, generates array of TestMessageValue for metadata of each marble values to be scheduled into.
99
122
*
@@ -107,9 +130,9 @@ const parseObservableMarble = <T>(
107
130
marble : string ,
108
131
value ?: { [ key : string ] : T } | null ,
109
132
error ?: any ,
110
- _materializeInnerObservables : boolean = false ,
133
+ materializeInnerObservables : boolean = false ,
111
134
frameTimeFactor = 1
112
- ) : Array < TestMessage < T > > => {
135
+ ) : Array < TestMessage < T | Array < TestMessage < T > > > > => {
113
136
if ( marble . indexOf ( SubscriptionMarbleToken . UNSUBSCRIBE ) !== - 1 ) {
114
137
throw new Error ( `Observable marble cannot have unsubscription marker ${ SubscriptionMarbleToken . UNSUBSCRIBE } ` ) ;
115
138
}
@@ -118,13 +141,16 @@ const parseObservableMarble = <T>(
118
141
const frameOffset = subscriptionIndex < 0 ? 0 : subscriptionIndex ;
119
142
120
143
const marbleTokenArray = Array . from ( marble ) . filter ( token => token !== ObservableMarbleToken . NOOP ) . slice ( frameOffset ) ;
121
- const values = marbleTokenArray . reduce ( marbleTokenParseReducer ( value , error , frameTimeFactor ) , {
122
- currentTimeframe : frameOffset ,
123
- messages : [ ] ,
124
- simultaneousGrouped : false ,
125
- expandingTokenCount : 0 ,
126
- expandingValue : [ ]
127
- } ) ;
144
+ const values = marbleTokenArray . reduce (
145
+ marbleTokenParseReducer ( value , error , materializeInnerObservables , frameTimeFactor ) ,
146
+ {
147
+ currentTimeframe : frameOffset ,
148
+ messages : [ ] ,
149
+ simultaneousGrouped : false ,
150
+ expandingTokenCount : 0 ,
151
+ expandingValue : [ ]
152
+ }
153
+ ) ;
128
154
129
155
return values . messages ;
130
156
} ;
0 commit comments