From bab81a98314291f02a09baf96d0b85a0f8e62e9d Mon Sep 17 00:00:00 2001 From: Vikram Subramanian Date: Mon, 18 Apr 2016 16:04:35 -0700 Subject: [PATCH] feat(test): Implement fakeAsync using the FakeAsyncTestZoneSpec from zone.js. Update the version of zone.js to @0.6.12 that contains the new FakeAsyncTestZoneSpec. The new fakeAsync zone handles errors better and clearPendingTimers() is no longer required to be called after handling an error and is deprecated. The fakeAsync test zone will now throw an error if an XHR is attemtped within the test since that cannot be controlled synchronously in the test(Need to be mocked out with a service implementation that doesn't involve XHRs). This commit also allows fakeAsync to wrap inject to make it consistent with async test zone. BREAKING CHANGE: inject can no longer wrap fakeAsync while fakeAsync can wrap inject. So the order in existing tests with inject and fakeAsync has to be switched as follows: Before: ``` inject([...], fakeAsync((...) => {...})) ``` After: ``` fakeAsync(inject([...], (...) => {...})) ``` Closes #8142 --- karma-js.conf.js | 1 + modules/angular2/src/testing/fake_async.dart | 42 +- modules/angular2/src/testing/fake_async.ts | 168 ++---- modules/angular2/src/testing/test_injector.ts | 4 +- modules/angular2/src/testing/testing.ts | 2 +- .../test/common/forms/integration_spec.ts | 542 +++++++++--------- .../core/linker/integration_dart_spec.dart | 4 +- .../test/core/linker/integration_spec.ts | 150 +++-- .../test/platform/browser/xhr_cache_spec.ts | 14 +- .../angular2/test/testing/fake_async_spec.ts | 3 +- .../testing/testing_public_browser_spec.ts | 13 +- .../test/testing/testing_public_spec.ts | 9 + npm-shrinkwrap.clean.json | 5 +- npm-shrinkwrap.json | 10 +- tools/cjs-jasmine/index.js | 1 + 15 files changed, 448 insertions(+), 520 deletions(-) diff --git a/karma-js.conf.js b/karma-js.conf.js index fbad50dd98..437a1ae2ec 100644 --- a/karma-js.conf.js +++ b/karma-js.conf.js @@ -21,6 +21,7 @@ module.exports = function(config) { 'node_modules/zone.js/dist/long-stack-trace-zone.js', 'node_modules/zone.js/dist/jasmine-patch.js', 'node_modules/zone.js/dist/async-test.js', + 'node_modules/zone.js/dist/fake-async-test.js', // Including systemjs because it defines `__eval`, which produces correct stack traces. 'modules/angular2/src/testing/shims_for_IE.js', diff --git a/modules/angular2/src/testing/fake_async.dart b/modules/angular2/src/testing/fake_async.dart index 2f9fe925a2..4dcf294c59 100644 --- a/modules/angular2/src/testing/fake_async.dart +++ b/modules/angular2/src/testing/fake_async.dart @@ -4,6 +4,8 @@ import 'dart:async' show runZoned, ZoneSpecification; import 'package:quiver/testing/async.dart' as quiver; import 'package:angular2/src/facade/exceptions.dart' show BaseException; +import 'test_injector.dart' show getTestInjector, FunctionWithParamTokens; + const _u = const Object(); quiver.FakeAsync _fakeAsync = null; @@ -16,24 +18,38 @@ quiver.FakeAsync _fakeAsync = null; * If there are any pending timers at the end of the function, an exception * will be thrown. * + * Can be used to wrap inject() calls. + * * Returns a `Function` that wraps [fn]. */ -Function fakeAsync(Function fn) { +Function fakeAsync(dynamic /* Function | FunctionWithParamTokens */ fn) { if (_fakeAsync != null) { throw 'fakeAsync() calls can not be nested'; } - return ( - [a0 = _u, - a1 = _u, - a2 = _u, - a3 = _u, - a4 = _u, - a5 = _u, - a6 = _u, - a7 = _u, - a8 = _u, - a9 = _u]) { + Function innerFn = null; + if (fn is FunctionWithParamTokens) { + if (fn.isAsync) { + throw 'Cannot wrap async test with fakeAsync'; + } + innerFn = () { getTestInjector().execute(fn); }; + } else if (fn is Function) { + innerFn = fn; + } else { + throw 'fakeAsync can wrap only test functions but got object of type ' + + fn.runtimeType.toString(); + } + + return ([a0 = _u, + a1 = _u, + a2 = _u, + a3 = _u, + a4 = _u, + a5 = _u, + a6 = _u, + a7 = _u, + a8 = _u, + a9 = _u]) { // runZoned() to install a custom exception handler that re-throws return runZoned(() { return new quiver.FakeAsync().run((quiver.FakeAsync async) { @@ -42,7 +58,7 @@ Function fakeAsync(Function fn) { List args = [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9] .takeWhile((a) => a != _u) .toList(); - var res = Function.apply(fn, args); + var res = Function.apply(innerFn, args); _fakeAsync.flushMicrotasks(); if (async.periodicTimerCount > 0) { diff --git a/modules/angular2/src/testing/fake_async.ts b/modules/angular2/src/testing/fake_async.ts index fca8d06467..1073a2e878 100644 --- a/modules/angular2/src/testing/fake_async.ts +++ b/modules/angular2/src/testing/fake_async.ts @@ -1,59 +1,7 @@ -import {global} from 'angular2/src/facade/lang'; import {BaseException} from 'angular2/src/facade/exceptions'; -import {ListWrapper} from 'angular2/src/facade/collection'; +import {getTestInjector, FunctionWithParamTokens} from './test_injector'; -var _scheduler; -var _microtasks: Function[] = []; -var _pendingPeriodicTimers: number[] = []; -var _pendingTimers: number[] = []; - -class FakeAsyncZoneSpec implements ZoneSpec { - static assertInZone(): void { - if (!Zone.current.get('inFakeAsyncZone')) { - throw new Error('The code should be running in the fakeAsync zone to call this function'); - } - } - - name: string = 'fakeAsync'; - - properties: {[key: string]: any} = {'inFakeAsyncZone': true}; - - onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task { - switch (task.type) { - case 'microTask': - _microtasks.push(task.invoke); - break; - case 'macroTask': - switch (task.source) { - case 'setTimeout': - task.data['handleId'] = _setTimeout(task.invoke, task.data['delay'], task.data['args']); - break; - case 'setInterval': - task.data['handleId'] = - _setInterval(task.invoke, task.data['delay'], task.data['args']); - break; - default: - task = delegate.scheduleTask(target, task); - } - break; - case 'eventTask': - task = delegate.scheduleTask(target, task); - break; - } - return task; - } - - onCancelTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): any { - switch (task.source) { - case 'setTimeout': - return _clearTimeout(task.data['handleId']); - case 'setInterval': - return _clearInterval(task.data['handleId']); - default: - return delegate.scheduleTask(target, task); - } - } -} +let _FakeAsyncTestZoneSpecType = Zone['FakeAsyncTestZoneSpec']; /** * Wraps a function to be executed in the fakeAsync zone: @@ -62,6 +10,8 @@ class FakeAsyncZoneSpec implements ZoneSpec { * * If there are any pending timers at the end of the function, an exception will be thrown. * + * Can be used to wrap inject() calls. + * * ## Example * * {@example testing/ts/fake_async.ts region='basic'} @@ -69,57 +19,63 @@ class FakeAsyncZoneSpec implements ZoneSpec { * @param fn * @returns {Function} The function wrapped to be executed in the fakeAsync zone */ -export function fakeAsync(fn: Function): Function { - if (Zone.current.get('inFakeAsyncZone')) { - throw new Error('fakeAsync() calls can not be nested'); +export function fakeAsync(fn: Function | FunctionWithParamTokens): Function { + if (Zone.current.get('FakeAsyncTestZoneSpec') != null) { + throw new BaseException('fakeAsync() calls can not be nested'); } - var fakeAsyncZone = Zone.current.fork(new FakeAsyncZoneSpec()); + let fakeAsyncTestZoneSpec = new _FakeAsyncTestZoneSpecType(); + let fakeAsyncZone = Zone.current.fork(fakeAsyncTestZoneSpec); + + let innerTestFn: Function = null; + + if (fn instanceof FunctionWithParamTokens) { + if (fn.isAsync) { + throw new BaseException('Cannot wrap async test with fakeAsync'); + } + innerTestFn = () => { getTestInjector().execute(fn as FunctionWithParamTokens); }; + } else { + innerTestFn = fn; + } return function(...args) { - // TODO(tbosch): This class should already be part of the jasmine typings but it is not... - _scheduler = new (jasmine).DelayedFunctionScheduler(); - clearPendingTimers(); - let res = fakeAsyncZone.run(() => { - let res = fn(...args); + let res = innerTestFn(...args); flushMicrotasks(); return res; }); - if (_pendingPeriodicTimers.length > 0) { + if (fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) { + throw new BaseException(`${fakeAsyncTestZoneSpec.pendingPeriodicTimers.length} ` + + `periodic timer(s) still in the queue.`); + } + + if (fakeAsyncTestZoneSpec.pendingTimers.length > 0) { throw new BaseException( - `${_pendingPeriodicTimers.length} periodic timer(s) still in the queue.`); + `${fakeAsyncTestZoneSpec.pendingTimers.length} timer(s) still in the queue.`); } - - if (_pendingTimers.length > 0) { - throw new BaseException(`${_pendingTimers.length} timer(s) still in the queue.`); - } - - _scheduler = null; - ListWrapper.clear(_microtasks); - return res; + }; +} + +function _getFakeAsyncZoneSpec(): any { + let zoneSpec = Zone.current.get('FakeAsyncTestZoneSpec'); + if (zoneSpec == null) { + throw new Error('The code should be running in the fakeAsync zone to call this function'); } + return zoneSpec; } /** * Clear the queue of pending timers and microtasks. + * Tests no longer need to call this explicitly. * - * Useful for cleaning up after an asynchronous test passes. - * - * ## Example - * - * {@example testing/ts/fake_async.ts region='pending'} + * @deprecated */ export function clearPendingTimers(): void { - // TODO we should fix tick to dequeue the failed timer instead of relying on clearPendingTimers - ListWrapper.clear(_microtasks); - ListWrapper.clear(_pendingPeriodicTimers); - ListWrapper.clear(_pendingTimers); + // Do nothing. } - /** * Simulates the asynchronous passage of time for the timers in the fakeAsync zone. * @@ -133,54 +89,12 @@ export function clearPendingTimers(): void { * @param {number} millis Number of millisecond, defaults to 0 */ export function tick(millis: number = 0): void { - FakeAsyncZoneSpec.assertInZone(); - flushMicrotasks(); - _scheduler.tick(millis); + _getFakeAsyncZoneSpec().tick(millis); } /** * Flush any pending microtasks. */ export function flushMicrotasks(): void { - FakeAsyncZoneSpec.assertInZone(); - while (_microtasks.length > 0) { - var microtask = ListWrapper.removeAt(_microtasks, 0); - microtask(); - } -} - -function _setTimeout(fn: Function, delay: number, args: any[]): number { - var cb = _fnAndFlush(fn); - var id = _scheduler.scheduleFunction(cb, delay, args); - _pendingTimers.push(id); - _scheduler.scheduleFunction(_dequeueTimer(id), delay); - return id; -} - -function _clearTimeout(id: number) { - _dequeueTimer(id); - return _scheduler.removeFunctionWithId(id); -} - -function _setInterval(fn: Function, interval: number, ...args) { - var cb = _fnAndFlush(fn); - var id = _scheduler.scheduleFunction(cb, interval, args, true); - _pendingPeriodicTimers.push(id); - return id; -} - -function _clearInterval(id: number) { - ListWrapper.remove(_pendingPeriodicTimers, id); - return _scheduler.removeFunctionWithId(id); -} - -function _fnAndFlush(fn: Function): Function { - return (...args) => { - fn.apply(global, args); - flushMicrotasks(); - } -} - -function _dequeueTimer(id: number): Function { - return function() { ListWrapper.remove(_pendingTimers, id); } + _getFakeAsyncZoneSpec().flushMicrotasks(); } diff --git a/modules/angular2/src/testing/test_injector.ts b/modules/angular2/src/testing/test_injector.ts index 7379e51181..ae8cc75784 100644 --- a/modules/angular2/src/testing/test_injector.ts +++ b/modules/angular2/src/testing/test_injector.ts @@ -195,7 +195,7 @@ function emptyArray(): Array { } export class FunctionWithParamTokens { - constructor(private _tokens: any[], private _fn: Function, public isAsync: boolean, + constructor(private _tokens: any[], public fn: Function, public isAsync: boolean, public additionalProviders: () => any = emptyArray) {} /** @@ -203,7 +203,7 @@ export class FunctionWithParamTokens { */ execute(injector: ReflectiveInjector): any { var params = this._tokens.map(t => injector.get(t)); - return FunctionWrapper.apply(this._fn, params); + return FunctionWrapper.apply(this.fn, params); } hasToken(token: any): boolean { return this._tokens.indexOf(token) > -1; } diff --git a/modules/angular2/src/testing/testing.ts b/modules/angular2/src/testing/testing.ts index 88ae7b30da..0d71843276 100644 --- a/modules/angular2/src/testing/testing.ts +++ b/modules/angular2/src/testing/testing.ts @@ -87,7 +87,7 @@ export type AsyncTestFn = (done: () => void) => void; /** * Signature for any simple testing function. */ -export type AnyTestFn = SyncTestFn | AsyncTestFn; +export type AnyTestFn = SyncTestFn | AsyncTestFn | Function; var jsmBeforeEach = _global.beforeEach; var jsmIt = _global.it; diff --git a/modules/angular2/test/common/forms/integration_spec.ts b/modules/angular2/test/common/forms/integration_spec.ts index 956549f96c..4634b3118d 100644 --- a/modules/angular2/test/common/forms/integration_spec.ts +++ b/modules/angular2/test/common/forms/integration_spec.ts @@ -120,29 +120,28 @@ export function main() { })); it("should emit ngSubmit event on submit", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
{{name}}
`; - var fixture: ComponentFixture; + var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); - fixture.debugElement.componentInstance.form = new ControlGroup({}); - fixture.debugElement.componentInstance.name = 'old'; + fixture.debugElement.componentInstance.form = new ControlGroup({}); + fixture.debugElement.componentInstance.name = 'old'; - tick(); + tick(); - var form = fixture.debugElement.query(By.css("form")); - dispatchEvent(form.nativeElement, "submit"); + var form = fixture.debugElement.query(By.css("form")); + dispatchEvent(form.nativeElement, "submit"); - tick(); - expect(fixture.debugElement.componentInstance.name).toEqual('updated'); - }))); + tick(); + expect(fixture.debugElement.componentInstance.name).toEqual('updated'); + }))); it("should work with single controls", inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { @@ -494,28 +493,28 @@ export function main() { })); it("with a dynamic list of options", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
`; - var fixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (compFixture) => fixture = compFixture); - tick(); + var fixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((compFixture) => fixture = + compFixture); + tick(); - fixture.debugElement.componentInstance.form = - new ControlGroup({"city": new Control("NYC")}); + fixture.debugElement.componentInstance.form = + new ControlGroup({"city": new Control("NYC")}); - fixture.debugElement.componentInstance.data = ['SF', 'NYC']; - fixture.detectChanges(); - tick(); + fixture.debugElement.componentInstance.data = ['SF', 'NYC']; + fixture.detectChanges(); + tick(); - var select = fixture.debugElement.query(By.css("select")); - expect(select.nativeElement.value).toEqual("NYC"); - }))); + var select = fixture.debugElement.query(By.css("select")); + expect(select.nativeElement.value).toEqual("NYC"); + }))); it("with option values that are objects", inject([TestComponentBuilder, AsyncTestCompleter], @@ -783,33 +782,33 @@ export function main() { })); it("should use async validators defined in the html", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var form = new ControlGroup({"login": new Control("")}); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var form = new ControlGroup({"login": new Control("")}); - var t = `
+ var t = `
`; - var rootTC; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => rootTC = root); - tick(); + var rootTC; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => rootTC = root); + tick(); - rootTC.debugElement.componentInstance.form = form; - rootTC.detectChanges(); + rootTC.debugElement.componentInstance.form = form; + rootTC.detectChanges(); - expect(form.pending).toEqual(true); + expect(form.pending).toEqual(true); - tick(100); + tick(100); - expect(form.hasError("uniqLogin", ["login"])).toEqual(true); + expect(form.hasError("uniqLogin", ["login"])).toEqual(true); - var input = rootTC.debugElement.query(By.css("input")); - input.nativeElement.value = "expected"; - dispatchEvent(input.nativeElement, "input"); - tick(100); + var input = rootTC.debugElement.query(By.css("input")); + input.nativeElement.value = "expected"; + dispatchEvent(input.nativeElement, "input"); + tick(100); - expect(form.valid).toEqual(true); - }))); + expect(form.valid).toEqual(true); + }))); it("should use sync validators defined in the model", inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { @@ -835,40 +834,38 @@ export function main() { })); it("should use async validators defined in the model", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var control = - new Control("", Validators.required, uniqLoginAsyncValidator("expected")); - var form = new ControlGroup({"login": control}); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var control = new Control("", Validators.required, uniqLoginAsyncValidator("expected")); + var form = new ControlGroup({"login": control}); - var t = `
+ var t = `
`; - var fixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => fixture = - root); - tick(); + var fixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => fixture = root); + tick(); - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - expect(form.hasError("required", ["login"])).toEqual(true); + expect(form.hasError("required", ["login"])).toEqual(true); - var input = fixture.debugElement.query(By.css("input")); - input.nativeElement.value = "wrong value"; - dispatchEvent(input.nativeElement, "input"); + var input = fixture.debugElement.query(By.css("input")); + input.nativeElement.value = "wrong value"; + dispatchEvent(input.nativeElement, "input"); - expect(form.pending).toEqual(true); - tick(); + expect(form.pending).toEqual(true); + tick(); - expect(form.hasError("uniqLogin", ["login"])).toEqual(true); + expect(form.hasError("uniqLogin", ["login"])).toEqual(true); - input.nativeElement.value = "expected"; - dispatchEvent(input.nativeElement, "input"); - tick(); + input.nativeElement.value = "expected"; + dispatchEvent(input.nativeElement, "input"); + tick(); - expect(form.valid).toEqual(true); - }))); + expect(form.valid).toEqual(true); + }))); }); describe("nested forms", () => { @@ -919,97 +916,92 @@ export function main() { }); it("should support ngModel for complex forms", - inject( - [TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var form = new ControlGroup({"name": new Control("")}); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var form = new ControlGroup({"name": new Control("")}); - var t = - `
`; + var t = + `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); - fixture.debugElement.componentInstance.name = 'oldValue'; - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + fixture.debugElement.componentInstance.name = 'oldValue'; + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css("input")).nativeElement; - expect(input.value).toEqual("oldValue"); + var input = fixture.debugElement.query(By.css("input")).nativeElement; + expect(input.value).toEqual("oldValue"); - input.value = "updatedValue"; - dispatchEvent(input, "input"); + input.value = "updatedValue"; + dispatchEvent(input, "input"); - tick(); - expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); - }))); + tick(); + expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); + }))); it("should support ngModel for single fields", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var form = new Control(""); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var form = new Control(""); - var t = `
`; + var t = `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.form = form; - fixture.debugElement.componentInstance.name = "oldValue"; - fixture.detectChanges(); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.form = form; + fixture.debugElement.componentInstance.name = "oldValue"; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css("input")).nativeElement; - expect(input.value).toEqual("oldValue"); + var input = fixture.debugElement.query(By.css("input")).nativeElement; + expect(input.value).toEqual("oldValue"); - input.value = "updatedValue"; - dispatchEvent(input, "input"); - tick(); + input.value = "updatedValue"; + dispatchEvent(input, "input"); + tick(); - expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); - }))); + expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); + }))); describe("template-driven forms", () => { it("should add new controls and control groups", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.name = null; - fixture.detectChanges(); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.name = null; + fixture.detectChanges(); - var form = fixture.debugElement.children[0].inject(NgForm); - expect(form.controls['user']).not.toBeDefined(); + var form = fixture.debugElement.children[0].inject(NgForm); + expect(form.controls['user']).not.toBeDefined(); - tick(); + tick(); - expect(form.controls['user']).toBeDefined(); - expect(form.controls['user'].controls['login']).toBeDefined(); - }))); + expect(form.controls['user']).toBeDefined(); + expect(form.controls['user'].controls['login']).toBeDefined(); + }))); it("should emit ngSubmit event on submit", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
`; + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.name = 'old'; - var form = fixture.debugElement.query(By.css("form")); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.name = 'old'; + var form = fixture.debugElement.query(By.css("form")); - dispatchEvent(form.nativeElement, "submit"); - tick(); + dispatchEvent(form.nativeElement, "submit"); + tick(); - expect(fixture.debugElement.componentInstance.name).toEqual("updated"); - }))); + expect(fixture.debugElement.componentInstance.name).toEqual("updated"); + }))); it("should not create a template-driven form when ngNoForm is used", inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { @@ -1026,109 +1018,105 @@ export function main() { })); it("should remove controls", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.name = 'show'; - fixture.detectChanges(); - tick(); - var form = fixture.debugElement.children[0].inject(NgForm); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.name = 'show'; + fixture.detectChanges(); + tick(); + var form = fixture.debugElement.children[0].inject(NgForm); - expect(form.controls['login']).toBeDefined(); + expect(form.controls['login']).toBeDefined(); - fixture.debugElement.componentInstance.name = 'hide'; - fixture.detectChanges(); - tick(); + fixture.debugElement.componentInstance.name = 'hide'; + fixture.detectChanges(); + tick(); - expect(form.controls['login']).not.toBeDefined(); - }))); + expect(form.controls['login']).not.toBeDefined(); + }))); it("should remove control groups", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.name = 'show'; - fixture.detectChanges(); - tick(); - var form = fixture.debugElement.children[0].inject(NgForm); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.name = 'show'; + fixture.detectChanges(); + tick(); + var form = fixture.debugElement.children[0].inject(NgForm); - expect(form.controls['user']).toBeDefined(); + expect(form.controls['user']).toBeDefined(); - fixture.debugElement.componentInstance.name = 'hide'; - fixture.detectChanges(); - tick(); + fixture.debugElement.componentInstance.name = 'hide'; + fixture.detectChanges(); + tick(); - expect(form.controls['user']).not.toBeDefined(); - }))); + expect(form.controls['user']).not.toBeDefined(); + }))); it("should support ngModel for complex forms", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.name = "oldValue"; - fixture.detectChanges(); - tick(); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.name = "oldValue"; + fixture.detectChanges(); + tick(); - var input = fixture.debugElement.query(By.css("input")).nativeElement; - expect(input.value).toEqual("oldValue"); + var input = fixture.debugElement.query(By.css("input")).nativeElement; + expect(input.value).toEqual("oldValue"); - input.value = "updatedValue"; - dispatchEvent(input, "input"); - tick(); + input.value = "updatedValue"; + dispatchEvent(input, "input"); + tick(); - expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); - }))); + expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); + }))); it("should support ngModel for single fields", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
`; + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.name = "oldValue"; - fixture.detectChanges(); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.name = "oldValue"; + fixture.detectChanges(); - var input = fixture.debugElement.query(By.css("input")).nativeElement; - expect(input.value).toEqual("oldValue"); + var input = fixture.debugElement.query(By.css("input")).nativeElement; + expect(input.value).toEqual("oldValue"); - input.value = "updatedValue"; - dispatchEvent(input, "input"); - tick(); + input.value = "updatedValue"; + dispatchEvent(input, "input"); + tick(); - expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); - }))); + expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue"); + }))); it("should support ", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = `
@@ -1137,34 +1125,34 @@ export function main() { `; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((f) => { fixture = f; }); - tick(); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((f) => { fixture = f; }); + tick(); - fixture.debugElement.componentInstance.data = { - 'chicken1': new RadioButtonState(false, 'chicken'), - 'fish1': new RadioButtonState(true, 'fish'), + fixture.debugElement.componentInstance.data = { + 'chicken1': new RadioButtonState(false, 'chicken'), + 'fish1': new RadioButtonState(true, 'fish'), - 'chicken2': new RadioButtonState(false, 'chicken'), - 'fish2': new RadioButtonState(true, 'fish') - }; - fixture.detectChanges(); - tick(); + 'chicken2': new RadioButtonState(false, 'chicken'), + 'fish2': new RadioButtonState(true, 'fish') + }; + fixture.detectChanges(); + tick(); - var input = fixture.debugElement.query(By.css("input")); - expect(input.nativeElement.checked).toEqual(false); + var input = fixture.debugElement.query(By.css("input")); + expect(input.nativeElement.checked).toEqual(false); - dispatchEvent(input.nativeElement, "change"); - tick(); + dispatchEvent(input.nativeElement, "change"); + tick(); - let data = fixture.debugElement.componentInstance.data; + let data = fixture.debugElement.componentInstance.data; - expect(data['chicken1']).toEqual(new RadioButtonState(true, 'chicken')); - expect(data['fish1']).toEqual(new RadioButtonState(false, 'fish')); + expect(data['chicken1']).toEqual(new RadioButtonState(true, 'chicken')); + expect(data['fish1']).toEqual(new RadioButtonState(false, 'fish')); - expect(data['chicken2']).toEqual(new RadioButtonState(false, 'chicken')); - expect(data['fish2']).toEqual(new RadioButtonState(true, 'fish')); - }))); + expect(data['chicken2']).toEqual(new RadioButtonState(false, 'chicken')); + expect(data['fish2']).toEqual(new RadioButtonState(true, 'fish')); + }))); }); describe("setting status classes", () => { @@ -1250,82 +1238,78 @@ export function main() { describe("ngModel corner cases", () => { it("should not update the view when the value initially came from the view", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var form = new Control(""); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var form = new Control(""); - var t = - `
`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.form = form; - fixture.detectChanges(); + var t = `
`; + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.form = form; + fixture.detectChanges(); - // In Firefox, effective text selection in the real DOM requires an actual focus - // of the field. This is not an issue in a new HTML document. - if (browserDetection.isFirefox) { - var fakeDoc = DOM.createHtmlDocument(); - DOM.appendChild(fakeDoc.body, fixture.debugElement.nativeElement); - } + // In Firefox, effective text selection in the real DOM requires an actual focus + // of the field. This is not an issue in a new HTML document. + if (browserDetection.isFirefox) { + var fakeDoc = DOM.createHtmlDocument(); + DOM.appendChild(fakeDoc.body, fixture.debugElement.nativeElement); + } - var input = fixture.debugElement.query(By.css("input")).nativeElement; - input.value = "aa"; - input.selectionStart = 1; - dispatchEvent(input, "input"); + var input = fixture.debugElement.query(By.css("input")).nativeElement; + input.value = "aa"; + input.selectionStart = 1; + dispatchEvent(input, "input"); - tick(); - fixture.detectChanges(); + tick(); + fixture.detectChanges(); - // selection start has not changed because we did not reset the value - expect(input.selectionStart).toEqual(1); - }))); + // selection start has not changed because we did not reset the value + expect(input.selectionStart).toEqual(1); + }))); it("should update the view when the model is set back to what used to be in the view", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - var t = ``; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.debugElement.componentInstance.name = ""; - fixture.detectChanges(); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + var t = ``; + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.debugElement.componentInstance.name = ""; + fixture.detectChanges(); - // Type "aa" into the input. - var input = fixture.debugElement.query(By.css("input")).nativeElement; - input.value = "aa"; - input.selectionStart = 1; - dispatchEvent(input, "input"); + // Type "aa" into the input. + var input = fixture.debugElement.query(By.css("input")).nativeElement; + input.value = "aa"; + input.selectionStart = 1; + dispatchEvent(input, "input"); - tick(); - fixture.detectChanges(); - expect(fixture.debugElement.componentInstance.name).toEqual("aa"); + tick(); + fixture.detectChanges(); + expect(fixture.debugElement.componentInstance.name).toEqual("aa"); - // Programatically update the input value to be "bb". - fixture.debugElement.componentInstance.name = "bb"; - tick(); - fixture.detectChanges(); - expect(input.value).toEqual("bb"); + // Programatically update the input value to be "bb". + fixture.debugElement.componentInstance.name = "bb"; + tick(); + fixture.detectChanges(); + expect(input.value).toEqual("bb"); - // Programatically set it back to "aa". - fixture.debugElement.componentInstance.name = "aa"; - tick(); - fixture.detectChanges(); - expect(input.value).toEqual("aa"); - }))); + // Programatically set it back to "aa". + fixture.debugElement.componentInstance.name = "aa"; + tick(); + fixture.detectChanges(); + expect(input.value).toEqual("aa"); + }))); it("should not crash when validity is checked from a binding", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - // {{x.valid}} used to crash because valid() tried to read a property - // from form.control before it was set. This test verifies this bug is - // fixed. - var t = `
+ fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + // {{x.valid}} used to crash because valid() tried to read a property + // from form.control before it was set. This test verifies this bug is + // fixed. + var t = `
{{x.valid}}`; - var fixture: ComponentFixture; - tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then( - (root) => { fixture = root; }); - tick(); - fixture.detectChanges(); - }))); + var fixture: ComponentFixture; + tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => { fixture = root; }); + tick(); + fixture.detectChanges(); + }))); }); }); } diff --git a/modules/angular2/test/core/linker/integration_dart_spec.dart b/modules/angular2/test/core/linker/integration_dart_spec.dart index 9a97230c56..aa1905a514 100644 --- a/modules/angular2/test/core/linker/integration_dart_spec.dart +++ b/modules/angular2/test/core/linker/integration_dart_spec.dart @@ -140,8 +140,8 @@ main() { describe("ObservableListDiff", () { it( 'should be notified of changes', - inject([TestComponentBuilder, Log], - fakeAsync((TestComponentBuilder tcb, Log log) { + fakeAsync(inject([TestComponentBuilder, Log], + (TestComponentBuilder tcb, Log log) { tcb .overrideView( Dummy, diff --git a/modules/angular2/test/core/linker/integration_spec.ts b/modules/angular2/test/core/linker/integration_spec.ts index 5c51ca260d..5d677f5be9 100644 --- a/modules/angular2/test/core/linker/integration_spec.ts +++ b/modules/angular2/test/core/linker/integration_spec.ts @@ -755,26 +755,25 @@ function declareTests(isJit: boolean) { if (DOM.supportsDOMEvents()) { it("should allow to destroy a component from within a host event handler", - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - var fixture: ComponentFixture; - tcb.overrideView( - MyComp, new ViewMetadata({ - template: '', - directives: [[[PushCmpWithHostEvent]]] - })) + var fixture: ComponentFixture; + tcb.overrideView(MyComp, new ViewMetadata({ + template: '', + directives: [[[PushCmpWithHostEvent]]] + })) - .createAsync(MyComp) - .then(root => { fixture = root; }); - tick(); - fixture.detectChanges(); + .createAsync(MyComp) + .then(root => { fixture = root; }); + tick(); + fixture.detectChanges(); - var cmpEl = fixture.debugElement.children[0]; - var cmp: PushCmpWithHostEvent = cmpEl.inject(PushCmpWithHostEvent); - cmp.ctxCallback = (_) => fixture.destroy(); + var cmpEl = fixture.debugElement.children[0]; + var cmp: PushCmpWithHostEvent = cmpEl.inject(PushCmpWithHostEvent); + cmp.ctxCallback = (_) => fixture.destroy(); - expect(() => cmpEl.triggerEventHandler('click', {})).not.toThrow(); - }))); + expect(() => cmpEl.triggerEventHandler('click', {})).not.toThrow(); + }))); } it("should be checked when an event is fired", @@ -829,32 +828,31 @@ function declareTests(isJit: boolean) { if (DOM.supportsDOMEvents()) { it('should be checked when an async pipe requests a check', - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - tcb = tcb.overrideView( - MyComp, new ViewMetadata({ - template: '', - directives: [[[PushCmpWithAsyncPipe]]] - })); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + tcb = + tcb.overrideView(MyComp, new ViewMetadata({ + template: '', + directives: [[[PushCmpWithAsyncPipe]]] + })); - var fixture: ComponentFixture; - tcb.createAsync(MyComp).then(root => { fixture = root; }); - tick(); + var fixture: ComponentFixture; + tcb.createAsync(MyComp).then(root => { fixture = root; }); + tick(); - var cmp: PushCmpWithAsyncPipe = - fixture.debugElement.children[0].getLocal('cmp'); - fixture.detectChanges(); - expect(cmp.numberOfChecks).toEqual(1); + var cmp: PushCmpWithAsyncPipe = fixture.debugElement.children[0].getLocal('cmp'); + fixture.detectChanges(); + expect(cmp.numberOfChecks).toEqual(1); - fixture.detectChanges(); - fixture.detectChanges(); - expect(cmp.numberOfChecks).toEqual(1); + fixture.detectChanges(); + fixture.detectChanges(); + expect(cmp.numberOfChecks).toEqual(1); - cmp.resolve(2); - tick(); + cmp.resolve(2); + tick(); - fixture.detectChanges(); - expect(cmp.numberOfChecks).toEqual(2); - }))); + fixture.detectChanges(); + expect(cmp.numberOfChecks).toEqual(2); + }))); } }); @@ -1462,35 +1460,34 @@ function declareTests(isJit: boolean) { if (DOM.supportsDOMEvents()) { // this is required to use fakeAsync it('should provide an error context when an error happens in an event handler', - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + tcb = tcb.overrideView( + MyComp, new ViewMetadata({ + template: ``, + directives: [DirectiveEmittingEvent, DirectiveListeningEvent] + })); - tcb = tcb.overrideView( - MyComp, new ViewMetadata({ - template: ``, - directives: [DirectiveEmittingEvent, DirectiveListeningEvent] - })); + var fixture: ComponentFixture; + tcb.createAsync(MyComp).then(root => { fixture = root; }); + tick(); - var fixture: ComponentFixture; - tcb.createAsync(MyComp).then(root => { fixture = root; }); - tick(); + var tc = fixture.debugElement.children[0]; + tc.inject(DirectiveEmittingEvent).fireEvent("boom"); - var tc = fixture.debugElement.children[0]; - tc.inject(DirectiveEmittingEvent).fireEvent("boom"); + try { + tick(); + throw "Should throw"; + } catch (e) { + clearPendingTimers(); - try { - tick(); - throw "Should throw"; - } catch (e) { - clearPendingTimers(); - - var c = e.context; - expect(DOM.nodeName(c.renderNode).toUpperCase()).toEqual("SPAN"); - expect(DOM.nodeName(c.componentRenderElement).toUpperCase()).toEqual("DIV"); - expect((c.injector).get).toBeTruthy(); - expect(c.context).toBe(fixture.debugElement.componentInstance); - expect(c.locals["local"]).toBeDefined(); - } - }))); + var c = e.context; + expect(DOM.nodeName(c.renderNode).toUpperCase()).toEqual("SPAN"); + expect(DOM.nodeName(c.componentRenderElement).toUpperCase()).toEqual("DIV"); + expect((c.injector).get).toBeTruthy(); + expect(c.context).toBe(fixture.debugElement.componentInstance); + expect(c.locals["local"]).toBeDefined(); + } + }))); } if (!IS_DART) { @@ -1791,25 +1788,24 @@ function declareTests(isJit: boolean) { if (DOM.supportsDOMEvents()) { it('should support event decorators', - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - tcb = tcb.overrideView( - MyComp, new ViewMetadata({ - template: ``, - directives: [DirectiveWithPropDecorators] - })); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + tcb = + tcb.overrideView(MyComp, new ViewMetadata({ + template: ``, + directives: [DirectiveWithPropDecorators] + })); - var fixture: ComponentFixture; - tcb.createAsync(MyComp).then(root => { fixture = root; }); - tick(); + var fixture: ComponentFixture; + tcb.createAsync(MyComp).then(root => { fixture = root; }); + tick(); - var emitter = - fixture.debugElement.children[0].inject(DirectiveWithPropDecorators); - emitter.fireEvent('fired !'); + var emitter = fixture.debugElement.children[0].inject(DirectiveWithPropDecorators); + emitter.fireEvent('fired !'); - tick(); + tick(); - expect(fixture.debugElement.componentInstance.ctxProp).toEqual("called"); - }))); + expect(fixture.debugElement.componentInstance.ctxProp).toEqual("called"); + }))); it('should support host listener decorators', diff --git a/modules/angular2/test/platform/browser/xhr_cache_spec.ts b/modules/angular2/test/platform/browser/xhr_cache_spec.ts index 63f080bedf..cfd3252b76 100644 --- a/modules/angular2/test/platform/browser/xhr_cache_spec.ts +++ b/modules/angular2/test/platform/browser/xhr_cache_spec.ts @@ -58,15 +58,15 @@ export function main() { })); it('should allow fakeAsync Tests to load components with templateUrl synchronously', - inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => { - let fixture: ComponentFixture; - tcb.createAsync(TestComponent).then((f) => { fixture = f; }); + fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + let fixture: ComponentFixture; + tcb.createAsync(TestComponent).then((f) => { fixture = f; }); - // This should initialize the fixture. - tick(); + // This should initialize the fixture. + tick(); - expect(fixture.debugElement.children[0].nativeElement).toHaveText('Hello'); - }))); + expect(fixture.debugElement.children[0].nativeElement).toHaveText('Hello'); + }))); }); } diff --git a/modules/angular2/test/testing/fake_async_spec.ts b/modules/angular2/test/testing/fake_async_spec.ts index 0d71a7bb62..69976190d1 100644 --- a/modules/angular2/test/testing/fake_async_spec.ts +++ b/modules/angular2/test/testing/fake_async_spec.ts @@ -34,7 +34,7 @@ export function main() { }); it('should work with inject()', - inject([Parser], fakeAsync((parser) => { expect(parser).toBeAnInstanceOf(Parser); }))); + fakeAsync(inject([Parser], (parser) => { expect(parser).toBeAnInstanceOf(Parser); }))); it('should throw on nested calls', () => { expect(() => { fakeAsync(() => { fakeAsync(() => null)(); })(); }) @@ -259,6 +259,5 @@ export function main() { .toThrowError('The code should be running in the fakeAsync zone to call this function'); }); }); - }); } diff --git a/modules/angular2/test/testing/testing_public_browser_spec.ts b/modules/angular2/test/testing/testing_public_browser_spec.ts index f04098fb75..56026cd26a 100644 --- a/modules/angular2/test/testing/testing_public_browser_spec.ts +++ b/modules/angular2/test/testing/testing_public_browser_spec.ts @@ -106,13 +106,12 @@ export function main() { it('provides a real XHR instance', inject([XHR], (xhr) => { expect(xhr).toBeAnInstanceOf(XHRImpl); })); - it('should allow the use of fakeAsync', - inject([FancyService], fakeAsync((service) => { - var value; - service.getAsyncValue().then(function(val) { value = val; }); - tick(); - expect(value).toEqual('async value'); - }))); + it('should allow the use of fakeAsync', fakeAsync(inject([FancyService], (service) => { + var value; + service.getAsyncValue().then(function(val) { value = val; }); + tick(); + expect(value).toEqual('async value'); + }))); }); }); diff --git a/modules/angular2/test/testing/testing_public_spec.ts b/modules/angular2/test/testing/testing_public_spec.ts index 9d50feaa59..bcdc4c77b8 100644 --- a/modules/angular2/test/testing/testing_public_spec.ts +++ b/modules/angular2/test/testing/testing_public_spec.ts @@ -9,6 +9,8 @@ import { beforeEach, inject, async, + fakeAsync, + tick, withProviders, beforeEachProviders, TestComponentBuilder @@ -142,6 +144,13 @@ export function main() { service.getTimeoutValue().then((value) => { expect(value).toEqual('timeout value'); }); }))); + it('should allow the use of fakeAsync', fakeAsync(inject([FancyService], (service) => { + var value; + service.getAsyncValue().then(function(val) { value = val; }); + tick(); + expect(value).toEqual('async value'); + }))); + describe('using beforeEach', () => { beforeEach(inject([FancyService], (service) => { service.value = 'value modified in beforeEach'; })); diff --git a/npm-shrinkwrap.clean.json b/npm-shrinkwrap.clean.json index 563499e271..741ac10f1d 100644 --- a/npm-shrinkwrap.clean.json +++ b/npm-shrinkwrap.clean.json @@ -2231,6 +2231,9 @@ "glob": { "version": "4.3.5", "dependencies": { + "inflight": { + "version": "1.0.4" + }, "minimatch": { "version": "2.0.10" } @@ -5819,7 +5822,7 @@ } }, "zone.js": { - "version": "0.6.11" + "version": "0.6.12" } }, "name": "angular-srcs", diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index a8d26170de..c4ab00d955 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -3519,6 +3519,11 @@ "from": "glob@>=4.3.0 <4.4.0", "resolved": "https://registry.npmjs.org/glob/-/glob-4.3.5.tgz", "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz" + }, "minimatch": { "version": "2.0.10", "from": "minimatch@>=2.0.1 <3.0.0", @@ -9285,8 +9290,9 @@ } }, "zone.js": { - "version": "0.6.11", - "from": "zone.js@0.6.11" + "version": "0.6.12", + "from": "zone.js@0.6.12", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.6.12.tgz" } } } diff --git a/tools/cjs-jasmine/index.js b/tools/cjs-jasmine/index.js index 0d4ab49551..6d6ee3df47 100644 --- a/tools/cjs-jasmine/index.js +++ b/tools/cjs-jasmine/index.js @@ -7,6 +7,7 @@ var path = require('path'); require('zone.js/dist/zone-node.js'); require('zone.js/dist/long-stack-trace-zone.js'); require('zone.js/dist/async-test.js'); +require('zone.js/dist/fake-async-test.js'); require('reflect-metadata/Reflect'); var jrunner = new JasmineRunner();