Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 4bbaac1

Browse files
committed
docs(testing) adapt sample code to beta.16 breaking changes
1 parent 097505b commit 4bbaac1

File tree

8 files changed

+383
-319
lines changed

8 files changed

+383
-319
lines changed

public/docs/_examples/karma.conf.js

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,30 @@ module.exports = function(config) {
2020
flags: ['--no-sandbox']
2121
}
2222
},
23-
2423
files: [
25-
// Angular and shim libraries loaded by Karma
26-
{ pattern: 'node_modules/systemjs/dist/system-polyfills.js', included: true, watched: true },
27-
{ pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true },
28-
{ pattern: 'node_modules/es6-shim/es6-shim.js', included: true, watched: true },
29-
{ pattern: 'node_modules/angular2/bundles/angular2-polyfills.js', included: true, watched: true },
30-
{ pattern: 'node_modules/rxjs/bundles/Rx.js', included: true, watched: true },
31-
{ pattern: 'node_modules/angular2/bundles/angular2.js', included: true, watched: true },
32-
{ pattern: 'node_modules/angular2/bundles/testing.dev.js', included: true, watched: true },
33-
34-
// External libraries loaded by Karma
35-
{ pattern: 'node_modules/angular2/bundles/http.dev.js', included: true, watched: true },
36-
{ pattern: 'node_modules/angular2/bundles/router.dev.js', included: true, watched: true },
37-
{ pattern: 'node_modules/a2-in-memory-web-api/web-api.js', included: true, watched: true },
38-
39-
// Configures module loader w/ app and specs, then launch karma
40-
{ pattern: 'karma-test-shim.js', included: true, watched: true },
24+
// System.js for module loading
25+
'node_modules/systemjs/dist/system-polyfills.js',
26+
'node_modules/systemjs/dist/system.src.js',
27+
28+
// Polyfills
29+
'node_modules/es6-shim/es6-shim.js',
30+
'node_modules/angular2/bundles/angular2-polyfills.js',
31+
32+
// Zone.js dependencies
33+
// Note - do not include zone.js itself or long-stack-trace-zone.js` here as
34+
// they are included already in angular2-polyfills
35+
'node_modules/zone.js/dist/jasmine-patch.js',
36+
'node_modules/zone.js/dist/async-test.js',
37+
'node_modules/zone.js/dist/fake-async-test.js',
38+
39+
// RxJs
40+
'node_modules/rxjs/bundles/Rx.js',
41+
42+
// Angular 2 itself and the testing library
43+
'node_modules/angular2/bundles/angular2.js',
44+
'node_modules/angular2/bundles/testing.dev.js',
45+
46+
'karma-test-shim.js',
4147

4248
// transpiled application & spec code paths loaded via module imports
4349
{pattern: appBase + '**/*.js', included: false, watched: true},

public/docs/_examples/testing/ts/app/app.component.spec.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
/* tslint:disable:no-unused-variable */
22
import { AppComponent } from './app.component';
33

4-
import { By } from 'angular2/platform/browser';
5-
import { provide } from 'angular2/core';
4+
import { By } from 'angular2/platform/browser';
5+
import { DebugElement, provide } from 'angular2/core';
66

77
import {
88
beforeEach, beforeEachProviders,
99
describe, ddescribe, xdescribe,
1010
expect, it, iit, xit,
11-
inject, injectAsync,
12-
ComponentFixture, TestComponentBuilder
11+
async, inject, ComponentFixture, TestComponentBuilder
1312
} from 'angular2/testing';
1413

1514
import { Hero, HeroService, MockHeroService } from './mock-hero.service';
@@ -22,8 +21,8 @@ describe('AppComponent', () => {
2221
let fixture: ComponentFixture;
2322
let comp: AppComponent;
2423

25-
beforeEach(injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
26-
return tcb
24+
beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
25+
tcb
2726
.overrideDirective(AppComponent, RouterLink, MockRouterLink)
2827
.overrideDirective(AppComponent, RouterOutlet, MockRouterOutlet)
2928
.overrideProviders(AppComponent, [
@@ -35,7 +34,7 @@ describe('AppComponent', () => {
3534
fixture = fix;
3635
comp = fixture.debugElement.componentInstance;
3736
});
38-
}));
37+
})));
3938

4039
it('can instantiate it', () => {
4140
expect(comp).not.toBeNull();
@@ -51,8 +50,8 @@ describe('AppComponent', () => {
5150
fixture.detectChanges();
5251

5352
let links = fixture.debugElement
54-
.queryAll(function (de) { return de.componentInstance instanceof MockRouterLink; })
55-
.map(de => <MockRouterLink> de.componentInstance);
53+
.queryAll(By.directive(MockRouterLink))
54+
.map(de => <MockRouterLink> extractDirective(de, MockRouterLink));
5655

5756
expect(links.length).toEqual(2, 'should have 2 links');
5857
expect(links[0].routeParams[0]).toEqual('Dashboard', '1st link should go to Dashboard');
@@ -67,11 +66,12 @@ describe('AppComponent', () => {
6766

6867
// Heroes RouterLink DebugElement
6968
let heroesDe = fixture.debugElement
70-
.queryAll(function (de) { return de.componentInstance instanceof MockRouterLink; })[1];
69+
.queryAll(By.directive(MockRouterLink))[1];
7170

72-
expect(heroesDe).not.toBeNull('should 2nd link');
71+
expect(heroesDe).toBeDefined('should have a 2nd RouterLink');
72+
73+
let link = <MockRouterLink> extractDirective(heroesDe, MockRouterLink);
7374

74-
let link = <MockRouterLink> heroesDe.componentInstance;
7575
expect(link.navigatedTo).toBeNull('link should not have navigate yet');
7676

7777
heroesDe.triggerEventHandler('click', null);
@@ -82,3 +82,15 @@ describe('AppComponent', () => {
8282
});
8383
});
8484

85+
///////////// Helpers ////////////////////
86+
87+
import { Type } from 'angular2/src/facade/lang';
88+
89+
/**
90+
* Get the directive instance from the DebugElement to which it is attached
91+
*/
92+
function extractDirective(de: DebugElement, directive: Type): any {
93+
return de.injector.get(
94+
de.providerTokens[de.providerTokens.indexOf(directive)]
95+
);
96+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
2+
/* tslint:disable:no-unused-variable */
3+
/**
4+
* Tests that show what goes wrong when the tests are incorrectly written or have a problem
5+
*/
6+
import {
7+
BadTemplateUrl, ButtonComp,
8+
ChildChildComp, ChildComp, ChildWithChildComp,
9+
ExternalTemplateComp,
10+
FancyService, MockFancyService,
11+
InputComp,
12+
MyIfComp, MyIfChildComp, MyIfParentComp,
13+
MockChildComp, MockChildChildComp,
14+
ParentComp,
15+
TestProvidersComp, TestViewProvidersComp
16+
} from './bag';
17+
18+
import { DebugElement } from 'angular2/core';
19+
import { By } from 'angular2/platform/browser';
20+
21+
import {
22+
beforeEach, beforeEachProviders, withProviders,
23+
describe, ddescribe, xdescribe,
24+
expect, it, iit, xit,
25+
async, inject, fakeAsync, tick,
26+
ComponentFixture, TestComponentBuilder
27+
} from 'angular2/testing';
28+
29+
import { provide } from 'angular2/core';
30+
import { ViewMetadata } from 'angular2/core';
31+
import { PromiseWrapper } from 'angular2/src/facade/promise';
32+
import { XHR } from 'angular2/src/compiler/xhr';
33+
import { XHRImpl } from 'angular2/src/platform/browser/xhr_impl';
34+
import { Observable } from 'rxjs/Rx';
35+
36+
//////// SPECS /////////////
37+
38+
xdescribe('async & inject testing errors', () => {
39+
let originalJasmineIt: any;
40+
let originalJasmineBeforeEach: any;
41+
42+
let patchJasmineIt = () => {
43+
let deferred = PromiseWrapper.completer();
44+
originalJasmineIt = jasmine.getEnv().it;
45+
jasmine.getEnv().it = (description: string, fn: Function): jasmine.Spec => {
46+
let done = () => { deferred.resolve(); };
47+
(<any>done).fail = (err: any) => { deferred.reject(err); };
48+
fn(done);
49+
return null;
50+
};
51+
return deferred.promise;
52+
};
53+
54+
let restoreJasmineIt = () => { jasmine.getEnv().it = originalJasmineIt; };
55+
56+
let patchJasmineBeforeEach = () => {
57+
let deferred = PromiseWrapper.completer();
58+
originalJasmineBeforeEach = jasmine.getEnv().beforeEach;
59+
jasmine.getEnv().beforeEach = (fn: any): void => {
60+
let done = () => { deferred.resolve(); };
61+
(<any>done).fail = (err: any) => { deferred.reject(err); };
62+
fn(done);
63+
return null;
64+
};
65+
return deferred.promise;
66+
};
67+
68+
let restoreJasmineBeforeEach =
69+
() => { jasmine.getEnv().beforeEach = originalJasmineBeforeEach; };
70+
71+
const shouldNotSucceed =
72+
(done: DoneFn) => () => done.fail( 'Expected an error, but did not get one.');
73+
74+
const shouldFail =
75+
(done: DoneFn, emsg: string) => (err: any) => { expect(err).toEqual(emsg); done(); };
76+
77+
it('should fail when an asynchronous error is thrown', (done: DoneFn) => {
78+
let itPromise = patchJasmineIt();
79+
80+
it('throws an async error',
81+
async(inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); })));
82+
83+
itPromise.then(
84+
shouldNotSucceed(done),
85+
err => {
86+
expect(err).toEqual('bar');
87+
done();
88+
});
89+
restoreJasmineIt();
90+
});
91+
92+
it('should fail when a returned promise is rejected', (done: DoneFn) => {
93+
let itPromise = patchJasmineIt();
94+
95+
it('should fail with an error from a promise', async(inject([], () => {
96+
let deferred = PromiseWrapper.completer();
97+
let p = deferred.promise.then(() => { expect(1).toEqual(2); });
98+
99+
deferred.reject('baz');
100+
return p;
101+
})));
102+
103+
itPromise.then(
104+
shouldNotSucceed(done),
105+
err => {
106+
expect(err).toEqual('Uncaught (in promise): baz');
107+
done();
108+
});
109+
restoreJasmineIt();
110+
});
111+
112+
it('should fail when an error occurs inside inject', (done: DoneFn) => {
113+
let itPromise = patchJasmineIt();
114+
115+
it('throws an error', inject([], () => { throw new Error('foo'); }));
116+
117+
itPromise.then(
118+
shouldNotSucceed(done),
119+
shouldFail(done, 'foo')
120+
);
121+
restoreJasmineIt();
122+
});
123+
124+
// TODO(juliemr): reenable this test when we are using a test zone and can capture this error.
125+
it('should fail when an asynchronous error is thrown', (done: DoneFn) => {
126+
let itPromise = patchJasmineIt();
127+
128+
it('throws an async error',
129+
async(inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); })));
130+
131+
itPromise.then(
132+
shouldNotSucceed(done),
133+
shouldFail(done, 'bar')
134+
);
135+
restoreJasmineIt();
136+
});
137+
138+
it('should fail when XHR loading of a template fails', (done: DoneFn) => {
139+
let itPromise = patchJasmineIt();
140+
141+
it('should fail with an error from a promise',
142+
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
143+
tcb.createAsync(BadTemplateUrl);
144+
})));
145+
146+
itPromise.then(
147+
shouldNotSucceed(done),
148+
shouldFail(done, 'Uncaught (in promise): Failed to load non-existant.html')
149+
);
150+
restoreJasmineIt();
151+
}, 10000);
152+
153+
describe('using beforeEachProviders', () => {
154+
beforeEachProviders(() => [provide(FancyService, {useValue: new FancyService()})]);
155+
156+
beforeEach(
157+
inject([FancyService], (service: FancyService) => { expect(service.value).toEqual('real value'); }));
158+
159+
describe('nested beforeEachProviders', () => {
160+
161+
it('should fail when the injector has already been used', () => {
162+
patchJasmineBeforeEach();
163+
expect(() => {
164+
beforeEachProviders(() => [provide(FancyService, {useValue: new FancyService()})]);
165+
})
166+
.toThrowError('beforeEachProviders was called after the injector had been used ' +
167+
'in a beforeEach or it block. This invalidates the test injector');
168+
restoreJasmineBeforeEach();
169+
});
170+
});
171+
});
172+
});

0 commit comments

Comments
 (0)