diff --git a/spec/schedulers/VirtualTimeScheduler-spec.ts b/spec/schedulers/VirtualTimeScheduler-spec.ts index 0b952d1f94..6d43c33534 100644 --- a/spec/schedulers/VirtualTimeScheduler-spec.ts +++ b/spec/schedulers/VirtualTimeScheduler-spec.ts @@ -1,6 +1,5 @@ import { expect } from 'chai'; -import * as Rx from 'rxjs/Rx'; -import { SchedulerAction, Subscription, VirtualAction, VirtualTimeScheduler } from 'rxjs'; +import { SchedulerAction, VirtualAction, VirtualTimeScheduler } from 'rxjs'; /** @test {VirtualTimeScheduler} */ describe('VirtualTimeScheduler', () => { @@ -67,7 +66,7 @@ describe('VirtualTimeScheduler', () => { let count = 0; const expected = [100, 200, 300]; - v.schedule(function(this: SchedulerAction, state: string) { + v.schedule(function (this: SchedulerAction, state: string) { if (++count === 3) { return; } @@ -82,12 +81,60 @@ describe('VirtualTimeScheduler', () => { it('should not execute virtual actions that have been rescheduled before flush', () => { const v = new VirtualTimeScheduler(); - let messages: string[] = []; - let action: VirtualAction = > v.schedule(function(state: string) { - messages.push(state); - }, 10, 'first message'); - action = > action.schedule('second message' , 10); + const messages: string[] = []; + + const action: VirtualAction = > v.schedule( + state => messages.push(state), + 10, + 'first message' + ); + + action.schedule('second message', 10); v.flush(); + expect(messages).to.deep.equal(['second message']); }); + + it('should execute only those virtual actions that fall into the maxFrames timespan', function () { + const MAX_FRAMES = 50; + const v = new VirtualTimeScheduler(VirtualAction, MAX_FRAMES); + const messages: string[] = ['first message', 'second message', 'third message']; + + const actualMessages: string[] = []; + + messages.forEach((message, index) => { + v.schedule( + (state: string) => actualMessages.push(state), + index * MAX_FRAMES, + message + ); + }); + + v.flush(); + + expect(actualMessages).to.deep.equal(['first message', 'second message']); + expect(v.actions.map(a => a.state)).to.deep.equal(['third message']); + }); + + it('should pick up actions execution where it left off after reaching previous maxFrames limit', function () { + const MAX_FRAMES = 50; + const v = new VirtualTimeScheduler(VirtualAction, MAX_FRAMES); + const messages: string[] = ['first message', 'second message', 'third message']; + + const actualMessages: string[] = []; + + messages.forEach((message, index) => { + v.schedule( + state => actualMessages.push(state), + index * MAX_FRAMES, + message + ); + }); + + v.flush(); + v.maxFrames = 2 * MAX_FRAMES; + v.flush(); + + expect(actualMessages).to.deep.equal(messages); + }); }); diff --git a/src/internal/scheduler/VirtualTimeScheduler.ts b/src/internal/scheduler/VirtualTimeScheduler.ts index cef81694af..7017ea5352 100644 --- a/src/internal/scheduler/VirtualTimeScheduler.ts +++ b/src/internal/scheduler/VirtualTimeScheduler.ts @@ -25,7 +25,10 @@ export class VirtualTimeScheduler extends AsyncScheduler { const {actions, maxFrames} = this; let error: any, action: AsyncAction; - while ((action = actions.shift()) && (this.frame = action.delay) <= maxFrames) { + while ((action = actions[0]) && action.delay <= maxFrames) { + actions.shift(); + this.frame = action.delay; + if (error = action.execute(action.state, action.delay)) { break; }