Marble diagrams
Marble diagrams are a way to visually represent Observables. The marbles represent a value being emitted, the passage of time is represented from left to right, a vertical line represents the completion of an Observable, and an X represents an error.
-represents the passage of 10 frames of time.|represents the completion of an Observable.^represents the subscription point of an Observable (only valid for hot Observables).#represents an error. The value of the error can be provided to errors argument."()"sync groupings: When multiple events need to single in the same frame synchronously, parenthesis are used to group those events. You can group nexted values, a completion or an error in this manner. The position of the initial ( determines the time at which its values are emitted."^"subscription point: (hot observables only) shows the point at which the tested observables will be subscribed to the hot observable. This is the “zero frame” for that observable, every frame before the^will be negative. You can only use this character once in a diagram."!"unsubscription point: shows the point in time at which a subscription is unsubscribed. You can only use this character once in a diagram.- any other character represents a value emitted. The actual value can be represented in the values argument, where the character is the key.
Methods
hot(marbles: string, values?: object, error?: any)- creates a “hot” observable (a subject) that will behave as though it’s already “running” when the test begins. An interesting difference is that hot marbles allow a^character to signal where the “zero frame” is. That is the point at which the subscription to observables being tested begins.cold(marbles: string, values?: object, error?: any)- creates a “cold” observable whose subscription starts when the test begins.expectObservable(actual: Observable<T>).toBe(marbles: string, values?: object, error?: any)- schedules an assertion for when the TestScheduler flushes. The TestScheduler will automatically flush at the end of your jasmineitblock.expectSubscriptions(actualSubscriptionLogs: SubscriptionLog[]).toBe(subscriptionMarbles: string)- likeexpectObservableschedules an assertion for when the testScheduler flushes. Bothcold()andhot()return an observable with a property subscriptions of typeSubscriptionLog[]. Givesubscriptionsas parameter toexpectSubscriptionsto assert whether it matches the subscriptionsMarbles marble diagram given intoBe().
Examples
hot('--a--b')will emit"a"and"b"hot('--a--b', { a: 1, b: 2 })will emit1and2hot('---#')will emit error"error"hot('---#', null, new SpecialError('test'))will emitnew SpecialError('test')hot('-')equivalent to Observable.never(), or an observable that never emits or completeshot('-a-^-b--|')on frame -20 emit a, then on frame 20 emit b, and on frame 50, complete.hot('-----(a|)')on frame 50, emit a and complete.
Basic test
var e1 = hot('----a--^--b-------c--|');
var e2 = hot( '---d-^--e---------f-----|');
var expected = '---(be)----c-f-----|';
expectObservable(e1.merge(e2)).toBe(expected);
- The
^characters of hot observables should always be aligned. - The first character of cold observables or expected observables should always be aligned with each other, and with the ^ of hot observables.
- Use default emission values when you can. Specify
valueswhen you have to.