Skip to content

Commit

Permalink
feat(matcher): Update comparative output for observable matcher (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
phillipzada authored and brandonroberts committed Oct 2, 2017
1 parent 902703b commit 31f6b76
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 39 deletions.
123 changes: 91 additions & 32 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
import { Notification } from 'rxjs/Notification';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { TestMessage } from 'rxjs/testing/TestMessage';
import { TestScheduler } from 'rxjs/testing/TestScheduler';
import {
TestHotObservable,
TestColdObservable,
TestObservable,
} from './src/test-observables';
import {
initTestScheduler,
getTestScheduler,
resetTestScheduler,
} from './src/scheduler';

export {
getTestScheduler,
initTestScheduler,
resetTestScheduler,
} from './src/scheduler';

export function hot(
marbles: string,
values?: any,
error?: any,
): TestHotObservable {

import { getTestScheduler, initTestScheduler, resetTestScheduler } from './src/scheduler';
import { TestColdObservable, TestHotObservable, TestObservable } from './src/test-observables';

export { getTestScheduler, initTestScheduler, resetTestScheduler } from './src/scheduler';

export function hot(marbles: string, values?: any, error?: any): TestHotObservable {
return new TestHotObservable(marbles, values, error);
}

export function cold(
marbles: string,
values?: any,
error?: any,
): TestColdObservable {
export function cold(marbles: string, values?: any, error?: any): TestColdObservable {
return new TestColdObservable(marbles, values, error);
}

Expand All @@ -44,14 +29,88 @@ declare global {
}
}

/*
* Based on source code found in rxjs library
* https://github.com/ReactiveX/rxjs/blob/master/src/testing/TestScheduler.ts
*
*/
function materializeInnerObservable(
observable: Observable<any>,
outerFrame: number,
): TestMessage[] {
const messages: TestMessage[] = [];
const scheduler = getTestScheduler();

observable.subscribe(
value => {
messages.push({
frame: scheduler.frame - outerFrame,
notification: Notification.createNext(value),
});
},
err => {
messages.push({
frame: scheduler.frame - outerFrame,
notification: Notification.createError(err),
});
},
() => {
messages.push({
frame: scheduler.frame - outerFrame,
notification: Notification.createComplete(),
});
},
);
return messages;
}

export function addMatchers() {
jasmine.addMatchers({
toBeObservable: () => ({
compare: function(actual: TestObservable, test: TestObservable) {
getTestScheduler()
.expectObservable(actual)
.toBe(test.marbles, test.values, test.error);
getTestScheduler().flush();
compare: function (actual: TestObservable, fixture: TestObservable) {
const results: TestMessage[] = [];
let subscription: Subscription;
const scheduler = getTestScheduler();

scheduler.schedule(() => {
subscription = actual.subscribe(
(x: any) => {
let value = x;

// Support Observable-of-Observables
if (x instanceof Observable) {
value = materializeInnerObservable(value, scheduler.frame);
}

results.push({
frame: scheduler.frame,
notification: Notification.createNext(value),
});
},
(err: any) => {
results.push({
frame: scheduler.frame,
notification: Notification.createError(err),
});
},
() => {
results.push({
frame: scheduler.frame,
notification: Notification.createComplete(),
});
},
);
});
scheduler.flush();

const expected = TestScheduler.parseMarbles(
fixture.marbles,
fixture.values,
fixture.error,
true,
);

expect(results).toEqual(expected);

return { pass: true };
},
Expand Down
14 changes: 8 additions & 6 deletions spec/integration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/mapTo';

import { of } from 'rxjs/observable/of';
import { timer } from 'rxjs/observable/timer';
import { Subject } from 'rxjs/Subject';

import {
hot,
cold,
time,
getTestScheduler,
resetTestScheduler,
hot,
initTestScheduler,
resetTestScheduler,
time,
} from '../index';
import { of } from 'rxjs/observable/of';
import { timer } from 'rxjs/observable/timer';
import { Subject } from 'rxjs/Subject';

describe('Integration', () => {
it('should work with a cold observable', () => {
Expand Down
1 change: 1 addition & 0 deletions src/scheduler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TestScheduler } from 'rxjs/testing/TestScheduler';

import { observableMatcher } from './matcher';

let scheduler: TestScheduler | null;
Expand Down
2 changes: 1 addition & 1 deletion src/test-observables.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Scheduler } from 'rxjs/Scheduler';
import { Observable } from 'rxjs/Observable';

import { getTestScheduler } from './scheduler';

export class TestColdObservable extends Observable<any> {
Expand Down

0 comments on commit 31f6b76

Please sign in to comment.