blob: f9e6da4b153e550ce5d53039dd56bd7090d389d4 [file] [log] [blame]
{"version":3,"file":"TestScheduler.js","sourceRoot":"","sources":["../../src/testing/TestScheduler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Observable } from '../Observable';\nimport { Notification } from '../Notification';\nimport { ColdObservable } from './ColdObservable';\nimport { HotObservable } from './HotObservable';\nimport { TestMessage } from './TestMessage';\nimport { SubscriptionLog } from './SubscriptionLog';\nimport { Subscription } from '../Subscription';\nimport { VirtualTimeScheduler, VirtualAction } from '../scheduler/VirtualTimeScheduler';\n\nconst defaultMaxFrame: number = 750;\n\ninterface FlushableTest {\n ready: boolean;\n actual?: any[];\n expected?: any[];\n}\n\nexport type observableToBeFn = (marbles: string, values?: any, errorValue?: any) => void;\nexport type subscriptionLogsToBeFn = (marbles: string | string[]) => void;\n\nexport class TestScheduler extends VirtualTimeScheduler {\n private hotObservables: HotObservable<any>[] = [];\n private coldObservables: ColdObservable<any>[] = [];\n private flushTests: FlushableTest[] = [];\n\n constructor(public assertDeepEqual: (actual: any, expected: any) => boolean | void) {\n super(VirtualAction, defaultMaxFrame);\n }\n\n createTime(marbles: string): number {\n const indexOf: number = marbles.indexOf('|');\n if (indexOf === -1) {\n throw new Error('marble diagram for time should have a completion marker \"|\"');\n }\n return indexOf * TestScheduler.frameTimeFactor;\n }\n\n createColdObservable<T>(marbles: string, values?: any, error?: any): ColdObservable<T> {\n if (marbles.indexOf('^') !== -1) {\n throw new Error('cold observable cannot have subscription offset \"^\"');\n }\n if (marbles.indexOf('!') !== -1) {\n throw new Error('cold observable cannot have unsubscription marker \"!\"');\n }\n const messages = TestScheduler.parseMarbles(marbles, values, error);\n const cold = new ColdObservable<T>(messages, this);\n this.coldObservables.push(cold);\n return cold;\n }\n\n createHotObservable<T>(marbles: string, values?: any, error?: any): HotObservable<T> {\n if (marbles.indexOf('!') !== -1) {\n throw new Error('hot observable cannot have unsubscription marker \"!\"');\n }\n const messages = TestScheduler.parseMarbles(marbles, values, error);\n const subject = new HotObservable<T>(messages, this);\n this.hotObservables.push(subject);\n return subject;\n }\n\n private materializeInnerObservable(observable: Observable<any>,\n outerFrame: number): TestMessage[] {\n const messages: TestMessage[] = [];\n observable.subscribe((value) => {\n messages.push({ frame: this.frame - outerFrame, notification: Notification.createNext(value) });\n }, (err) => {\n messages.push({ frame: this.frame - outerFrame, notification: Notification.createError(err) });\n }, () => {\n messages.push({ frame: this.frame - outerFrame, notification: Notification.createComplete() });\n });\n return messages;\n }\n\n expectObservable(observable: Observable<any>,\n unsubscriptionMarbles: string = null): ({ toBe: observableToBeFn }) {\n const actual: TestMessage[] = [];\n const flushTest: FlushableTest = { actual, ready: false };\n const unsubscriptionFrame = TestScheduler\n .parseMarblesAsSubscriptions(unsubscriptionMarbles).unsubscribedFrame;\n let subscription: Subscription;\n\n this.schedule(() => {\n subscription = observable.subscribe(x => {\n let value = x;\n // Support Observable-of-Observables\n if (x instanceof Observable) {\n value = this.materializeInnerObservable(value, this.frame);\n }\n actual.push({ frame: this.frame, notification: Notification.createNext(value) });\n }, (err) => {\n actual.push({ frame: this.frame, notification: Notification.createError(err) });\n }, () => {\n actual.push({ frame: this.frame, notification: Notification.createComplete() });\n });\n }, 0);\n\n if (unsubscriptionFrame !== Number.POSITIVE_INFINITY) {\n this.schedule(() => subscription.unsubscribe(), unsubscriptionFrame);\n }\n\n this.flushTests.push(flushTest);\n\n return {\n toBe(marbles: string, values?: any, errorValue?: any) {\n flushTest.ready = true;\n flushTest.expected = TestScheduler.parseMarbles(marbles, values, errorValue, true);\n }\n };\n }\n\n expectSubscriptions(actualSubscriptionLogs: SubscriptionLog[]): ({ toBe: subscriptionLogsToBeFn }) {\n const flushTest: FlushableTest = { actual: actualSubscriptionLogs, ready: false };\n this.flushTests.push(flushTest);\n return {\n toBe(marbles: string | string[]) {\n const marblesArray: string[] = (typeof marbles === 'string') ? [marbles] : marbles;\n flushTest.ready = true;\n flushTest.expected = marblesArray.map(marbles =>\n TestScheduler.parseMarblesAsSubscriptions(marbles)\n );\n }\n };\n }\n\n flush() {\n const hotObservables = this.hotObservables;\n while (hotObservables.length > 0) {\n hotObservables.shift().setup();\n }\n\n super.flush();\n const readyFlushTests = this.flushTests.filter(test => test.ready);\n while (readyFlushTests.length > 0) {\n const test = readyFlushTests.shift();\n this.assertDeepEqual(test.actual, test.expected);\n }\n }\n\n static parseMarblesAsSubscriptions(marbles: string): SubscriptionLog {\n if (typeof marbles !== 'string') {\n return new SubscriptionLog(Number.POSITIVE_INFINITY);\n }\n const len = marbles.length;\n let groupStart = -1;\n let subscriptionFrame = Number.POSITIVE_INFINITY;\n let unsubscriptionFrame = Number.POSITIVE_INFINITY;\n\n for (let i = 0; i < len; i++) {\n const frame = i * this.frameTimeFactor;\n const c = marbles[i];\n switch (c) {\n case '-':\n case ' ':\n break;\n case '(':\n groupStart = frame;\n break;\n case ')':\n groupStart = -1;\n break;\n case '^':\n if (subscriptionFrame !== Number.POSITIVE_INFINITY) {\n throw new Error('found a second subscription point \\'^\\' in a ' +\n 'subscription marble diagram. There can only be one.');\n }\n subscriptionFrame = groupStart > -1 ? groupStart : frame;\n break;\n case '!':\n if (unsubscriptionFrame !== Number.POSITIVE_INFINITY) {\n throw new Error('found a second subscription point \\'^\\' in a ' +\n 'subscription marble diagram. There can only be one.');\n }\n unsubscriptionFrame = groupStart > -1 ? groupStart : frame;\n break;\n default:\n throw new Error('there can only be \\'^\\' and \\'!\\' markers in a ' +\n 'subscription marble diagram. Found instead \\'' + c + '\\'.');\n }\n }\n\n if (unsubscriptionFrame < 0) {\n return new SubscriptionLog(subscriptionFrame);\n } else {\n return new SubscriptionLog(subscriptionFrame, unsubscriptionFrame);\n }\n }\n\n static parseMarbles(marbles: string,\n values?: any,\n errorValue?: any,\n materializeInnerObservables: boolean = false): TestMessage[] {\n if (marbles.indexOf('!') !== -1) {\n throw new Error('conventional marble diagrams cannot have the ' +\n 'unsubscription marker \"!\"');\n }\n const len = marbles.length;\n const testMessages: TestMessage[] = [];\n const subIndex = marbles.indexOf('^');\n const frameOffset = subIndex === -1 ? 0 : (subIndex * -this.frameTimeFactor);\n const getValue = typeof values !== 'object' ?\n (x: any) => x :\n (x: any) => {\n // Support Observable-of-Observables\n if (materializeInnerObservables && values[x] instanceof ColdObservable) {\n return values[x].messages;\n }\n return values[x];\n };\n let groupStart = -1;\n\n for (let i = 0; i < len; i++) {\n const frame = i * this.frameTimeFactor + frameOffset;\n let notification: Notification<any>;\n const c = marbles[i];\n switch (c) {\n case '-':\n case ' ':\n break;\n case '(':\n groupStart = frame;\n break;\n case ')':\n groupStart = -1;\n break;\n case '|':\n notification = Notification.createComplete();\n break;\n case '^':\n break;\n case '#':\n notification = Notification.createError(errorValue || 'error');\n break;\n default:\n notification = Notification.createNext(getValue(c));\n break;\n }\n\n if (notification) {\n testMessages.push({ frame: groupStart > -1 ? groupStart : frame, notification });\n }\n }\n return testMessages;\n }\n}\n"]}