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:
Julie Ralph 2016-03-23 10:59:38 -07:00 committed by Robert Messerle
parent ecb9bb96f0
commit 8490921fb3
11 changed files with 289 additions and 254 deletions

View File

@ -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',

View File

@ -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 [];
}

View File

@ -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.
*

View File

@ -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() {}

View File

@ -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.
});
});
}

View File

@ -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.
})));
});
}

View File

@ -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"
}

15
npm-shrinkwrap.json generated
View File

@ -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"
}
}
}

View File

@ -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",

View File

@ -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/**',

View File

@ -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();