diff --git a/modules/angular2/src/test_lib/test_lib.ts b/modules/angular2/src/test_lib/test_lib.ts index 8b0e328a2b..bd02853a83 100644 --- a/modules/angular2/src/test_lib/test_lib.ts +++ b/modules/angular2/src/test_lib/test_lib.ts @@ -2,12 +2,13 @@ import {DOM} from 'angular2/src/core/dom/dom_adapter'; import {StringMapWrapper} from 'angular2/src/core/facade/collection'; -import {global, isFunction} from 'angular2/src/core/facade/lang'; +import {global, isFunction, Math} from 'angular2/src/core/facade/lang'; import {NgZoneZone} from 'angular2/src/core/zone/ng_zone'; import {bind} from 'angular2/src/core/di'; import {createTestInjector, FunctionWithParamTokens, inject} from './test_injector'; +import {browserDetection} from './utils'; export {inject} from './test_injector'; @@ -52,6 +53,7 @@ var jsmXIt = _global.xit; var runnerStack = []; var inIt = false; +var globalTimeOut = browserDetection.isSlow ? 3000 : jasmine.DEFAULT_TIMEOUT_INTERVAL; var testBindings; @@ -130,8 +132,9 @@ export function beforeEachBindings(fn): void { } function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | AnyTestFn, - timeOut: number): void { + testTimeOut: number): void { var runner = runnerStack[runnerStack.length - 1]; + var timeOut = Math.max(globalTimeOut, testTimeOut); if (testFn instanceof FunctionWithParamTokens) { // The test case uses inject(). ie `it('test', inject([AsyncTestCompleter], (async) => { ... diff --git a/modules/angular2/src/test_lib/utils.ts b/modules/angular2/src/test_lib/utils.ts index 7b61878078..40c7ebd7de 100644 --- a/modules/angular2/src/test_lib/utils.ts +++ b/modules/angular2/src/test_lib/utils.ts @@ -51,6 +51,12 @@ export class BrowserDetection { return this._ua.indexOf('AppleWebKit') > -1 && this._ua.indexOf('Edge') == -1; } + get isIOS7(): boolean { + return this._ua.indexOf('iPhone OS 7') > -1 || this._ua.indexOf('iPad OS 7') > -1; + } + + get isSlow(): boolean { return this.isAndroid || this.isIE || this.isIOS7; } + // The Intl API is only properly supported in recent Chrome and Opera. // Note: Edge is disguised as Chrome 42, so checking the "Edge" part is needed, // see https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx diff --git a/modules/angular2/test/compiler/style_compiler_spec.ts b/modules/angular2/test/compiler/style_compiler_spec.ts index 17a25e4db2..d961f2ef1d 100644 --- a/modules/angular2/test/compiler/style_compiler_spec.ts +++ b/modules/angular2/test/compiler/style_compiler_spec.ts @@ -180,12 +180,10 @@ export function main() { it('should allow to import rules with relative paths', runTest(`div {color: red}@import ${IMPORT_REL_MODULE_NAME};`, - ['div {color: red}', 'span {color: blue}'], - [ + ['div {color: red}', 'span {color: blue}'], [ 'div[_ngcontent-%COMP%] {\ncolor: red;\n}', 'span[_ngcontent-%COMP%] {\ncolor: blue;\n}' - ]), - 1000); + ])); }); }); } diff --git a/modules/angular2/test/core/zone/ng_zone_spec.ts b/modules/angular2/test/core/zone/ng_zone_spec.ts index 078b839d08..351c7ac51b 100644 --- a/modules/angular2/test/core/zone/ng_zone_spec.ts +++ b/modules/angular2/test/core/zone/ng_zone_spec.ts @@ -11,7 +11,8 @@ import { xit, Log, isInInnerZone, - browserDetection + browserDetection, + TIMEOUT_INTERVAL_FOR_SLOW_BROWSERS } from 'angular2/test_lib'; import {PromiseCompleter, PromiseWrapper, TimerWrapper} from 'angular2/src/core/facade/async'; @@ -19,8 +20,9 @@ import {BaseException} from 'angular2/src/core/facade/exceptions'; import {NgZone} from 'angular2/src/core/zone/ng_zone'; -var needsLongerTimers = - browserDetection.isAndroid || browserDetection.isEdge || browserDetection.isIE; +var needsLongerTimers = browserDetection.isSlow || browserDetection.isEdge; +var resultTimer = 1000; +var testTimeout = browserDetection.isEdge ? 1200 : 100; // Schedules a macrotask (using a timer) function macroTask(fn: Function, timer = 1): void { // adds longer timers for passing tests in IE and Edge @@ -83,7 +85,7 @@ export function main() { async.done(); }); }); - })); + }), testTimeout); it('should produce long stack traces (when using microtasks)', inject([AsyncTestCompleter], (async) => { @@ -106,7 +108,7 @@ export function main() { async.done(); }); }); - })); + }), testTimeout); }); describe('short stack trace', () => { @@ -134,7 +136,7 @@ export function main() { async.done(); }); }); - })); + }), testTimeout); }); }); } @@ -144,14 +146,14 @@ function commonTests() { () => {it('should return whether the code executes in the inner zone', () => { expect(isInInnerZone()).toEqual(false); _zone.run(() => { expect(isInInnerZone()).toEqual(true); }); - })}); + }, testTimeout)}); describe('run', () => { it('should return the body return value from run', inject([AsyncTestCompleter], (async) => { macroTask(() => { expect(_zone.run(() => { return 6; })).toEqual(6); }); macroTask(() => { async.done(); }); - })); + }), testTimeout); it('should call onTurnStart and onTurnDone', inject([AsyncTestCompleter], (async) => { macroTask(() => { _zone.run(_log.fn('run')); }); @@ -160,7 +162,7 @@ function commonTests() { expect(_log.result()).toEqual('onTurnStart; run; onTurnDone'); async.done(); }); - })); + }), testTimeout); it('should call onEventDone once at the end of event', inject([AsyncTestCompleter], (async) => { // The test is set up in a way that causes the zone loop to run onTurnDone twice @@ -183,8 +185,8 @@ function commonTests() { macroTask(() => { expect(_log.result()).toEqual('run; onTurnDone 1; onTurnDone 2; onEventDone'); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); it('should call standalone onEventDone', inject([AsyncTestCompleter], (async) => { _zone.overrideOnTurnStart(null); @@ -197,8 +199,8 @@ function commonTests() { macroTask(() => { expect(_log.result()).toEqual('run; onEventDone'); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); it('should not allow onEventDone to cause further digests', inject([AsyncTestCompleter], (async) => { @@ -221,8 +223,8 @@ function commonTests() { macroTask(() => { expect(_log.result()).toEqual('run; onTurnDone; onEventDone'); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); it('should run async tasks scheduled inside onEventDone outside Angular zone', inject([AsyncTestCompleter], (async) => { @@ -243,9 +245,9 @@ function commonTests() { TimerWrapper.setTimeout(() => { expect(_log.result()).toEqual('run; onTurnDone; onEventDone; asyncTask'); async.done(); - }, 20); + }, 50); }); - })); + }), testTimeout); it('should call onTurnStart once before a turn and onTurnDone once after the turn', inject([AsyncTestCompleter], (async) => { @@ -262,8 +264,8 @@ function commonTests() { // The microtask (async) is executed after the macrotask (run) expect(_log.result()).toEqual('onTurnStart; run start; run end; async; onTurnDone'); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); it('should not run onTurnStart and onTurnDone for nested Zone.run', inject([AsyncTestCompleter], (async) => { @@ -283,8 +285,8 @@ function commonTests() { .toEqual( 'onTurnStart; start run; nested run; end run; nested run microtask; onTurnDone'); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); it('should not run onTurnStart and onTurnDone for nested Zone.run invoked from onTurnDone', inject([AsyncTestCompleter], (async) => { @@ -301,8 +303,8 @@ function commonTests() { expect(_log.result()) .toEqual('start run; onTurnDone:started; nested run; onTurnDone:finished'); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); it('should call onTurnStart and onTurnDone before and after each top-level run', inject([AsyncTestCompleter], (async) => { @@ -314,8 +316,8 @@ function commonTests() { expect(_log.result()) .toEqual('onTurnStart; run1; onTurnDone; onTurnStart; run2; onTurnDone'); async.done(); - }); - })); + }, resultTimer); + }), testTimeout); it('should call onTurnStart and onTurnDone before and after each turn', inject([AsyncTestCompleter], (async) => { @@ -345,8 +347,8 @@ function commonTests() { .toEqual( 'onTurnStart; run start; onTurnDone; onTurnStart; a then; b then; onTurnDone'); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); it('should run a function outside of the angular zone', inject([AsyncTestCompleter], (async) => { @@ -356,7 +358,7 @@ function commonTests() { expect(_log.result()).toEqual('run'); async.done() }); - })); + }), testTimeout); it('should call onTurnStart and onTurnDone when an inner microtask is scheduled from outside angular', inject([AsyncTestCompleter], (async) => { @@ -385,8 +387,8 @@ function commonTests() { // Third VM Turn => execute the microtask (inside angular) 'onTurnStart; executedMicrotask; onTurnDone'); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); it('should call onTurnStart before executing a microtask scheduled in onTurnDone as well as ' + 'onTurnDone after executing the task', @@ -415,8 +417,8 @@ function commonTests() { // Second VM Turn => microtask enqueued from onTurnDone 'onTurnStart; executedMicrotask; onTurnDone(begin); onTurnDone(end)'); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); it('should call onTurnStart and onTurnDone for a scheduleMicrotask in onTurnDone triggered by ' + 'a scheduleMicrotask in run', @@ -450,8 +452,8 @@ function commonTests() { // Second VM Turn => the microtask enqueued from onTurnDone 'onTurnStart; onTurnDone(executeMicrotask); onTurnDone(begin); onTurnDone(end)'); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); it('should execute promises scheduled in onTurnStart before promises scheduled in run', inject([AsyncTestCompleter], (async) => { @@ -505,8 +507,8 @@ function commonTests() { // Second VM turn: execute the microtask from onTurnEnd 'onTurnStart(begin); onTurnStart(end); onTurnDone(executePromise); onTurnDone(begin); onTurnDone(end)'); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); it('should call onTurnStart and onTurnDone before and after each turn, respectively', inject([AsyncTestCompleter], (async) => { @@ -526,7 +528,7 @@ function commonTests() { macroTask(() => { _zone.run(() => { completerA.resolve(null); }); }, 20); - macroTask(() => { _zone.run(() => { completerB.resolve(null); }); }, 120); + macroTask(() => { _zone.run(() => { completerB.resolve(null); }); }, 500); macroTask(() => { expect(_log.result()) @@ -538,8 +540,8 @@ function commonTests() { // Third VM turn 'onTurnStart; b then; onTurnDone'); async.done(); - }, 180); - }), 200); + }, resultTimer); + }), testTimeout); it('should call onTurnStart and onTurnDone before and after (respectively) all turns in a chain', inject([AsyncTestCompleter], (async) => { @@ -558,8 +560,8 @@ function commonTests() { expect(_log.result()) .toEqual('onTurnStart; run start; run end; async1; async2; onTurnDone'); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); it('should call onTurnStart and onTurnDone for promises created outside of run body', inject([AsyncTestCompleter], (async) => { @@ -580,8 +582,8 @@ function commonTests() { expect(_log.result()) .toEqual('onTurnStart; zone run; onTurnDone; onTurnStart; promise then; onTurnDone'); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); }); describe('exceptions', () => { @@ -598,7 +600,7 @@ function commonTests() { expect(_errors[0]).toBe(exception); async.done(); }); - })); + }), testTimeout); it('should call onError for errors from microtasks', inject([AsyncTestCompleter], (async) => { _zone.overrideOnErrorHandler(logError); @@ -611,8 +613,8 @@ function commonTests() { expect(_errors.length).toBe(1); expect(_errors[0]).toEqual(exception); async.done(); - }, 150); - }), 200); + }, resultTimer); + }), testTimeout); it('should call onError when onTurnDone throws and the zone is sync', inject([AsyncTestCompleter], (async) => { @@ -627,8 +629,8 @@ function commonTests() { expect(_errors.length).toBe(1); expect(_errors[0]).toEqual(exception); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); it('should call onError when onTurnDone throws and the zone is async', inject([AsyncTestCompleter], (async) => { @@ -646,7 +648,7 @@ function commonTests() { expect(_errors.length).toBe(1); expect(_errors[0]).toEqual(exception); async.done(); - }, 80); - })); + }, resultTimer); + }), testTimeout); }); } diff --git a/modules/angular2/test/router/integration/lifecycle_hook_spec.ts b/modules/angular2/test/router/integration/lifecycle_hook_spec.ts index b6283a3f71..1b000ba935 100644 --- a/modules/angular2/test/router/integration/lifecycle_hook_spec.ts +++ b/modules/angular2/test/router/integration/lifecycle_hook_spec.ts @@ -97,7 +97,7 @@ export function main() { expect(log).toEqual(['activate: null -> /on-activate']); async.done(); }); - }), 2000); + })); it('should wait for a parent component\'s onActivate hook to resolve before calling its child\'s', inject([AsyncTestCompleter], (async) => { @@ -120,7 +120,7 @@ export function main() { async.done(); }); }); - }), 2000); + })); it('should call the onDeactivate hook', inject([AsyncTestCompleter], (async) => { compile() @@ -133,7 +133,7 @@ export function main() { expect(log).toEqual(['deactivate: /on-deactivate -> /a']); async.done(); }); - }), 2000); + })); it('should wait for a child component\'s onDeactivate hook to resolve before calling its parent\'s', inject([AsyncTestCompleter], (async) => { @@ -158,7 +158,7 @@ export function main() { async.done(); }); }); - }), 2000); + })); it('should reuse a component when the canReuse hook returns true', inject([AsyncTestCompleter], (async) => { @@ -179,7 +179,7 @@ export function main() { expect(cmpInstanceCount).toBe(1); async.done(); }); - }), 2000); + })); it('should not reuse a component when the canReuse hook returns false', @@ -201,7 +201,7 @@ export function main() { expect(cmpInstanceCount).toBe(2); async.done(); }); - }), 2000); + })); it('should navigate when canActivate returns true', inject([AsyncTestCompleter], (async) => { @@ -221,7 +221,7 @@ export function main() { async.done(); }); }); - }), 2000); + })); it('should not navigate when canActivate returns false', inject([AsyncTestCompleter], (async) => { @@ -241,7 +241,7 @@ export function main() { async.done(); }); }); - }), 2000); + })); it('should navigate away when canDeactivate returns true', inject([AsyncTestCompleter], (async) => { @@ -266,7 +266,7 @@ export function main() { async.done(); }); }); - }), 2000); + })); it('should not navigate away when canDeactivate returns false', inject([AsyncTestCompleter], (async) => { @@ -291,7 +291,7 @@ export function main() { async.done(); }); }); - }), 2000); + })); it('should run activation and deactivation hooks in the correct order', @@ -319,7 +319,7 @@ export function main() { ]); async.done(); }); - }), 2000); + })); it('should only run reuse hooks when reusing', inject([AsyncTestCompleter], (async) => { compile() @@ -346,7 +346,7 @@ export function main() { ]); async.done(); }); - }), 2000); + })); it('should not run reuse hooks when not reusing', inject([AsyncTestCompleter], (async) => { compile() @@ -375,7 +375,7 @@ export function main() { ]); async.done(); }); - }), 2000); + })); }); } diff --git a/modules/angular2/test/router/integration/router_integration_spec.ts b/modules/angular2/test/router/integration/router_integration_spec.ts index 61a5e4893b..dfbb1987d9 100644 --- a/modules/angular2/test/router/integration/router_integration_spec.ts +++ b/modules/angular2/test/router/integration/router_integration_spec.ts @@ -63,7 +63,7 @@ export function main() { async.done(); }); }); - }), 1000); + })); }); describe('broken app', () => { @@ -79,7 +79,7 @@ export function main() { async.done(); }); }); - }), 1000); + })); }); describe('back button app', () => { @@ -153,7 +153,7 @@ export function main() { }); router.navigateByUrl('/parent/child'); }); - }), 1000); + })); describe('custom app base ref', () => { beforeEachBindings(() => { return [bind(APP_BASE_HREF).toValue('/my/app')]; }); @@ -173,8 +173,7 @@ export function main() { }); router.navigateByUrl('/parent/child'); }); - }), - 1000); + })); }); }); // TODO: add a test in which the child component has bindings @@ -201,7 +200,7 @@ export function main() { router.navigateByUrl('/qs?q=search-for-something'); rootTC.detectChanges(); }); - }), 1000); + })); }); }); } diff --git a/modules/angular2/test/router/integration/router_link_spec.ts b/modules/angular2/test/router/integration/router_link_spec.ts index aa3c268b10..bdab016b25 100644 --- a/modules/angular2/test/router/integration/router_link_spec.ts +++ b/modules/angular2/test/router/integration/router_link_spec.ts @@ -277,7 +277,7 @@ export function main() { async.done(); }); }); - }), 1000); + })); it('should navigate to link hrefs in presence of base href', inject([AsyncTestCompleter], (async) => { @@ -298,7 +298,7 @@ export function main() { async.done(); }); }); - }), 1000); + })); }); }); } diff --git a/modules/angular2/test/router/location_spec.ts b/modules/angular2/test/router/location_spec.ts index 1fe0bd5f28..6b2fb99944 100644 --- a/modules/angular2/test/router/location_spec.ts +++ b/modules/angular2/test/router/location_spec.ts @@ -63,7 +63,7 @@ export function main() { expect(ev['url']).toEqual('/user/btford'); async.done(); }) - }), 2000); + })); it('should normalize location path', () => { locationStrategy.internalPath = '/my/app/user/btford'; diff --git a/modules/angular2/test/router/route_config_spec.ts b/modules/angular2/test/router/route_config_spec.ts index 063de85727..70d5aa3361 100644 --- a/modules/angular2/test/router/route_config_spec.ts +++ b/modules/angular2/test/router/route_config_spec.ts @@ -68,7 +68,7 @@ export function main() { }); router.navigateByUrl('/parent/child'); }); - }), 1000); + })); it('should work in an app with redirects', inject([AsyncTestCompleter], (async) => { @@ -83,7 +83,7 @@ export function main() { }); router.navigateByUrl('/before'); }); - }), 1000); + })); it('should work in an app with async components', inject([AsyncTestCompleter], (async) => { @@ -97,7 +97,7 @@ export function main() { }); router.navigateByUrl('/hello'); }); - }), 1000); + })); it('should work in an app with a constructor component', @@ -114,7 +114,7 @@ export function main() { }); router.navigateByUrl('/hello'); }); - }), 1000); + })); it('should throw if a config is missing a target', inject( diff --git a/modules/angular2/test/test_lib/utils_spec.ts b/modules/angular2/test/test_lib/utils_spec.ts index 5f492e172e..b78312cd61 100644 --- a/modules/angular2/test/test_lib/utils_spec.ts +++ b/modules/angular2/test/test_lib/utils_spec.ts @@ -13,6 +13,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: false, supportsIntlApi: true }, { @@ -23,6 +25,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: false, supportsIntlApi: true }, { @@ -33,6 +37,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: false, + isIOS7: false, + isSlow: false, supportsIntlApi: false }, { @@ -43,6 +49,8 @@ export function main() { isEdge: false, isIE: true, isWebkit: false, + isIOS7: false, + isSlow: true, supportsIntlApi: false }, { @@ -53,6 +61,8 @@ export function main() { isEdge: false, isIE: true, isWebkit: false, + isIOS7: false, + isSlow: true, supportsIntlApi: false }, { @@ -63,6 +73,8 @@ export function main() { isEdge: false, isIE: true, isWebkit: false, + isIOS7: false, + isSlow: true, supportsIntlApi: false }, { @@ -73,6 +85,8 @@ export function main() { isEdge: true, isIE: false, isWebkit: false, + isIOS7: false, + isSlow: false, supportsIntlApi: false }, { @@ -83,6 +97,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: true, supportsIntlApi: false }, { @@ -93,6 +109,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: true, supportsIntlApi: false }, { @@ -103,6 +121,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: true, supportsIntlApi: false }, { @@ -113,6 +133,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: false, supportsIntlApi: false }, { @@ -123,6 +145,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: false, supportsIntlApi: false }, { @@ -133,6 +157,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: false, supportsIntlApi: false }, { @@ -143,6 +169,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: true, + isSlow: true, supportsIntlApi: false }, { @@ -153,6 +181,8 @@ export function main() { isEdge: false, isIE: false, isWebkit: true, + isIOS7: false, + isSlow: false, supportsIntlApi: false } ]; @@ -165,6 +195,8 @@ export function main() { expect(bd.isEdge).toBe(StringMapWrapper.get(browser, 'isEdge')); expect(bd.isIE).toBe(StringMapWrapper.get(browser, 'isIE')); expect(bd.isWebkit).toBe(StringMapWrapper.get(browser, 'isWebkit')); + expect(bd.isIOS7).toBe(StringMapWrapper.get(browser, 'isIOS7')); + expect(bd.isSlow).toBe(StringMapWrapper.get(browser, 'isSlow')); expect(bd.supportsIntlApi).toBe(StringMapWrapper.get(browser, 'supportsIntlApi')); }); }); diff --git a/modules/angular2/test/web_workers/shared/message_bus_spec.ts b/modules/angular2/test/web_workers/shared/message_bus_spec.ts index 648b1f6a9c..139b50d775 100644 --- a/modules/angular2/test/web_workers/shared/message_bus_spec.ts +++ b/modules/angular2/test/web_workers/shared/message_bus_spec.ts @@ -38,7 +38,7 @@ export function main() { }); var toEmitter = bus.to(CHANNEL); ObservableWrapper.callNext(toEmitter, MESSAGE); - }), 1000); + })); it("should broadcast", inject([AsyncTestCompleter], (async) => { const CHANNEL = "CHANNEL 1"; @@ -111,7 +111,7 @@ export function main() { * Flushes pending messages and then runs the given function. */ // TODO(mlaval): timeout is fragile, test to be rewritten - function flushMessages(fn: () => void) { TimerWrapper.setTimeout(fn, 40); } + function flushMessages(fn: () => void) { TimerWrapper.setTimeout(fn, 50); } beforeEach(() => { bus = createConnectedMessageBus(); }); @@ -133,7 +133,7 @@ export function main() { async.done(); }); }); - })); + }), 500); it("should send messages immediatly when run outside the zone", inject([AsyncTestCompleter, NgZone], (async, zone: MockNgZone) => { @@ -147,6 +147,6 @@ export function main() { expect(wasCalled).toBeTruthy(); async.done(); }); - })); + }), 500); }); }