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

Commit b6534c0

Browse files
committed
docs(hierarchical di): Correct avoidance example (#3086) and other tweaks
closes #3086 sample reworked to conform to our sample style, to make more sense, and cover the examples discussed copy edits to bring closer to Google docs standards.
1 parent 09f79e3 commit b6534c0

25 files changed

+623
-302
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,106 @@
1-
import { browser, element, by } from 'protractor';
1+
'use strict'; // necessary for es6 output in node
22

3-
describe('Hierarchical dependency injection', function () {
3+
import { browser, by, element, ElementFinder } from 'protractor';
44

5-
beforeEach(function () {
5+
describe('Hierarchical dependency injection', () => {
6+
7+
beforeAll(() => {
68
browser.get('');
79
});
810

9-
it('should open with a card view', function () {
10-
expect(element.all(by.cssContainingText('button', 'edit')).get(0).isDisplayed()).toBe(true,
11-
'edit button should be displayed');
12-
});
11+
describe('Heroes Scenario', () => {
12+
let page = {
13+
heroName: '',
14+
heroText: '',
1315

14-
it('should have multiple heroes listed', function () {
15-
expect(element.all(by.css('heroes-list li')).count()).toBeGreaterThan(1);
16-
});
16+
// queries
17+
heroEl: element.all(by.css('heroes-list li')).get(0), // first hero
18+
heroCardEl: element(by.css('heroes-list hero-card')), // first hero card
19+
cardNameInputEl: element.all(by.css('heroes-list hero-card input')).get(0),
20+
cancelButtonEl: element(by.cssContainingText('heroes-list hero-card button', 'Cancel')),
21+
closeButtonEl: element(by.cssContainingText('heroes-list hero-card button', 'Close')),
22+
saveButtonEl: element(by.cssContainingText('heroes-list hero-card button', 'Save'))
23+
}
1724

18-
it('should change to editor view after selection', function () {
19-
let editButtonEle = element.all(by.cssContainingText('button', 'edit')).get(0);
20-
editButtonEle.click().then(function() {
21-
expect(editButtonEle.isDisplayed()).toBe(false, 'edit button should be hidden after selection');
25+
it('should list multiple heroes', () => {
26+
expect(element.all(by.css('heroes-list li')).count()).toBeGreaterThan(1);
27+
});
28+
29+
it('should show no hero cards at the start', () => {
30+
expect(element.all(by.css('heroes-list li hero-card')).count()).toBe(0);
31+
});
32+
33+
it('should open first hero in hero-card view after click', () => {
34+
page.heroEl.getText()
35+
.then(val => {
36+
// console.log('Selected hero text: ' + val);
37+
page.heroText = val;
38+
page.heroName = val.substring(0, val.indexOf('()') - 1)
39+
})
40+
.then(() => page.heroEl.click())
41+
.then(() => {
42+
expect(page.heroCardEl.isDisplayed()).toBe(true);
43+
});
44+
});
45+
46+
it('hero card should have first hero\'s name', () => {
47+
// Not `page.cardNameInputEl.getAttribute('value')` although later that is essential
48+
expect(page.cardNameInputEl.getText()).toEqual(page.heroName);
49+
});
50+
51+
it('should be able to cancel change', () => {
52+
page.cardNameInputEl.sendKeys('foo')
53+
.then(() => {
54+
expect(page.cardNameInputEl.getAttribute('value')).toContain('foo', 'input name should have foo');
55+
expect(page.heroEl.getText()).toEqual(page.heroText, 'list text should be unchanged');
56+
return page.cancelButtonEl.click();
57+
})
58+
.then(() => {
59+
expect(page.cardNameInputEl.getAttribute('value')).not.toContain('foo', 'input name should not have foo');
60+
expect(page.heroEl.getText()).toEqual(page.heroText, 'list text should be unchanged');
61+
});
62+
});
63+
64+
it('should be able to save change', () => {
65+
page.cardNameInputEl.sendKeys('bar')
66+
.then(() => {
67+
expect(page.cardNameInputEl.getAttribute('value')).toContain('bar', 'input name should have bar');
68+
expect(page.heroEl.getText()).toEqual(page.heroText, 'list text should be unchanged');
69+
return page.saveButtonEl.click();
70+
})
71+
.then(() => {
72+
expect(page.cardNameInputEl.getAttribute('value')).toContain('bar', 'input name should still have bar');
73+
expect(page.heroEl.getText()).toContain('bar', 'list text should have changed to include bar');
74+
});
75+
});
76+
77+
it('should be able to close card', () => {
78+
page.saveButtonEl.click()
79+
.then(() => {
80+
expect(element.all(by.css('heroes-list li hero-card')).count()).toBe(0);
81+
});
2282
});
23-
});
2483

25-
it('should be able to save editor change', function () {
26-
testEdit(true);
2784
});
2885

29-
it('should be able to cancel editor change', function () {
30-
testEdit(false);
86+
describe('Villains Scenario', () => {
87+
it('should list multiple villains', () => {
88+
expect(element.all(by.css('villains-list li')).count()).toBeGreaterThan(1);
89+
});
3190
});
3291

33-
function testEdit(shouldSave: boolean) {
34-
// select 2nd ele
35-
let heroEle = element.all(by.css('heroes-list li')).get(1);
36-
// get the 2nd span which is the name of the hero
37-
let heroNameEle = heroEle.all(by.css('hero-card span')).get(1);
38-
let editButtonEle = heroEle.element(by.cssContainingText('button', 'edit'));
39-
editButtonEle.click().then(function() {
40-
let inputEle = heroEle.element(by.css('hero-editor input'));
41-
return inputEle.sendKeys('foo');
42-
}).then(function() {
43-
let buttonName = shouldSave ? 'save' : 'cancel';
44-
let buttonEle = heroEle.element(by.cssContainingText('button', buttonName));
45-
return buttonEle.click();
46-
}).then(function() {
47-
if (shouldSave) {
48-
expect(heroNameEle.getText()).toContain('foo');
49-
} else {
50-
expect(heroNameEle.getText()).not.toContain('foo');
51-
}
52-
});
53-
}
92+
describe('Cars Scenario', () => {
5493

94+
it('A-component should use expected services', () => {
95+
expect(element(by.css('a-car')).getText()).toContain('C1-E1-T1');
96+
});
97+
98+
it('B-component should use expected services', () => {
99+
expect(element(by.css('b-car')).getText()).toContain('C2-E2-T1');
100+
});
55101

102+
it('C-component should use expected services', () => {
103+
expect(element(by.css('c-car')).getText()).toContain('C3-E2-T1');
104+
});
105+
});
56106
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'my-app',
5+
template: `
6+
<label><input type="checkbox" [checked]="showHeroes" (change)="showHeroes=!showHeroes">Heroes</label>
7+
<label><input type="checkbox" [checked]="showVillains" (change)="showVillains=!showVillains">Villains</label>
8+
<label><input type="checkbox" [checked]="showCars" (change)="showCars=!showCars">Cars</label>
9+
10+
<h1>Hierarchical Dependency Injection</h1>
11+
12+
<heroes-list *ngIf="showHeroes"></heroes-list>
13+
<villains-list *ngIf="showVillains"></villains-list>
14+
<my-cars *ngIf="showCars"></my-cars>
15+
`
16+
})
17+
export class AppComponent {
18+
showCars = true;
19+
showHeroes = true;
20+
showVillains = true;
21+
}
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,33 @@
11
// #docregion
2-
import { NgModule } from '@angular/core';
2+
import { NgModule } from '@angular/core';
33
import { BrowserModule } from '@angular/platform-browser';
4-
import { FormsModule } from '@angular/forms';
4+
import { FormsModule } from '@angular/forms';
55

6-
import { HeroesListComponent } from './heroes-list.component';
7-
import { HeroEditorComponent } from './hero-editor.component';
8-
import { HeroCardComponent } from './hero-card.component';
9-
import { HeroesService } from './heroes.service';
6+
import { AppComponent } from './app.component';
7+
import { HeroCardComponent } from './hero-card.component';
8+
import { HeroesListComponent } from './heroes-list.component';
9+
import { HeroesService } from './heroes.service';
10+
import { VillainsListComponent } from './villains-list.component';
11+
12+
import { carComponents, carServices } from './car.components';
1013

1114
@NgModule({
1215
imports: [
1316
BrowserModule,
1417
FormsModule
1518
],
16-
providers: [ HeroesService ],
19+
providers: [
20+
carServices,
21+
HeroesService
22+
],
1723
declarations: [
24+
AppComponent,
25+
carComponents,
1826
HeroesListComponent,
1927
HeroCardComponent,
20-
HeroEditorComponent
28+
VillainsListComponent
2129
],
22-
bootstrap: [ HeroesListComponent ]
30+
bootstrap: [ AppComponent ]
2331
})
2432
export class AppModule { }
2533

26-
/* Documentation artifact below
27-
// #docregion bad-alternative
28-
// Don't do this!
29-
@NgModule({
30-
imports: [
31-
BrowserModule,
32-
FormsModule
33-
],
34-
providers: [ HeroesService, RestoreService ],
35-
declarations: [ HeroesListComponent ],
36-
bootstrap: [
37-
HeroesListComponent,
38-
HeroCardComponent,
39-
HeroEditorComponent
40-
]
41-
})
42-
// #enddocregion bad-alternative
43-
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Component } from '@angular/core';
2+
3+
import {
4+
CarService, CarService2, CarService3,
5+
EngineService, EngineService2, TiresService
6+
} from './car.services';
7+
8+
////////// CCarComponent ////////////
9+
@Component({
10+
selector: 'c-car',
11+
template: `<div>C: {{description}}</div>`,
12+
providers: [
13+
{ provide: CarService, useClass: CarService3 }
14+
]
15+
})
16+
export class CCarComponent {
17+
description: string;
18+
constructor(carService: CarService) {
19+
this.description = `${carService.getCar().description} (${carService.name})`;
20+
}
21+
}
22+
23+
////////// BCarComponent ////////////
24+
@Component({
25+
selector: 'b-car',
26+
template: `
27+
<div>B: {{description}}</div>
28+
<c-car></c-car>
29+
`,
30+
providers: [
31+
{ provide: CarService, useClass: CarService2 },
32+
{ provide: EngineService, useClass: EngineService2 }
33+
]
34+
})
35+
export class BCarComponent {
36+
description: string;
37+
constructor(carService: CarService) {
38+
this.description = `${carService.getCar().description} (${carService.name})`;
39+
}
40+
}
41+
42+
////////// ACarComponent ////////////
43+
@Component({
44+
selector: 'a-car',
45+
template: `
46+
<div>A: {{description}}</div>
47+
<b-car></b-car>`
48+
})
49+
export class ACarComponent {
50+
description: string;
51+
constructor(carService: CarService) {
52+
this.description = `${carService.getCar().description} (${carService.name})`;
53+
}
54+
}
55+
////////// CarsComponent ////////////
56+
@Component({
57+
selector: 'my-cars',
58+
template: `
59+
<h3>Cars</h3>
60+
<a-car></a-car>`
61+
})
62+
export class CarsComponent { }
63+
64+
////////////////
65+
66+
export const carComponents = [
67+
CarsComponent,
68+
ACarComponent, BCarComponent, CCarComponent
69+
];
70+
71+
// generic car-related services
72+
export const carServices = [
73+
CarService, EngineService, TiresService
74+
];

0 commit comments

Comments
 (0)