Skip to content

Commit

Permalink
Fix RxJS scheduler is corrupted after fakeSchedulers usage (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
zvirja authored and cartant committed Sep 13, 2019
1 parent 2994226 commit e1d9c83
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 30 deletions.
10 changes: 10 additions & 0 deletions fixtures/jasmine-angular/passing-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,14 @@ describe("fakeSchedulers", () => {
expect(received).toBe(1);
})
);

it("should not corrupt rxjs scheduler", () => {
fakeSchedulers(() => {})();

expect(() =>
of(undefined)
.pipe(delay(100))
.subscribe()
).not.toThrowError();
});
});
26 changes: 17 additions & 9 deletions source/fake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,29 @@

import { asapScheduler, asyncScheduler } from "rxjs";

export function fakeSchedulers(fakeTest: () => any): () => any;
export function fakeSchedulers<T>(fakeTest: (t: T) => any): (t: T) => any;
export function fakeSchedulers(
fakeTest: (...args: any[]) => any
fakeTest: () => any,
nowImpl?: () => number
): () => any;
export function fakeSchedulers<T>(
fakeTest: (t: T) => any,
nowImpl?: () => number
): (t: T) => any;
export function fakeSchedulers(
fakeTest: (...args: any[]) => any,
nowImpl?: () => number
): (...args: any[]) => any {
return (...args: any[]) => {
const origSchedule = asapScheduler.schedule;
const origNow = asyncScheduler.now;
try {
asapScheduler.schedule = asyncScheduler.schedule.bind(
asyncScheduler
) as any;
asyncScheduler.now = () => Date.now();
asapScheduler.schedule = asyncScheduler.schedule.bind(asyncScheduler);
asyncScheduler.now = nowImpl || (() => Date.now());

return fakeTest(...args);
} finally {
delete asapScheduler.schedule;
delete asyncScheduler.now;
asapScheduler.schedule = origSchedule;
asyncScheduler.now = origNow;
}
};
}
13 changes: 5 additions & 8 deletions source/jasmine/angular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,20 @@
*/

import { fakeAsync, tick } from "@angular/core/testing";
import { asyncScheduler } from "rxjs";
import { fakeSchedulers as _fakeSchedulers } from "../fake";

export function fakeSchedulers(
fakeTest: (tick: (milliseconds: number) => void) => any
): () => any {
return fakeAsync(() => {
try {
asyncScheduler.now = () => Date.now();
return fakeAsync(
_fakeSchedulers(() => {
return fakeTest(milliseconds => {
/*tslint:disable-next-line:no-console*/
console.log(
"The tick parameter passed to the fakeSchedulers test is deprecated; call the @angular/core/testing tick function instead. See the examples for the intended usage."
);
tick(milliseconds);
});
} finally {
delete asyncScheduler.now;
}
});
})
);
}
20 changes: 7 additions & 13 deletions source/jest/fake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,21 @@
* can be found in the LICENSE file at https://github.com/cartant/rxjs-marbles
*/

import { asapScheduler, asyncScheduler } from "rxjs";
import { fakeSchedulers as _fakeSchedulers } from "../fake";

declare const jest: any;

export function fakeSchedulers(
fakeTest: (advance: (milliseconds: number) => void) => any
): () => any {
return () => {
try {
let fakeTime = 0;
asapScheduler.schedule = asyncScheduler.schedule.bind(
asyncScheduler
) as any;
asyncScheduler.now = () => fakeTime;
let fakeTime = 0;
return _fakeSchedulers(
() => {
return fakeTest(milliseconds => {
fakeTime += milliseconds;
jest.advanceTimersByTime(milliseconds);
});
} finally {
delete asapScheduler.schedule;
delete asyncScheduler.now;
}
};
},
() => fakeTime
);
}

0 comments on commit e1d9c83

Please sign in to comment.