Skip to content

Commit

Permalink
feat(testing): testScheduler.run() supports time progression syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
jayphelps committed Apr 24, 2018
1 parent 2d5b3b2 commit 9322b7d
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 28 deletions.
120 changes: 110 additions & 10 deletions spec/schedulers/TestScheduler-spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { expect } from 'chai';
import { hot, cold, expectObservable, expectSubscriptions, time } from '../helpers/marble-testing';
import { TestScheduler } from 'rxjs/testing';
import { Observable, NEVER, EMPTY, Subject, of, merge, Notification } from 'rxjs';
import { delay, debounceTime } from 'rxjs/operators';
import { Observable, NEVER, EMPTY, Subject, of, concat, merge, Notification } from 'rxjs';
import { delay, debounceTime, concatMap } from 'rxjs/operators';

declare const rxTestScheduler: TestScheduler;

Expand Down Expand Up @@ -67,6 +67,28 @@ describe('TestScheduler', () => {
{ frame: 30, notification: Notification.createNext('c') }
]);
});

it('should ignore whitespace when runMode=true', () => {
const runMode = true;
const result = TestScheduler.parseMarbles(' -a - b - c | ', { a: 'A', b: 'B', c: 'C' }, undefined, undefined, runMode);
expect(result).deep.equal([
{ frame: 10, notification: Notification.createNext('A') },
{ frame: 30, notification: Notification.createNext('B') },
{ frame: 50, notification: Notification.createNext('C') },
{ frame: 60, notification: Notification.createComplete() }
]);
});

it('should suppport time progression syntax when runMode=true', () => {
const runMode = true;
const result = TestScheduler.parseMarbles('10.2ms a 1.2s b 1m c|', { a: 'A', b: 'B', c: 'C' }, undefined, undefined, runMode);
expect(result).deep.equal([
{ frame: 10.2, notification: Notification.createNext('A') },
{ frame: 10.2 + 10 + (1.2 * 1000), notification: Notification.createNext('B') },
{ frame: 10.2 + 10 + (1.2 * 1000) + 10 + (1000 * 60), notification: Notification.createNext('C') },
{ frame: 10.2 + 10 + (1.2 * 1000) + 10 + (1000 * 60) + 10, notification: Notification.createComplete() }
]);
});
});

describe('parseMarblesAsSubscriptions()', () => {
Expand All @@ -87,6 +109,20 @@ describe('TestScheduler', () => {
expect(result.subscribedFrame).to.equal(30);
expect(result.unsubscribedFrame).to.equal(30);
});

it('should ignore whitespace when runMode=true', () => {
const runMode = true;
const result = TestScheduler.parseMarblesAsSubscriptions(' - - - - ^ - - ! -- - ', runMode);
expect(result.subscribedFrame).to.equal(40);
expect(result.unsubscribedFrame).to.equal(70);
});

it('should suppport time progression syntax when runMode=true', () => {
const runMode = true;
const result = TestScheduler.parseMarblesAsSubscriptions('10.2ms ^ 1.2s - 1m !', runMode);
expect(result.subscribedFrame).to.equal(10.2);
expect(result.unsubscribedFrame).to.equal(10.2 + 10 + (1.2 * 1000) + 10 + (1000 * 60));
});
});

describe('createTime()', () => {
Expand Down Expand Up @@ -262,6 +298,36 @@ describe('TestScheduler', () => {
expect(actual).deep.equal(expected);
};

describe('marble diagrams', () => {
it('should ignore whitespace', () => {
const testScheduler = new TestScheduler(assertDeepEquals);

testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
const input = cold(' -a - b - c | ');
const output = input.pipe(
concatMap(d => of(d).pipe(
delay(10)
))
);
const expected = ' -- 9ms a 9ms b 9ms (c|) ';

expectObservable(output).toBe(expected);
expectSubscriptions(input.subscriptions).toBe(' ^- - - - --------------------------!');
});
});

it('should support time progression syntax', () => {
const testScheduler = new TestScheduler(assertDeepEquals);

testScheduler.run(({ cold, hot, flush, expectObservable, expectSubscriptions }) => {
const output = cold('10.2ms a 1.2s b 1m c|');
const expected = ' 10.2ms a 1.2s b 1m c|';

expectObservable(output).toBe(expected);
});
});
});

it('should provide the correct helpers', () => {
const testScheduler = new TestScheduler(assertDeepEquals);

Expand All @@ -273,22 +339,48 @@ describe('TestScheduler', () => {
expect(expectSubscriptions).to.be.a('function');

const obs1 = cold('-a-c-e|');
const obs2 = hot('-^-b-d-f|');
const obs2 = hot(' ^-b-d-f|');
const output = merge(obs1, obs2);
const expected = '-abcdef|';
const expected = ' -abcdef|';

expectObservable(output).toBe(expected);
expectSubscriptions(obs1.subscriptions).toBe('^-----!');
expectSubscriptions(obs2.subscriptions).toBe('^------!');
});
});

it('should have each frame represent a single virtual millisecond', () => {
const testScheduler = new TestScheduler(assertDeepEquals);

testScheduler.run(({ cold, expectObservable }) => {
const output = cold('-a-b-c--------|').pipe(
debounceTime(5)
);
const expected = ' ------ 4ms c---|';
expectObservable(output).toBe(expected);
});
});

it('should have no maximum frame count', () => {
const testScheduler = new TestScheduler(assertDeepEquals);

testScheduler.run(({ cold, expectObservable }) => {
const output = cold('-a|').pipe(
delay(1000 * 10)
);
const expected = ' - 10s a|';
expectObservable(output).toBe(expected);
});
});

it('should make operators that use AsyncScheduler automatically use TestScheduler for actual scheduling', () => {
const testScheduler = new TestScheduler(assertDeepEquals);

testScheduler.run(({ cold, expectObservable }) => {
const output = cold('-a-b-(c|)').pipe(debounceTime(20), delay(10));
const expected = '------(c|)';
const output = cold('-a-b-c--------|').pipe(
debounceTime(5)
);
const expected = ' ----------c---|';
expectObservable(output).toBe(expected);
});
});
Expand All @@ -298,8 +390,12 @@ describe('TestScheduler', () => {
expect(actual).deep.equal(expected);
});
testScheduler.run(({ cold, expectObservable }) => {
const output = cold('-a-b-(c|)').pipe(debounceTime(20), delay(10));
const expected = '------(c|)';
const output = cold('-a-b-c|').pipe(
concatMap(d => of(d).pipe(
delay(10)
))
);
const expected = ' -- 9ms a 9ms b 9ms (c|)';
expectObservable(output).toBe(expected);

expect(testScheduler['flushTests'].length).to.equal(1);
Expand All @@ -314,8 +410,12 @@ describe('TestScheduler', () => {
const testScheduler = new TestScheduler(assertDeepEquals);

testScheduler.run(({ cold, expectObservable, flush }) => {
const output = cold('-a-b-(c|)').pipe(debounceTime(20), delay(10));
const expected = '------(c|)';
const output = cold('-a-b-c|').pipe(
concatMap(d => of(d).pipe(
delay(10)
))
);
const expected = ' -- 9ms a 9ms b 9ms (c|)';
expectObservable(output).toBe(expected);

expect(testScheduler['flushTests'].length).to.equal(1);
Expand Down
4 changes: 0 additions & 4 deletions src/internal/scheduler/VirtualTimeScheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ export class VirtualTimeScheduler extends AsyncScheduler {
throw error;
}
}

public schedule<T>(work: (this: SchedulerAction<T>, state?: T) => void, delay: number = 0, state?: T): Subscription {
return new VirtualAction<T>(this, work).schedule(state, delay);
}
}

/**
Expand Down
Loading

0 comments on commit 9322b7d

Please sign in to comment.