Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
feat(spec): add an option to FakeAsyncTestZoneSpec to flush periodic …
Browse files Browse the repository at this point in the history
…timers (#857)

A flush with flushPeriodic set to true will flush till all the pending
timers in the queue have been visited atleast once.
  • Loading branch information
vikerman authored and mhevery committed Jul 27, 2017
1 parent eca04b0 commit 5c5ca1a
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 8 deletions.
31 changes: 24 additions & 7 deletions lib/zone-spec/fake-async-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,22 +91,39 @@
this._currentTime = finalTime;
}

flush(limit: number = 20): number {
flush(limit: number = 20, flushPeriodic = false): number {
const startTime = this._currentTime;
let count = 0;
let seenTimers: number[] = [];
while (this._schedulerQueue.length > 0) {
count++;
if (count > limit) {
throw new Error(
'flush failed after reaching the limit of ' + limit +
' tasks. Does your code use a polling timeout?');
}
// If the only remaining tasks are periodic, finish flushing.
if (!(this._schedulerQueue.filter(task => !task.isPeriodic && !task.isRequestAnimationFrame)
.length)) {
break;
if (!flushPeriodic) {
// flush only non-periodic timers.
// If the only remaining tasks are periodic(or requestAnimationFrame), finish flushing.
if (this._schedulerQueue.filter(task => !task.isPeriodic && !task.isRequestAnimationFrame)
.length === 0) {
break;
}
} else {
// flushPeriodic has been requested.
// Stop when all timer id-s have been seen at least once.
if (this._schedulerQueue
.filter(
task =>
seenTimers.indexOf(task.id) === -1 || this._currentTime === task.endTime)
.length === 0) {
break;
}
}
let current = this._schedulerQueue.shift();
if (seenTimers.indexOf(current.id) === -1) {
seenTimers.push(current.id);
}
this._currentTime = current.endTime;
let retval = current.func.apply(global, current.args);
if (!retval) {
Expand Down Expand Up @@ -254,10 +271,10 @@
flushErrors();
}

flush(limit?: number): number {
flush(limit?: number, flushPeriodic?: boolean): number {
FakeAsyncTestZoneSpec.assertInZone();
this.flushMicrotasks();
let elapsed = this._scheduler.flush(limit);
let elapsed = this._scheduler.flush(limit, flushPeriodic);
if (this._lastError !== null) {
this._resetLastErrorAndThrow();
}
Expand Down
59 changes: 58 additions & 1 deletion test/zone-spec/fake-async-test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ describe('FakeAsyncTestZoneSpec', () => {
'flush failed after reaching the limit of 20 tasks. Does your code use a polling timeout?');
});

it('accepts a custom limit', function() {
it('accepts a custom limit', () => {
expect(() => {
fakeAsyncTestZone.run(() => {
let z = 0;
Expand All @@ -521,6 +521,42 @@ describe('FakeAsyncTestZoneSpec', () => {
.toThrowError(
'flush failed after reaching the limit of 10 tasks. Does your code use a polling timeout?');
});

it('can flush periodic timers if flushPeriodic is true', () => {
fakeAsyncTestZone.run(() => {
let x = 0;

setInterval(() => {
x++;
}, 10);

let elapsed = testZoneSpec.flush(20, true);

expect(elapsed).toEqual(10);
expect(x).toEqual(1);
});
});

it('can flush multiple periodic timers if flushPeriodic is true', () => {
fakeAsyncTestZone.run(() => {
let x = 0;
let y = 0;

setInterval(() => {
x++;
}, 10);

setInterval(() => {
y++;
}, 100);

let elapsed = testZoneSpec.flush(20, true);

expect(elapsed).toEqual(100);
expect(x).toEqual(10);
expect(y).toEqual(1);
});
});
});

describe('outside of FakeAsync Zone', () => {
Expand Down Expand Up @@ -578,6 +614,27 @@ describe('FakeAsyncTestZoneSpec', () => {
expect(ran).toEqual(false);
});
});
it('is not flushed when flushPeriodic is false', () => {
let ran = false;
fakeAsyncTestZone.run(() => {
requestAnimationFrame(() => {
ran = true;
});
testZoneSpec.flush(20);
expect(ran).toEqual(false);
});
});
it('is flushed when flushPeriodic is true', () => {
let ran = false;
fakeAsyncTestZone.run(() => {
requestAnimationFrame(() => {
ran = true;
});
const elapsed = testZoneSpec.flush(20, true);
expect(elapsed).toEqual(16);
expect(ran).toEqual(true);
});
});
}));
});
});
Expand Down

0 comments on commit 5c5ca1a

Please sign in to comment.