feat(tests): manage asynchronous tests using zones
Instead of using injectAsync and returning a promise, use the `async` function to wrap tests. This will run the test inside a zone which does not complete the test until all asynchronous tasks have been completed. `async` may be used with the `inject` function, or separately. BREAKING CHANGE: `injectAsync` is now deprecated. Instead, use the `async` function to wrap any asynchronous tests. Before: ``` it('should wait for returned promises', injectAsync([FancyService], (service) => { return service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); }); })); it('should wait for returned promises', injectAsync([], () => { return somePromise.then(() => { expect(true).toEqual(true); }); })); ``` After: ``` it('should wait for returned promises', async(inject([FancyService], (service) => { service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); }); }))); // Note that if there is no injection, we no longer need `inject` OR `injectAsync`. it('should wait for returned promises', async(() => { somePromise.then() => { expect(true).toEqual(true); }); })); ``` Closes #7735
This commit is contained in:
parent
ecb9bb96f0
commit
8490921fb3
|
@ -20,6 +20,7 @@ module.exports = function(config) {
|
|||
'node_modules/zone.js/dist/zone.js',
|
||||
'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',
|
||||
|
||||
// Including systemjs because it defines `__eval`, which produces correct stack traces.
|
||||
'modules/angular2/src/testing/shims_for_IE.js',
|
||||
|
|
|
@ -130,6 +130,7 @@ export class InjectSetupWrapper {
|
|||
return new FunctionWithParamTokens(tokens, fn, false, this._providers);
|
||||
}
|
||||
|
||||
/** @Deprecated {use async(withProviders().inject())} */
|
||||
injectAsync(tokens: any[], fn: Function): FunctionWithParamTokens {
|
||||
return new FunctionWithParamTokens(tokens, fn, true, this._providers);
|
||||
}
|
||||
|
@ -140,6 +141,8 @@ export function withProviders(providers: () => any) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @Deprecated {use async(inject())}
|
||||
*
|
||||
* Allows injecting dependencies in `beforeEach()` and `it()`. The test must return
|
||||
* a promise which will resolve when all asynchronous activity is complete.
|
||||
*
|
||||
|
@ -161,6 +164,32 @@ export function injectAsync(tokens: any[], fn: Function): FunctionWithParamToken
|
|||
return new FunctionWithParamTokens(tokens, fn, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a test function in an asynchronous test zone. The test will automatically
|
||||
* complete when all asynchronous calls within this zone are done. Can be used
|
||||
* to wrap an {@link inject} call.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* it('...', async(inject([AClass], (object) => {
|
||||
* object.doSomething.then(() => {
|
||||
* expect(...);
|
||||
* })
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function async(fn: Function | FunctionWithParamTokens): FunctionWithParamTokens {
|
||||
if (fn instanceof FunctionWithParamTokens) {
|
||||
fn.isAsync = true;
|
||||
return fn;
|
||||
} else if (fn instanceof Function) {
|
||||
return new FunctionWithParamTokens([], fn, true);
|
||||
} else {
|
||||
throw new BaseException('argument to async must be a function or inject(<Function>)');
|
||||
}
|
||||
}
|
||||
|
||||
function emptyArray(): Array<any> {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -9,12 +9,13 @@ import {bind} from 'angular2/core';
|
|||
import {
|
||||
FunctionWithParamTokens,
|
||||
inject,
|
||||
async,
|
||||
injectAsync,
|
||||
TestInjector,
|
||||
getTestInjector
|
||||
} from './test_injector';
|
||||
|
||||
export {inject, injectAsync} from './test_injector';
|
||||
export {inject, async, injectAsync} from './test_injector';
|
||||
|
||||
export {expect, NgMatchers} from './matchers';
|
||||
|
||||
|
@ -122,6 +123,14 @@ export function beforeEachProviders(fn): void {
|
|||
});
|
||||
}
|
||||
|
||||
function runInAsyncTestZone(fnToExecute, finishCallback: Function, failCallback: Function,
|
||||
testName = ''): any {
|
||||
var AsyncTestZoneSpec = Zone['AsyncTestZoneSpec'];
|
||||
var testZoneSpec = new AsyncTestZoneSpec(finishCallback, failCallback, testName);
|
||||
var testZone = Zone.current.fork(testZoneSpec);
|
||||
return testZone.run(fnToExecute);
|
||||
}
|
||||
|
||||
function _isPromiseLike(input): boolean {
|
||||
return input && !!(input.then);
|
||||
}
|
||||
|
@ -129,30 +138,13 @@ function _isPromiseLike(input): boolean {
|
|||
function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | AnyTestFn,
|
||||
testTimeOut: number): void {
|
||||
var timeOut = testTimeOut;
|
||||
|
||||
if (testFn instanceof FunctionWithParamTokens) {
|
||||
let testFnT = testFn;
|
||||
jsmFn(name, (done) => {
|
||||
var returnedTestValue;
|
||||
try {
|
||||
returnedTestValue = testInjector.execute(testFnT);
|
||||
} catch (err) {
|
||||
done.fail(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (testFnT.isAsync) {
|
||||
if (_isPromiseLike(returnedTestValue)) {
|
||||
(<Promise<any>>returnedTestValue).then(() => { done(); }, (err) => { done.fail(err); });
|
||||
} else {
|
||||
done.fail('Error: injectAsync was expected to return a promise, but the ' +
|
||||
' returned value was: ' + returnedTestValue);
|
||||
}
|
||||
runInAsyncTestZone(() => testInjector.execute(testFnT), done, done.fail, name);
|
||||
} else {
|
||||
if (!(returnedTestValue === undefined)) {
|
||||
done.fail('Error: inject returned a value. Did you mean to use injectAsync? Returned ' +
|
||||
'value was: ' + returnedTestValue);
|
||||
}
|
||||
testInjector.execute(testFnT);
|
||||
done();
|
||||
}
|
||||
}, timeOut);
|
||||
|
@ -166,8 +158,6 @@ function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | An
|
|||
* Wrapper around Jasmine beforeEach function.
|
||||
*
|
||||
* beforeEach may be used with the `inject` function to fetch dependencies.
|
||||
* The test will automatically wait for any asynchronous calls inside the
|
||||
* injected test function to complete.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
|
@ -181,26 +171,10 @@ export function beforeEach(fn: FunctionWithParamTokens | AnyTestFn): void {
|
|||
// }));`
|
||||
let fnT = fn;
|
||||
jsmBeforeEach((done) => {
|
||||
|
||||
var returnedTestValue;
|
||||
try {
|
||||
returnedTestValue = testInjector.execute(fnT);
|
||||
} catch (err) {
|
||||
done.fail(err);
|
||||
return;
|
||||
}
|
||||
if (fnT.isAsync) {
|
||||
if (_isPromiseLike(returnedTestValue)) {
|
||||
(<Promise<any>>returnedTestValue).then(() => { done(); }, (err) => { done.fail(err); });
|
||||
} else {
|
||||
done.fail('Error: injectAsync was expected to return a promise, but the ' +
|
||||
' returned value was: ' + returnedTestValue);
|
||||
}
|
||||
runInAsyncTestZone(() => testInjector.execute(fnT), done, done.fail, 'beforeEach');
|
||||
} else {
|
||||
if (!(returnedTestValue === undefined)) {
|
||||
done.fail('Error: inject returned a value. Did you mean to use injectAsync? Returned ' +
|
||||
'value was: ' + returnedTestValue);
|
||||
}
|
||||
testInjector.execute(fnT);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
@ -217,10 +191,8 @@ export function beforeEach(fn: FunctionWithParamTokens | AnyTestFn): void {
|
|||
/**
|
||||
* Define a single test case with the given test name and execution function.
|
||||
*
|
||||
* The test function can be either a synchronous function, an asynchronous function
|
||||
* that takes a completion callback, or an injected function created via {@link inject}
|
||||
* or {@link injectAsync}. The test will automatically wait for any asynchronous calls
|
||||
* inside the injected test function to complete.
|
||||
* The test function can be either a synchronous function, the result of {@link async},
|
||||
* or an injected function created via {@link inject}.
|
||||
*
|
||||
* Wrapper around Jasmine it function. See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
library angular2.test.testing.testing_browser_pec;
|
||||
|
||||
/**
|
||||
* This is intentionally left blank. The public test lib is only for TS/JS
|
||||
* apps.
|
||||
*/
|
||||
main() {}
|
|
@ -0,0 +1,166 @@
|
|||
import {
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
describe,
|
||||
ddescribe,
|
||||
xdescribe,
|
||||
expect,
|
||||
beforeEach,
|
||||
beforeEachProviders,
|
||||
inject,
|
||||
async,
|
||||
TestComponentBuilder,
|
||||
fakeAsync,
|
||||
tick
|
||||
} from 'angular2/testing';
|
||||
|
||||
import {Injectable, bind} from 'angular2/core';
|
||||
import {Directive, Component, ViewMetadata} from 'angular2/core';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/promise';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
|
||||
|
||||
// Components for the tests.
|
||||
class FancyService {
|
||||
value: string = 'real value';
|
||||
getAsyncValue() { return Promise.resolve('async value'); }
|
||||
getTimeoutValue() {
|
||||
return new Promise((resolve, reject) => { setTimeout(() => {resolve('timeout value')}, 10); })
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'external-template-comp',
|
||||
templateUrl: '/base/modules/angular2/test/testing/static_assets/test.html'
|
||||
})
|
||||
class ExternalTemplateComp {
|
||||
}
|
||||
|
||||
@Component({selector: 'bad-template-comp', templateUrl: 'non-existant.html'})
|
||||
class BadTemplateUrl {
|
||||
}
|
||||
|
||||
// Tests for angular2/testing bundle specific to the browser environment.
|
||||
// For general tests, see test/testing/testing_public_spec.ts.
|
||||
export function main() {
|
||||
describe('test APIs for the browser', () => {
|
||||
describe('angular2 jasmine matchers', () => {
|
||||
describe('toHaveCssClass', () => {
|
||||
it('should assert that the CSS class is present', () => {
|
||||
var el = document.createElement('div');
|
||||
el.classList.add('matias');
|
||||
expect(el).toHaveCssClass('matias');
|
||||
});
|
||||
|
||||
it('should assert that the CSS class is not present', () => {
|
||||
var el = document.createElement('div');
|
||||
el.classList.add('matias');
|
||||
expect(el).not.toHaveCssClass('fatias');
|
||||
});
|
||||
});
|
||||
|
||||
describe('toHaveCssStyle', () => {
|
||||
it('should assert that the CSS style is present', () => {
|
||||
var el = document.createElement('div');
|
||||
expect(el).not.toHaveCssStyle('width');
|
||||
|
||||
el.style.setProperty('width', '100px');
|
||||
expect(el).toHaveCssStyle('width');
|
||||
});
|
||||
|
||||
it('should assert that the styles are matched against the element', () => {
|
||||
var el = document.createElement('div');
|
||||
expect(el).not.toHaveCssStyle({width: '100px', height: '555px'});
|
||||
|
||||
el.style.setProperty('width', '100px');
|
||||
expect(el).toHaveCssStyle({width: '100px'});
|
||||
expect(el).not.toHaveCssStyle({width: '100px', height: '555px'});
|
||||
|
||||
el.style.setProperty('height', '555px');
|
||||
expect(el).toHaveCssStyle({height: '555px'});
|
||||
expect(el).toHaveCssStyle({width: '100px', height: '555px'});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('using the async helper', () => {
|
||||
var actuallyDone: boolean;
|
||||
|
||||
beforeEach(() => { actuallyDone = false; });
|
||||
|
||||
afterEach(() => { expect(actuallyDone).toEqual(true); });
|
||||
|
||||
it('should run async tests with XHRs', async(() => {
|
||||
var xhr = new XHRImpl();
|
||||
xhr.get('/base/modules/angular2/test/testing/static_assets/test.html')
|
||||
.then(() => { actuallyDone = true; });
|
||||
}),
|
||||
10000); // Long timeout here because this test makes an actual XHR.
|
||||
});
|
||||
|
||||
describe('using the test injector with the inject helper', () => {
|
||||
describe('setting up Providers', () => {
|
||||
beforeEachProviders(() => [bind(FancyService).toValue(new FancyService())]);
|
||||
|
||||
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');
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
||||
describe('errors', () => {
|
||||
var originalJasmineIt: any;
|
||||
|
||||
var patchJasmineIt = () => {
|
||||
var deferred = PromiseWrapper.completer();
|
||||
originalJasmineIt = jasmine.getEnv().it;
|
||||
jasmine.getEnv().it = (description: string, fn) => {
|
||||
var done = () => { deferred.resolve() };
|
||||
(<any>done).fail = (err) => { deferred.reject(err) };
|
||||
fn(done);
|
||||
return null;
|
||||
};
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var restoreJasmineIt = () => { jasmine.getEnv().it = originalJasmineIt; };
|
||||
|
||||
it('should fail when an XHR fails', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
|
||||
it('should fail with an error from a promise',
|
||||
async(inject([TestComponentBuilder],
|
||||
(tcb) => { return tcb.createAsync(BadTemplateUrl); })));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
|
||||
expect(err).toEqual('Uncaught (in promise): Failed to load non-existant.html');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
describe('test component builder', function() {
|
||||
it('should allow an external templateUrl',
|
||||
async(inject([TestComponentBuilder],
|
||||
(tcb: TestComponentBuilder) => {
|
||||
|
||||
tcb.createAsync(ExternalTemplateComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement)
|
||||
.toHaveText('from external template\n');
|
||||
});
|
||||
})),
|
||||
10000); // Long timeout here because this test makes an actual XHR, and is slow on Edge.
|
||||
});
|
||||
});
|
||||
}
|
|
@ -6,11 +6,9 @@ import {
|
|||
ddescribe,
|
||||
xdescribe,
|
||||
expect,
|
||||
fakeAsync,
|
||||
tick,
|
||||
beforeEach,
|
||||
inject,
|
||||
injectAsync,
|
||||
async,
|
||||
withProviders,
|
||||
beforeEachProviders,
|
||||
TestComponentBuilder
|
||||
|
@ -20,8 +18,6 @@ import {Injectable, bind} from 'angular2/core';
|
|||
import {NgIf} from 'angular2/common';
|
||||
import {Directive, Component, ViewMetadata} from 'angular2/core';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/promise';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
|
||||
|
||||
// Services, and components for the tests.
|
||||
|
||||
|
@ -81,6 +77,9 @@ class MockChildChildComp {
|
|||
class FancyService {
|
||||
value: string = 'real value';
|
||||
getAsyncValue() { return Promise.resolve('async value'); }
|
||||
getTimeoutValue() {
|
||||
return new Promise((resolve, reject) => { setTimeout(() => {resolve('timeout value')}, 10); })
|
||||
}
|
||||
}
|
||||
|
||||
class MockFancyService extends FancyService {
|
||||
|
@ -105,88 +104,43 @@ class TestViewProvidersComp {
|
|||
constructor(private fancyService: FancyService) {}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'external-template-comp',
|
||||
templateUrl: '/base/modules/angular2/test/testing/static_assets/test.html'
|
||||
})
|
||||
class ExternalTemplateComp {
|
||||
}
|
||||
|
||||
@Component({selector: 'bad-template-comp', templateUrl: 'non-existant.html'})
|
||||
class BadTemplateUrl {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('angular2 jasmine matchers', () => {
|
||||
describe('toHaveCssClass', () => {
|
||||
it('should assert that the CSS class is present', () => {
|
||||
var el = document.createElement('div');
|
||||
el.classList.add('matias');
|
||||
expect(el).toHaveCssClass('matias');
|
||||
});
|
||||
describe('using the async helper', () => {
|
||||
var actuallyDone: boolean;
|
||||
|
||||
it('should assert that the CSS class is not present', () => {
|
||||
var el = document.createElement('div');
|
||||
el.classList.add('matias');
|
||||
expect(el).not.toHaveCssClass('fatias');
|
||||
});
|
||||
});
|
||||
beforeEach(() => { actuallyDone = false; });
|
||||
|
||||
describe('toHaveCssStyle', () => {
|
||||
it('should assert that the CSS style is present', () => {
|
||||
var el = document.createElement('div');
|
||||
expect(el).not.toHaveCssStyle('width');
|
||||
afterEach(() => { expect(actuallyDone).toEqual(true); });
|
||||
|
||||
el.style.setProperty('width', '100px');
|
||||
expect(el).toHaveCssStyle('width');
|
||||
});
|
||||
|
||||
it('should assert that the styles are matched against the element', () => {
|
||||
var el = document.createElement('div');
|
||||
expect(el).not.toHaveCssStyle({width: '100px', height: '555px'});
|
||||
|
||||
el.style.setProperty('width', '100px');
|
||||
expect(el).toHaveCssStyle({width: '100px'});
|
||||
expect(el).not.toHaveCssStyle({width: '100px', height: '555px'});
|
||||
|
||||
el.style.setProperty('height', '555px');
|
||||
expect(el).toHaveCssStyle({height: '555px'});
|
||||
expect(el).toHaveCssStyle({width: '100px', height: '555px'});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('using the test injector with the inject helper', () => {
|
||||
it('should run normal tests', () => { expect(true).toEqual(true); });
|
||||
it('should run normal tests', () => { actuallyDone = true; });
|
||||
|
||||
it('should run normal async tests', (done) => {
|
||||
setTimeout(() => {
|
||||
expect(true).toEqual(true);
|
||||
actuallyDone = true;
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('provides a real XHR instance',
|
||||
inject([XHR], (xhr) => { expect(xhr).toBeAnInstanceOf(XHRImpl); }));
|
||||
it('should run async tests with tasks',
|
||||
async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
|
||||
|
||||
it('should run async tests with promises', async(() => {
|
||||
var p = new Promise((resolve, reject) => { setTimeout(resolve, 10); });
|
||||
p.then(() => { actuallyDone = true; });
|
||||
}));
|
||||
});
|
||||
|
||||
describe('using the test injector with the inject helper', () => {
|
||||
describe('setting up Providers', () => {
|
||||
beforeEachProviders(() => [bind(FancyService).toValue(new FancyService())]);
|
||||
|
||||
it('should use set up providers',
|
||||
inject([FancyService], (service) => { expect(service.value).toEqual('real value'); }));
|
||||
|
||||
it('should wait until returned promises', injectAsync([FancyService], (service) => {
|
||||
return service.getAsyncValue().then(
|
||||
(value) => { expect(value).toEqual('async value'); });
|
||||
}));
|
||||
|
||||
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 wait until returned promises', async(inject([FancyService], (service) => {
|
||||
service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
|
||||
service.getTimeoutValue().then((value) => { expect(value).toEqual('timeout value'); });
|
||||
})));
|
||||
|
||||
describe('using beforeEach', () => {
|
||||
beforeEach(inject([FancyService],
|
||||
|
@ -198,9 +152,9 @@ export function main() {
|
|||
});
|
||||
|
||||
describe('using async beforeEach', () => {
|
||||
beforeEach(injectAsync([FancyService], (service) => {
|
||||
return service.getAsyncValue().then((value) => { service.value = value; });
|
||||
}));
|
||||
beforeEach(async(inject([FancyService], (service) => {
|
||||
service.getAsyncValue().then((value) => { service.value = value; });
|
||||
})));
|
||||
|
||||
it('should use asynchronously modified value',
|
||||
inject([FancyService], (service) => { expect(service.value).toEqual('async value'); }));
|
||||
|
@ -248,76 +202,14 @@ export function main() {
|
|||
var restoreJasmineBeforeEach =
|
||||
() => { jasmine.getEnv().beforeEach = originalJasmineBeforeEach; }
|
||||
|
||||
it('injectAsync should fail when return was forgotten in it', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
it('forgets to return a proimse', injectAsync([], () => { return true; }));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected function to throw, but it did not'); }, (err) => {
|
||||
expect(err).toEqual(
|
||||
'Error: injectAsync was expected to return a promise, but the returned value was: true');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
it('inject should fail if a value was returned', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
it('returns a value', inject([], () => { return true; }));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected function to throw, but it did not'); }, (err) => {
|
||||
expect(err).toEqual(
|
||||
'Error: inject returned a value. Did you mean to use injectAsync? Returned value was: true');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
it('injectAsync should fail when return was forgotten in beforeEach', (done) => {
|
||||
var beforeEachPromise = patchJasmineBeforeEach();
|
||||
beforeEach(injectAsync([], () => { return true; }));
|
||||
|
||||
beforeEachPromise.then(
|
||||
() => { done.fail('Expected function to throw, but it did not'); }, (err) => {
|
||||
expect(err).toEqual(
|
||||
'Error: injectAsync was expected to return a promise, but the returned value was: true');
|
||||
done();
|
||||
});
|
||||
restoreJasmineBeforeEach();
|
||||
});
|
||||
|
||||
it('inject should fail if a value was returned in beforeEach', (done) => {
|
||||
var beforeEachPromise = patchJasmineBeforeEach();
|
||||
beforeEach(inject([], () => { return true; }));
|
||||
|
||||
beforeEachPromise.then(
|
||||
() => { done.fail('Expected function to throw, but it did not'); }, (err) => {
|
||||
expect(err).toEqual(
|
||||
'Error: inject returned a value. Did you mean to use injectAsync? Returned value was: true');
|
||||
done();
|
||||
});
|
||||
restoreJasmineBeforeEach();
|
||||
});
|
||||
|
||||
it('should fail when an error occurs inside inject', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
it('throws an error', inject([], () => { throw new Error('foo'); }));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected function to throw, but it did not'); }, (err) => {
|
||||
expect(err.message).toEqual('foo');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
// TODO(juliemr): reenable this test when we are using a test zone and can capture this error.
|
||||
xit('should fail when an asynchronous error is thrown', (done) => {
|
||||
it('should fail when an asynchronous error is thrown', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
|
||||
it('throws an async error',
|
||||
injectAsync([], () => { setTimeout(() => { throw new Error('bar'); }, 0); }));
|
||||
async(inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); })));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
|
||||
expect(err.message).toEqual('bar');
|
||||
expect(err).toEqual('bar');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
|
@ -326,34 +218,21 @@ export function main() {
|
|||
it('should fail when a returned promise is rejected', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
|
||||
it('should fail with an error from a promise', injectAsync([], () => {
|
||||
it('should fail with an error from a promise', async(inject([], () => {
|
||||
var deferred = PromiseWrapper.completer();
|
||||
var p = deferred.promise.then(() => { expect(1).toEqual(2); });
|
||||
|
||||
deferred.reject('baz');
|
||||
return p;
|
||||
}));
|
||||
})));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
|
||||
expect(err).toEqual('baz');
|
||||
expect(err).toEqual('Uncaught (in promise): baz');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
it('should fail when an XHR fails', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
|
||||
it('should fail with an error from a promise',
|
||||
injectAsync([TestComponentBuilder], (tcb) => { return tcb.createAsync(BadTemplateUrl); }));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
|
||||
expect(err).toEqual('Failed to load non-existant.html');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
}, 10000);
|
||||
|
||||
describe('using beforeEachProviders', () => {
|
||||
beforeEachProviders(() => [bind(FancyService).toValue(new FancyService())]);
|
||||
|
||||
|
@ -377,19 +256,19 @@ export function main() {
|
|||
|
||||
describe('test component builder', function() {
|
||||
it('should instantiate a component with valid DOM',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.createAsync(ChildComp).then((componentFixture) => {
|
||||
tcb.createAsync(ChildComp).then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
expect(componentFixture.debugElement.nativeElement).toHaveText('Original Child');
|
||||
});
|
||||
}));
|
||||
})));
|
||||
|
||||
it('should allow changing members of the component',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.createAsync(MyIfComp).then((componentFixture) => {
|
||||
tcb.createAsync(MyIfComp).then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement).toHaveText('MyIf()');
|
||||
|
||||
|
@ -397,51 +276,50 @@ export function main() {
|
|||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement).toHaveText('MyIf(More)');
|
||||
});
|
||||
}));
|
||||
})));
|
||||
|
||||
it('should override a template',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.overrideTemplate(MockChildComp, '<span>Mock</span>')
|
||||
tcb.overrideTemplate(MockChildComp, '<span>Mock</span>')
|
||||
.createAsync(MockChildComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement).toHaveText('Mock');
|
||||
|
||||
});
|
||||
}));
|
||||
})));
|
||||
|
||||
it('should override a view',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.overrideView(
|
||||
ChildComp,
|
||||
new ViewMetadata({template: '<span>Modified {{childBinding}}</span>'}))
|
||||
tcb.overrideView(ChildComp,
|
||||
new ViewMetadata({template: '<span>Modified {{childBinding}}</span>'}))
|
||||
.createAsync(ChildComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement).toHaveText('Modified Child');
|
||||
|
||||
});
|
||||
}));
|
||||
})));
|
||||
|
||||
it('should override component dependencies',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.overrideDirective(ParentComp, ChildComp, MockChildComp)
|
||||
tcb.overrideDirective(ParentComp, ChildComp, MockChildComp)
|
||||
.createAsync(ParentComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement).toHaveText('Parent(Mock)');
|
||||
|
||||
});
|
||||
}));
|
||||
})));
|
||||
|
||||
|
||||
it("should override child component's dependencies",
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.overrideDirective(ParentComp, ChildComp, ChildWithChildComp)
|
||||
tcb.overrideDirective(ParentComp, ChildComp, ChildWithChildComp)
|
||||
.overrideDirective(ChildWithChildComp, ChildChildComp, MockChildChildComp)
|
||||
.createAsync(ParentComp)
|
||||
.then((componentFixture) => {
|
||||
|
@ -450,44 +328,32 @@ export function main() {
|
|||
.toHaveText('Parent(Original Child(ChildChild Mock))');
|
||||
|
||||
});
|
||||
}));
|
||||
})));
|
||||
|
||||
it('should override a provider',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.overrideProviders(TestProvidersComp,
|
||||
[bind(FancyService).toClass(MockFancyService)])
|
||||
tcb.overrideProviders(TestProvidersComp, [bind(FancyService).toClass(MockFancyService)])
|
||||
.createAsync(TestProvidersComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement)
|
||||
.toHaveText('injected value: mocked out value');
|
||||
});
|
||||
}));
|
||||
})));
|
||||
|
||||
|
||||
it('should override a viewProvider',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.overrideViewProviders(TestViewProvidersComp,
|
||||
[bind(FancyService).toClass(MockFancyService)])
|
||||
tcb.overrideViewProviders(TestViewProvidersComp,
|
||||
[bind(FancyService).toClass(MockFancyService)])
|
||||
.createAsync(TestViewProvidersComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement)
|
||||
.toHaveText('injected value: mocked out value');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow an external templateUrl',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.createAsync(ExternalTemplateComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement)
|
||||
.toHaveText('from external template\n');
|
||||
});
|
||||
}), 10000); // Long timeout here because this test makes an actual XHR, and is slow on Edge.
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2231,9 +2231,6 @@
|
|||
"glob": {
|
||||
"version": "4.3.5",
|
||||
"dependencies": {
|
||||
"inflight": {
|
||||
"version": "1.0.4"
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "2.0.10"
|
||||
}
|
||||
|
@ -5822,9 +5819,9 @@
|
|||
}
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.6.10"
|
||||
"version": "0.6.11"
|
||||
}
|
||||
},
|
||||
"name": "angular-srcs",
|
||||
"version": "2.0.0-beta.14"
|
||||
"version": "2.0.0-beta.15"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "2.0.0-beta.14",
|
||||
"version": "2.0.0-beta.15",
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.0.7",
|
||||
|
@ -3519,11 +3519,6 @@
|
|||
"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",
|
||||
|
@ -7804,7 +7799,8 @@
|
|||
"dependencies": {
|
||||
"mime-db": {
|
||||
"version": "1.20.0",
|
||||
"from": "mime-db@>=1.20.0 <1.21.0"
|
||||
"from": "mime-db@1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.20.0.tgz"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.8",
|
||||
|
@ -9289,9 +9285,8 @@
|
|||
}
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.6.10",
|
||||
"from": "zone.js@0.6.10",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.6.10.tgz"
|
||||
"version": "0.6.11",
|
||||
"from": "zone.js@0.6.11"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"es6-shim": "^0.35.0",
|
||||
"reflect-metadata": "0.1.2",
|
||||
"rxjs": "5.0.0-beta.2",
|
||||
"zone.js": "^0.6.10"
|
||||
"zone.js": "^0.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular": "^1.5.0",
|
||||
|
|
|
@ -76,7 +76,7 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
|||
'angular2/test/animate/**',
|
||||
'angular2/test/core/zone/**',
|
||||
'angular2/test/testing/fake_async_spec.ts',
|
||||
'angular2/test/testing/testing_public_spec.ts',
|
||||
'angular2/test/testing/testing_public_browser_spec.ts',
|
||||
'angular2/test/platform/xhr_impl_spec.ts',
|
||||
'angular2/test/platform/browser/**/*.ts',
|
||||
'angular2/test/common/forms/**',
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
var glob = require('glob');
|
||||
var JasmineRunner = require('jasmine');
|
||||
var path = require('path');
|
||||
// require('es6-shim/es6-shim.js');
|
||||
require('zone.js/dist/zone-node.js');
|
||||
require('zone.js/dist/long-stack-trace-zone.js');
|
||||
require('es6-shim/es6-shim.js');
|
||||
require('zone.js/dist/async-test.js');
|
||||
require('reflect-metadata/Reflect');
|
||||
|
||||
var jrunner = new JasmineRunner();
|
||||
|
@ -36,4 +37,5 @@ jrunner.projectBaseDir = path.resolve(__dirname, '../../');
|
|||
jrunner.specDir = '';
|
||||
jrunner.addSpecFiles(specFiles);
|
||||
require('./test-cjs-main.js');
|
||||
require('zone.js/dist/jasmine-patch.js');
|
||||
jrunner.execute();
|
||||
|
|
Loading…
Reference in New Issue