Skip to content

Commit 0d20255

Browse files
gstamacbenlesh
authored andcommitted
feat(TestScheduler): Add subscription schedule to expectObservable (#3997)
1 parent 9be9cae commit 0d20255

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

doc/marble-testing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ testScheduler.run(helpers => {
4444

4545
- `hot(marbleDiagram: string, values?: object, error?: any)` - creates a ["hot" observable](https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339) (like 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.
4646
- `cold(marbleDiagram: string, values?: object, error?: any)` - creates a ["cold" observable](https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339) whose subscription starts when the test begins.
47-
- `expectObservable(actual: Observable<T>).toBe(marbleDiagram: string, values?: object, error?: any)` - schedules an assertion for when the TestScheduler flushes.
47+
- `expectObservable(actual: Observable<T>).toBe(marbleDiagram: string, values?: object, error?: any)` - schedules an assertion for when the TestScheduler flushes. Give `subscriptionMarbles` as parameter to change the schedule of subscription and unsubscription. If you don't provide the `subscriptionMarbles` parameter it will subscribe at the beginning and never unsubscribe. Read below about subscription marble diagram.
4848
- `expectSubscriptions(actualSubscriptionLogs: SubscriptionLog[]).toBe(subscriptionMarbles: string)` - like `expectObservable` schedules an assertion for when the testScheduler flushes. Both `cold()` and `hot()` return an observable with a property `subscriptions` of type `SubscriptionLog[]`. Give `subscriptions` as parameter to `expectSubscriptions` to assert whether it matches the `subscriptionsMarbles` marble diagram given in `toBe()`. Subscription marble diagrams are slightly different than Observable marble diagrams. Read more below.
4949
- `flush()` - immediately starts virtual time. Not often used since `run()` will automatically flush for you when your callback returns, but in some cases you may wish to flush more than once or otherwise have more control.
5050

spec/schedulers/TestScheduler-spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ describe('TestScheduler', () => {
248248
const expected = '--a';
249249
expectObservable(source, unsubscribe).toBe(expected);
250250
});
251+
252+
it('should accept a subscription marble diagram', () => {
253+
const source = hot('-a-b-c|');
254+
const subscribe = '---^';
255+
const expected = '---b-c|';
256+
expectObservable(source, subscribe).toBe(expected);
257+
});
251258
});
252259

253260
describe('expectSubscriptions()', () => {

src/internal/testing/TestScheduler.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,13 @@ export class TestScheduler extends VirtualTimeScheduler {
9292
}
9393

9494
expectObservable(observable: Observable<any>,
95-
unsubscriptionMarbles: string = null): ({ toBe: observableToBeFn }) {
95+
subscriptionMarbles: string = null): ({ toBe: observableToBeFn }) {
9696
const actual: TestMessage[] = [];
9797
const flushTest: FlushableTest = { actual, ready: false };
98-
const unsubscriptionFrame = TestScheduler
99-
.parseMarblesAsSubscriptions(unsubscriptionMarbles, this.runMode).unsubscribedFrame;
98+
const subscriptionParsed = TestScheduler.parseMarblesAsSubscriptions(subscriptionMarbles, this.runMode);
99+
const subscriptionFrame = subscriptionParsed.subscribedFrame === Number.POSITIVE_INFINITY ?
100+
0 : subscriptionParsed.subscribedFrame;
101+
const unsubscriptionFrame = subscriptionParsed.unsubscribedFrame;
100102
let subscription: Subscription;
101103

102104
this.schedule(() => {
@@ -112,7 +114,7 @@ export class TestScheduler extends VirtualTimeScheduler {
112114
}, () => {
113115
actual.push({ frame: this.frame, notification: Notification.createComplete() });
114116
});
115-
}, 0);
117+
}, subscriptionFrame);
116118

117119
if (unsubscriptionFrame !== Number.POSITIVE_INFINITY) {
118120
this.schedule(() => subscription.unsubscribe(), unsubscriptionFrame);

0 commit comments

Comments
 (0)