docs(tutorial/ts): delete tutorial sample in favor of toh-6

This commit is contained in:
Ward Bell 2016-05-19 00:30:30 -07:00
parent e4db340464
commit e91659ac13
24 changed files with 134 additions and 550 deletions

View File

@ -2,15 +2,15 @@
import { Hero } from './hero'; import { Hero } from './hero';
export var HEROES: Hero[] = [ export var HEROES: Hero[] = [
{"id": 11, "name": "Mr. Nice"}, {id: 11, name: 'Mr. Nice'},
{"id": 12, "name": "Narco"}, {id: 12, name: 'Narco'},
{"id": 13, "name": "Bombasto"}, {id: 13, name: 'Bombasto'},
{"id": 14, "name": "Celeritas"}, {id: 14, name: 'Celeritas'},
{"id": 15, "name": "Magneta"}, {id: 15, name: 'Magneta'},
{"id": 16, "name": "RubberMan"}, {id: 16, name: 'RubberMan'},
{"id": 17, "name": "Dynama"}, {id: 17, name: 'Dynama'},
{"id": 18, "name": "Dr IQ"}, {id: 18, name: 'Dr IQ'},
{"id": 19, "name": "Magma"}, {id: 19, name: 'Magma'},
{"id": 20, "name": "Tornado"} {id: 20, name: 'Tornado'}
]; ];
// #enddocregion // #enddocregion

View File

@ -2,15 +2,15 @@
import { Hero } from './hero'; import { Hero } from './hero';
export var HEROES: Hero[] = [ export var HEROES: Hero[] = [
{"id": 11, "name": "Mr. Nice"}, {id: 11, name: 'Mr. Nice'},
{"id": 12, "name": "Narco"}, {id: 12, name: 'Narco'},
{"id": 13, "name": "Bombasto"}, {id: 13, name: 'Bombasto'},
{"id": 14, "name": "Celeritas"}, {id: 14, name: 'Celeritas'},
{"id": 15, "name": "Magneta"}, {id: 15, name: 'Magneta'},
{"id": 16, "name": "RubberMan"}, {id: 16, name: 'RubberMan'},
{"id": 17, "name": "Dynama"}, {id: 17, name: 'Dynama'},
{"id": 18, "name": "Dr IQ"}, {id: 18, name: 'Dr IQ'},
{"id": 19, "name": "Magma"}, {id: 19, name: 'Magma'},
{"id": 20, "name": "Tornado"} {id: 20, name: 'Tornado'}
]; ];
// #enddocregion // #enddocregion

View File

@ -32,7 +32,7 @@ describe('TOH Http Chapter', function () {
page.myHeroesHref.click().then(function() { page.myHeroesHref.click().then(function() {
browser.waitForAngular(); browser.waitForAngular();
heroCount = page.allHeroes.count(); heroCount = page.allHeroes.count();
expect(heroCount).toBe(4, 'should show 4'); expect(heroCount).toBe(10, 'should show 10');
}).then(function() { }).then(function() {
return page.addButton.click(); return page.addButton.click();
}).then(function(){ }).then(function(){
@ -41,7 +41,7 @@ describe('TOH Http Chapter', function () {
browser.waitForAngular(); browser.waitForAngular();
heroCount = page.allHeroes.count(); heroCount = page.allHeroes.count();
expect(heroCount).toBe(5, 'should show 5'); expect(heroCount).toBe(11, 'should show 11');
var newHero = element(by.xpath('//span[@class="hero-element" and contains(text(),"The New Hero")]')); var newHero = element(by.xpath('//span[@class="hero-element" and contains(text(),"The New Hero")]'));
expect(newHero).toBeDefined(); expect(newHero).toBeDefined();
@ -55,13 +55,13 @@ describe('TOH Http Chapter', function () {
page.myHeroesHref.click().then(function() { page.myHeroesHref.click().then(function() {
browser.waitForAngular(); browser.waitForAngular();
heroCount = page.allHeroes.count(); heroCount = page.allHeroes.count();
expect(heroCount).toBe(4, 'should show 4'); expect(heroCount).toBe(10, 'should show 10');
}).then(function() { }).then(function() {
return page.firstDeleteButton.click(); return page.firstDeleteButton.click();
}).then(function(){ }).then(function(){
browser.waitForAngular(); browser.waitForAngular();
heroCount = page.allHeroes.count(); heroCount = page.allHeroes.count();
expect(heroCount).toBe(3, 'should show 3'); expect(heroCount).toBe(9, 'should show 9');
}); });
}); });
@ -130,4 +130,94 @@ describe('TOH Http Chapter', function () {
return saveButtonEle.click(); return saveButtonEle.click();
}); });
} }
it('should be able to see the start screen', function () {
var page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.myDashboardHref.getText()).toEqual("Dashboard");
expect(page.myHeroesHref.getText()).toEqual("Heroes");
});
it('should be able to see dashboard choices', function () {
var page = getPageStruct();
expect(page.topHeroes.count()).toBe(4, "should be 4 dashboard hero choices");
});
it('should be able to toggle the views', function () {
var page = getPageStruct();
expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element');
expect(page.allHeroes.count()).toBeGreaterThan(4, "should be more than 4 heroes shown");
return page.myDashboardHref.click();
}).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element');
});
});
it('should be able to edit details from "Dashboard" view', function () {
var page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
var heroEle = page.topHeroes.get(3);
var heroDescrEle = heroEle.element(by.css('h4'));
var heroDescr;
return heroDescrEle.getText().then(function(text) {
heroDescr = text;
return heroEle.click();
}).then(function() {
return editDetails(page, heroDescr, '-foo');
}).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back');
expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo');
});
});
it('should be able to edit details from "Heroes" view', function () {
var page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present');
var viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
var heroEle, heroDescr;
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present');
heroEle = page.allHeroes.get(2);
return heroEle.getText();
}).then(function(text) {
// remove leading 'id' from the element
heroDescr = text.substr(text.indexOf(' ')+1);
return heroEle.click();
}).then(function() {
expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
return viewDetailsButtonEle.click();
}).then(function() {
return editDetails(page, heroDescr, '-bar');
}).then(function() {
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back');
expect(heroEle.getText()).toContain(heroDescr + '-bar');
expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present');
});
});
function editDetails(page, origValue, textToAdd) {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present');
expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details');
var inputEle = page.heroDetail.element(by.css('input'));
expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
var buttons = page.heroDetail.all(by.css('button'));
var backButtonEle = buttons.get(0);
var saveButtonEle = buttons.get(1);
expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
expect(saveButtonEle.isDisplayed()).toBe(true, 'should be able to see the save button');
var detailTextEle = page.heroDetail.element(by.css('div h2'));
expect(detailTextEle.getText()).toContain(origValue);
return sendKeys(inputEle, textToAdd).then(function () {
expect(detailTextEle.getText()).toContain(origValue + textToAdd);
return saveButtonEle.click();
});
}
}); });

View File

@ -2,10 +2,16 @@
export class InMemoryDataService { export class InMemoryDataService {
createDb() { createDb() {
let heroes = [ let heroes = [
{ id: 1, name: 'Windstorm' }, {id: 11, name: 'Mr. Nice'},
{ id: 2, name: 'Bombasto' }, {id: 12, name: 'Narco'},
{ id: 3, name: 'Magneta' }, {id: 13, name: 'Bombasto'},
{ id: 4, name: 'Tornado' } {id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'}
]; ];
return {heroes}; return {heroes};
} }

View File

@ -1,111 +0,0 @@
describe('Tutorial', function () {
beforeAll(function () {
browser.get('');
});
function getPageStruct() {
hrefEles = element.all(by.css('my-app a'));
return {
hrefs: hrefEles,
myDashboardHref: hrefEles.get(0),
myDashboardParent: element(by.css('my-app my-dashboard')),
topHeroes: element.all(by.css('my-app my-dashboard .module.hero')),
myHeroesHref: hrefEles.get(1),
myHeroesParent: element(by.css('my-app my-heroes')),
allHeroes: element.all(by.css('my-app my-heroes li')),
heroDetail: element(by.css('my-app my-hero-detail'))
}
}
it('should be able to see the start screen', function () {
var page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.myDashboardHref.getText()).toEqual("Dashboard");
expect(page.myHeroesHref.getText()).toEqual("Heroes");
});
it('should be able to see dashboard choices', function () {
var page = getPageStruct();
expect(page.topHeroes.count()).toBe(4, "should be 4 dashboard hero choices");
});
it('should be able to toggle the views', function () {
var page = getPageStruct();
expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element');
expect(page.allHeroes.count()).toBeGreaterThan(4, "should be more than 4 heroes shown");
return page.myDashboardHref.click();
}).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element');
});
});
it('should be able to edit details from "Dashboard" view', function () {
var page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
var heroEle = page.topHeroes.get(3);
var heroDescrEle = heroEle.element(by.css('h4'));
var heroDescr;
return heroDescrEle.getText().then(function(text) {
heroDescr = text;
return heroEle.click();
}).then(function() {
return editDetails(page, heroDescr, '-foo');
}).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back');
expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo');
});
});
it('should be able to edit details from "Heroes" view', function () {
var page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present');
var viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
var heroEle, heroDescr;
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present');
heroEle = page.allHeroes.get(2);
return heroEle.getText();
}).then(function(text) {
// remove leading 'id' from the element
heroDescr = text.substr(text.indexOf(' ')+1);
return heroEle.click();
}).then(function() {
expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
return viewDetailsButtonEle.click();
}).then(function() {
return editDetails(page, heroDescr, '-bar');
}).then(function() {
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back');
expect(heroEle.getText()).toContain(heroDescr + '-bar');
expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present');
});
});
function editDetails(page, origValue, textToAdd) {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present');
expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details');
var inputEle = page.heroDetail.element(by.css('input'));
expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
var backButtonEle = page.heroDetail.element(by.css('button'));
expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
var detailTextEle = page.heroDetail.element(by.css('div h2'));
expect(detailTextEle.getText()).toContain(origValue);
return sendKeys(inputEle, textToAdd).then(function () {
expect(detailTextEle.getText()).toContain(origValue + textToAdd);
return backButtonEle.click();
});
}
});

View File

@ -1,28 +0,0 @@
nav a {
padding: 5px 10px;
text-decoration: none;
margin-top: 10px;
display: inline-block;
background-color: #eee;
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
nav a.router-link-active {
color: #039be5;
}
h1 {
font-size: 1.2em;
color: #999;
margin-bottom: 0;
}
h2 {
font-size: 2em;
margin-top: 0;
padding-top: 0;
}

View File

@ -1,31 +0,0 @@
import { Component } from '@angular/core';
import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
import { DashboardComponent } from './dashboard.component';
import { HeroService } from './hero.service';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<nav>
<a [routerLink]="['Dashboard']">Dashboard</a>
<a [routerLink]="['Heroes']">Heroes</a>
</nav>
<router-outlet></router-outlet>
`,
styleUrls: ['app/app.component.css'],
directives: [ROUTER_DIRECTIVES],
providers: [HeroService]
})
@RouteConfig([
// {path: '/', redirectTo: ['Dashboard'] },
{path: '/dashboard', name: 'Dashboard', component: DashboardComponent, useAsDefault: true},
{path: '/heroes', name: 'Heroes', component: HeroesComponent},
{path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent}
])
export class AppComponent {
title = 'Tour of Heroes';
}

View File

@ -1,60 +0,0 @@
[class*='col-'] {
float: left;
}
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
}
[class*='col-'] {
padding-right: 20px;
padding-bottom: 20px;
}
[class*='col-']:last-of-type {
padding-right: 0;
}
.grid {
margin: 0;
}
.col-1-4 {
width: 25%;
}
.module {
padding: 20px;
text-align: center;
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607D8B;
border-radius: 2px;
}
h4 {
position: relative;
}
.module:hover {
background-color: #EEE;
cursor: pointer;
color: #607d8b;
}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
padding-right: 20px;
}
@media (max-width: 600px) {
.module {
font-size: 10px;
max-height: 75px; }
}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
.module {
min-width: 60px;
}
}

View File

@ -1,8 +0,0 @@
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<div *ngFor="let hero of heroes" class="col-1-4" (click)="gotoDetail(hero)">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>
</div>
</div>

View File

@ -1,25 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router-deprecated';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'my-dashboard',
templateUrl: 'app/dashboard.component.html',
styleUrls: ['app/dashboard.component.css']
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(private heroService: HeroService, private _router: Router) { }
ngOnInit() {
this.heroService.getHeroes().then(heroes => this.heroes = heroes.slice(1,5));
}
gotoDetail(hero: Hero) {
let link = ['HeroDetail', { id: hero.id }];
this._router.navigate(link);
}
}

View File

@ -1,29 +0,0 @@
label {
display: inline-block;
width: 3em;
margin: .5em 0;
color: #607D8B;
font-weight: bold;
}
input {
height: 2em;
font-size: 1em;
padding-left: .4em;
}
button {
margin-top: 20px;
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #ccc;
cursor: auto;
}

View File

@ -1,10 +0,0 @@
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div>
<label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
<button (click)="goBack()">Back</button>
</div>

View File

@ -1,27 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { RouteParams } from '@angular/router-deprecated';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'my-hero-detail',
templateUrl: 'app/hero-detail.component.html',
styleUrls: ['app/hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
hero: Hero;
constructor(private heroService: HeroService,
private routeParams: RouteParams) {
}
ngOnInit() {
let id = +this.routeParams.get('id');
this.heroService.getHero(id).then(hero => this.hero = hero);
}
goBack() {
window.history.back();
}
}

View File

@ -1,16 +0,0 @@
import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
getHeroes() {
return Promise.resolve(HEROES);
}
getHero(id: number) {
return Promise.resolve(HEROES).then(
heroes => heroes.filter(hero => hero.id === id)[0]
);
}
}

View File

@ -1,4 +0,0 @@
export class Hero {
id: number;
name: string;
}

View File

@ -1,59 +0,0 @@
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
button {
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}

View File

@ -1,14 +0,0 @@
<div>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<div *ngIf="selectedHero">
<h2>{{selectedHero.name | uppercase}} is my hero</h2>
<button (click)="gotoDetail()">View Details</button>
</div>
</div>

View File

@ -1,32 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router-deprecated';
import { HeroService } from './hero.service';
import { HeroDetailComponent } from './hero-detail.component';
import { Hero } from './hero';
@Component({
selector: 'my-heroes',
templateUrl: 'app/heroes.component.html',
styleUrls: ['app/heroes.component.css'],
directives: [HeroDetailComponent]
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(private heroService: HeroService, private router: Router) { }
getHeroes() {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
gotoDetail() {
this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
}
ngOnInit() {
this.getHeroes();
}
onSelect(hero: Hero) { this.selectedHero = hero; }
}

View File

@ -1,10 +0,0 @@
import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { HeroService } from './hero.service';
import { AppComponent } from './app.component';
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
HeroService
]);

View File

@ -1,14 +0,0 @@
import { Hero } from './hero';
export var HEROES: Hero[] = [
{"id": 11, "name": "Mr. Nice"},
{"id": 12, "name": "Narco"},
{"id": 13, "name": "Bombasto"},
{"id": 14, "name": "Celeritas"},
{"id": 15, "name": "Magneta"},
{"id": 16, "name": "RubberMan"},
{"id": 17, "name": "Dynama"},
{"id": 18, "name": "Dr IQ"},
{"id": 19, "name": "Magma"},
{"id": 20, "name": "Tornado"}
];

View File

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>Angular 2 Tour of Heroes</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>

View File

@ -1,8 +0,0 @@
{
"description": "Tour of Heroes",
"files":[
"!**/*.d.ts",
"!**/*.js"
],
"tags": ["tutorial", "tour", "heroes"]
}

View File

@ -27,7 +27,7 @@ include ../_util-fns
// #enddocregion intro // #enddocregion intro
:marked :marked
[Run the live example](/resources/live-examples/tutorial/ts/plnkr.html) [Run the live example](/resources/live-examples/toh-6/ts/plnkr.html)
// #docregion main // #docregion main
.l-main-section .l-main-section