feat(testability): hook zone into whenstable api with async support

closes(#428)
This commit is contained in:
Hank Duan
2015-07-24 12:46:12 -07:00
parent 19d8b221b4
commit a8b75c3d41
9 changed files with 511 additions and 54 deletions
@@ -1,41 +1,212 @@
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach} from 'angular2/test_lib';
import {
AsyncTestCompleter,
inject,
describe,
ddescribe,
it,
iit,
xit,
xdescribe,
expect,
beforeEach,
SpyObject
} from 'angular2/test_lib';
import {Testability} from 'angular2/src/core/testability/testability';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {normalizeBlank} from 'angular2/src/facade/lang';
import {PromiseWrapper} from 'angular2/src/facade/async';
// Schedules a microtasks (using a resolved promise .then())
function microTask(fn: Function): void {
PromiseWrapper.resolve(null).then((_) => { fn(); });
}
class MockNgZone extends NgZone {
_onTurnStart: () => void;
_onEventDone: () => void;
constructor() { super({enableLongStackTrace: false}); }
start(): void { this._onTurnStart(); }
finish(): void { this._onEventDone(); }
overrideOnTurnStart(onTurnStartFn: Function): void {
this._onTurnStart = normalizeBlank(onTurnStartFn);
}
overrideOnEventDone(onEventDoneFn: Function, waitForAsync: boolean = false): void {
this._onEventDone = normalizeBlank(onEventDoneFn);
}
}
export function main() {
describe('Testability', () => {
var testability, executed;
var testability, execute, ngZone;
beforeEach(() => {
testability = new Testability();
executed = false;
ngZone = new MockNgZone();
testability = new Testability(ngZone);
execute = new SpyObject().spy('execute');
});
it('should start with a pending count of 0',
() => { expect(testability.getPendingCount()).toEqual(0); });
describe('Pending count logic', () => {
it('should start with a pending count of 0',
() => { expect(testability.getPendingRequestCount()).toEqual(0); });
it('should fire whenstable callbacks if pending count is 0', () => {
testability.whenStable(() => executed = true);
expect(executed).toBe(true);
it('should fire whenstable callbacks if pending count is 0',
inject([AsyncTestCompleter], (async) => {
testability.whenStable(execute);
microTask(() => {
expect(execute).toHaveBeenCalled();
async.done();
});
}));
it('should not fire whenstable callbacks synchronously if pending count is 0', () => {
testability.whenStable(execute);
expect(execute).not.toHaveBeenCalled();
});
it('should not call whenstable callbacks when there are pending counts',
inject([AsyncTestCompleter], (async) => {
testability.increasePendingRequestCount();
testability.increasePendingRequestCount();
testability.whenStable(execute);
microTask(() => {
expect(execute).not.toHaveBeenCalled();
testability.decreasePendingRequestCount();
microTask(() => {
expect(execute).not.toHaveBeenCalled();
async.done();
});
});
}));
it('should fire whenstable callbacks when pending drops to 0',
inject([AsyncTestCompleter], (async) => {
testability.increasePendingRequestCount();
testability.whenStable(execute);
microTask(() => {
expect(execute).not.toHaveBeenCalled();
testability.decreasePendingRequestCount();
microTask(() => {
expect(execute).toHaveBeenCalled();
async.done();
});
});
}));
it('should not fire whenstable callbacks synchronously when pending drops to 0', () => {
testability.increasePendingRequestCount();
testability.whenStable(execute);
testability.decreasePendingRequestCount();
expect(execute).not.toHaveBeenCalled();
});
});
it('should not call whenstable callbacks when there are pending counts', () => {
testability.increaseCount(2);
testability.whenStable(() => executed = true);
describe('NgZone callback logic', () => {
it('should start being ready',
() => { expect(testability.isAngularEventPending()).toEqual(false); });
expect(executed).toBe(false);
testability.increaseCount(-1);
expect(executed).toBe(false);
});
it('should fire whenstable callback if event is already finished',
inject([AsyncTestCompleter], (async) => {
ngZone.start();
ngZone.finish();
testability.whenStable(execute);
it('should fire whenstable callbacks when pending drops to 0', () => {
testability.increaseCount(2);
testability.whenStable(() => executed = true);
microTask(() => {
expect(execute).toHaveBeenCalled();
async.done();
});
}));
expect(executed).toBe(false);
it('should not fire whenstable callbacks synchronously if event is already finished', () => {
ngZone.start();
ngZone.finish();
testability.whenStable(execute);
testability.increaseCount(-2);
expect(executed).toBe(true);
expect(execute).not.toHaveBeenCalled();
});
it('should fire whenstable callback when event finishes',
inject([AsyncTestCompleter], (async) => {
ngZone.start();
testability.whenStable(execute);
microTask(() => {
expect(execute).not.toHaveBeenCalled();
ngZone.finish();
microTask(() => {
expect(execute).toHaveBeenCalled();
async.done();
});
});
}));
it('should not fire whenstable callbacks synchronously when event finishes', () => {
ngZone.start();
testability.whenStable(execute);
ngZone.finish();
expect(execute).not.toHaveBeenCalled();
});
it('should not fire whenstable callback when event did not finish',
inject([AsyncTestCompleter], (async) => {
ngZone.start();
testability.increasePendingRequestCount();
testability.whenStable(execute);
microTask(() => {
expect(execute).not.toHaveBeenCalled();
testability.decreasePendingRequestCount();
microTask(() => {
expect(execute).not.toHaveBeenCalled();
ngZone.finish();
microTask(() => {
expect(execute).toHaveBeenCalled();
async.done();
});
});
});
}));
it('should not fire whenstable callback when there are pending counts',
inject([AsyncTestCompleter], (async) => {
ngZone.start();
testability.increasePendingRequestCount();
testability.increasePendingRequestCount();
testability.whenStable(execute);
microTask(() => {
expect(execute).not.toHaveBeenCalled();
ngZone.finish();
microTask(() => {
expect(execute).not.toHaveBeenCalled();
testability.decreasePendingRequestCount();
microTask(() => {
expect(execute).not.toHaveBeenCalled();
testability.decreasePendingRequestCount();
microTask(() => {
expect(execute).toHaveBeenCalled();
async.done();
});
});
});
});
}));
});
});
}