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

docs(testing): fix hero-detail impl and use done for observable tests #3270

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class Page {
}

constructor() {
router.events.forEach(e => this.recordedEvents.push(e));
router.events.subscribe(e => this.recordedEvents.push(e));
const links = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref));
this.aboutLinkDe = links[2];
this.dashboardLinkDe = links[0];
Expand Down
38 changes: 25 additions & 13 deletions public/docs/_examples/testing/ts/src/app/bag/async-helper.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// tslint:disable-next-line:no-unused-variable
import { async, fakeAsync, tick } from '@angular/core/testing';

import { Observable } from 'rxjs/Observable';
Expand Down Expand Up @@ -31,26 +32,37 @@ describe('Angular async helper', () => {
p.catch(() => { actuallyDone = true; });
}));

// Fail message: Cannot use setInterval from within an async zone test
// Use done. Cannot use setInterval with async or fakeAsync
// See https://github.com/angular/angular/issues/10127
xit('should run async test with successful delayed Observable', async(() => {
it('should run async test with successful delayed Observable', done => {
const source = Observable.of(true).delay(10);
source.subscribe(
val => actuallyDone = true,
err => fail(err)
err => fail(err),
done
);
}));
});

// Fail message: Error: 1 periodic timer(s) still in the queue
// Cannot use setInterval from within an async zone test
// See https://github.com/angular/angular/issues/10127
xit('should run async test with successful delayed Observable', fakeAsync(() => {
const source = Observable.of(true).delay(10);
source.subscribe(
val => actuallyDone = true,
err => fail(err)
);
// xit('should run async test with successful delayed Observable', async(() => {
// const source = Observable.of(true).delay(10);
// source.subscribe(
// val => actuallyDone = true,
// err => fail(err)
// );
// }));

tick();
}));
// // Fail message: Error: 1 periodic timer(s) still in the queue
// // See https://github.com/angular/angular/issues/10127
// xit('should run async test with successful delayed Observable', fakeAsync(() => {
// const source = Observable.of(true).delay(10);
// source.subscribe(
// val => actuallyDone = true,
// err => fail(err)
// );

// tick();
// }));

});
16 changes: 8 additions & 8 deletions public/docs/_examples/testing/ts/src/app/bag/bag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ describe('use inject helper in beforeEach', () => {
);
}));

// #enddocregion FancyService
// See https://github.com/angular/angular/issues/10127
xit('test should wait for FancyService.getObservableDelayValue', async(() => {
service.getObservableDelayValue().subscribe(
value => expect(value).toBe('observable delay value')
);
}));
// #docregion FancyService
// Must use done. See https://github.com/angular/angular/issues/10127
it('test should wait for FancyService.getObservableDelayValue', done => {
service.getObservableDelayValue().subscribe(value => {
expect(value).toBe('observable delay value');
done();
});
});

it('should allow the use of fakeAsync', fakeAsync(() => {
let value: any;
service.getAsyncValue().then((val: any) => value = val);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ export class HeroDetailComponent implements OnInit {
// #docregion ng-on-init
ngOnInit(): void {
// get hero when `id` param changes
this.route.params.map(p => p['id'])
.forEach(id => this.getHero(id))
.catch(() => this.hero = new Hero()); // no id; should edit new hero
this.route.params.subscribe(p => this.getHero(p && p['id']));
}
// #enddocregion ng-on-init

private getHero(id: string): void {
// when no id or id===0, create new hero
if (!id) {
this.hero = new Hero();
return;
}

this.heroDetailService.getHero(id).then(hero => {
if (hero) {
this.hero = hero;
Expand Down
12 changes: 5 additions & 7 deletions public/docs/ts/latest/guide/testing.jade
Original file line number Diff line number Diff line change
Expand Up @@ -1105,17 +1105,15 @@ a#routed-component-w-param
Here's the `HeroDetailComponent` constructor:
+makeExample('testing/ts/src/app/hero/hero-detail.component.ts', 'ctor', 'src/app/hero/hero-detail.component.ts (constructor)')(format='.')
:marked
`HeroDetailComponent` listens for changes to the `ActivatedRoute.params` in its `ngOnInit` method.
`HeroDetailComponent` subscribes to `ActivatedRoute.params` changes in its `ngOnInit` method.
+makeExample('testing/ts/src/app/hero/hero-detail.component.ts', 'ng-on-init', 'src/app/hero/hero-detail.component.ts (ngOnInit)')(format='.')
.l-sub-section
:marked
The expression after `route.params` chains an _Observable_ operator that _plucks_ the `id` from the `params`
and then chains a `forEach` operator to subscribes to `id`-changing events.
The `id` changes every time the user navigates to a different hero.

The `forEach` passes the new `id` value to the component's `getHero` method (not shown)
The subscription confirms that there are `params` and, if there are,
plucks the `id` from those `params`.
It passes the `id` to the component's `getHero` method (not shown)
which fetches a hero and sets the component's `hero` property.
If the`id` parameter is missing, the `pluck` operator fails and the `catch` treats failure as a request to edit a new hero.
The `getHero` method treats an undefined `id` or `id===0` as a request to edit a new hero.

The [Router](router.html#route-parameters) guide covers `ActivatedRoute.params` in more detail.
:marked
Expand Down