Skip to content

Commit

Permalink
feat(parseobservablemarble): support flatten inner observables
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj committed Aug 17, 2017
1 parent d9fde83 commit 9cbb534
Showing 1 changed file with 42 additions and 16 deletions.
58 changes: 42 additions & 16 deletions src/marbles/parseObservableMarble.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Notification } from 'rxjs/Notification';
import { ColdObservable } from 'rxjs/testing/ColdObservable';
import { TestMessage } from '../message/TestMessage';
import { TestMessageValue } from '../message/TestMessageValue';
import { ObservableMarbleToken } from './ObservableMarbleToken';
Expand All @@ -12,7 +13,7 @@ interface TokenParseAccumulator<T> {
/**
* Meta values emitted by marbles (value, error, complete)
*/
messages: Array<TestMessage<T>>;
messages: Array<TestMessage<T | Array<TestMessage<T>>>>;
/**
* Flag indicate values are grouped `()` and emitted simultaneously
*/
Expand All @@ -27,11 +28,29 @@ interface TokenParseAccumulator<T> {
expandingValue: Array<string>;
}

const marbleTokenParseReducer = <T>(value?: { [key: string]: T } | null, error?: any, frameTimeFactor: number = 1) => (
acc: TokenParseAccumulator<T>,
token: any
/**
* Translate single token in marble diagram to correct metadata
* @param {any} token Single char in marble diagram
* @param {{ [key: string]: T }} [value] Custom value for marble value
* @param {boolean} [materializeInnerObservables] Flatten inner observables in cold observable. False by default.
*/
const getMarbleTokenValue = <T>(
token: any,
value?: { [key: string]: T } | null,
materializeInnerObservables: boolean = false
) => {
let message: TestMessage<T> | null = null;
const customValue = value && value[token] ? value[token] : token;

return materializeInnerObservables && customValue instanceof ColdObservable ? customValue.messages : customValue;
};

const marbleTokenParseReducer = <T>(
value?: { [key: string]: T } | null,
error?: any,
materializeInnerObservables: boolean = false,
frameTimeFactor: number = 1
) => (acc: TokenParseAccumulator<T>, token: any) => {
let message: TestMessage<T | Array<TestMessage<T>>> | null = null;

switch (token) {
case ObservableMarbleToken.TIMEFRAME:
Expand Down Expand Up @@ -80,8 +99,11 @@ const marbleTokenParseReducer = <T>(value?: { [key: string]: T } | null, error?:
if (acc.expandingTokenCount > 0) {
acc.expandingValue.push(token);
} else {
const customValue = value && value[token] ? value[token] : token;
message = new TestMessageValue<T>(acc.currentTimeframe, Notification.createNext<T>(customValue));
const tokenValue = getMarbleTokenValue(token, value, materializeInnerObservables);
message = new TestMessageValue<T | Array<TestMessage<T>>>(
acc.currentTimeframe,
Notification.createNext<T | Array<TestMessage<T>>>(tokenValue)
);
}
}

Expand All @@ -94,6 +116,7 @@ const marbleTokenParseReducer = <T>(value?: { [key: string]: T } | null, error?:

return acc;
};

/**
* Parse marble DSL diagram, generates array of TestMessageValue for metadata of each marble values to be scheduled into.
*
Expand All @@ -107,9 +130,9 @@ const parseObservableMarble = <T>(
marble: string,
value?: { [key: string]: T } | null,
error?: any,
_materializeInnerObservables: boolean = false,
materializeInnerObservables: boolean = false,
frameTimeFactor = 1
): Array<TestMessage<T>> => {
): Array<TestMessage<T | Array<TestMessage<T>>>> => {
if (marble.indexOf(SubscriptionMarbleToken.UNSUBSCRIBE) !== -1) {
throw new Error(`Observable marble cannot have unsubscription marker ${SubscriptionMarbleToken.UNSUBSCRIBE}`);
}
Expand All @@ -118,13 +141,16 @@ const parseObservableMarble = <T>(
const frameOffset = subscriptionIndex < 0 ? 0 : subscriptionIndex;

const marbleTokenArray = Array.from(marble).filter(token => token !== ObservableMarbleToken.NOOP).slice(frameOffset);
const values = marbleTokenArray.reduce(marbleTokenParseReducer(value, error, frameTimeFactor), {
currentTimeframe: frameOffset,
messages: [],
simultaneousGrouped: false,
expandingTokenCount: 0,
expandingValue: []
});
const values = marbleTokenArray.reduce(
marbleTokenParseReducer(value, error, materializeInnerObservables, frameTimeFactor),
{
currentTimeframe: frameOffset,
messages: [],
simultaneousGrouped: false,
expandingTokenCount: 0,
expandingValue: []
}
);

return values.messages;
};
Expand Down

0 comments on commit 9cbb534

Please sign in to comment.