docs(aio): fix badly formatted code-examples

closes #19970
This commit is contained in:
Peter Bacon Darwin 2017-10-23 14:47:21 +01:00 committed by Victor Berchet
parent 0355142737
commit feae55b264
2 changed files with 169 additions and 355 deletions

View File

@ -46,6 +46,7 @@ The following table lists some of the key AngularJS template features with their
### Bindings/interpolation
<code-example hideCopy>
Your favorite hero is: {{vm.favoriteHero}}
</code-example>
@ -64,9 +65,8 @@ The following table lists some of the key AngularJS template features with their
### Bindings/interpolation
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="interpolation" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="interpolation" linenums="false"></code-example>
In Angular, a template expression in curly braces still denotes one-way binding.
@ -86,6 +86,7 @@ The following table lists some of the key AngularJS template features with their
### Filters
<code-example hideCopy>
&lt;td>{{movie.title | uppercase}}&lt;/td>
</code-example>
@ -100,9 +101,8 @@ The following table lists some of the key AngularJS template features with their
### Pipes
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="uppercase" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="uppercase" linenums="false"></code-example>
In Angular you use similar syntax with the pipe (|) character to filter output, but now you call them **pipes**.
@ -120,6 +120,7 @@ The following table lists some of the key AngularJS template features with their
### Local variables
<code-example hideCopy format="">
&lt;tr ng-repeat="movie in vm.movies">
&lt;td>{{movie.title}}&lt;/td>
@ -134,9 +135,8 @@ The following table lists some of the key AngularJS template features with their
### Input variables
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="local" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="local" linenums="false"></code-example>
Angular has true template input variables that are explicitly defined using the `let` keyword.
@ -184,6 +184,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-app
<code-example hideCopy>
&lt;body ng-app="movieHunter">
</code-example>
@ -200,13 +201,11 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bootstrapping
<code-example hideCopy path="ajs-quick-reference/src/main.ts" title="main.ts" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/main.ts" title="main.ts" linenums="false"></code-example>
<br>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" title="app.module.ts" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" title="app.module.ts" linenums="false"></code-example>
Angular doesn't have a bootstrap directive.
@ -225,6 +224,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-class
<code-example hideCopy format="">
&lt;div ng-class="{active: isActive}">
&lt;div ng-class="{active: isActive,
@ -246,9 +246,8 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngClass
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngClass" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngClass" linenums="false"></code-example>
In Angular, the `ngClass` directive works similarly.
@ -261,7 +260,7 @@ The following are some of the key AngularJS built-in directives and their equiva
Angular also has **class binding**, which is a good way to add or remove a single class,
as shown in the third example.
For more information see the [Attribute, class, and style bindings](guide/template-syntax#other-bindings)
For more information see the [Attribute, class, and style bindings](guide/template-syntax#other-bindings)
section of the [Template Syntax](guide/template-syntax) page.
</td>
@ -274,6 +273,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-click
<code-example hideCopy format="">
&lt;button ng-click="vm.toggleImage()">
&lt;button ng-click="vm.toggleImage($event)">
@ -292,9 +292,8 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `click` event
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="event-binding" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="event-binding" linenums="false"></code-example>
AngularJS event-based directives do not exist in Angular.
@ -312,7 +311,7 @@ The following are some of the key AngularJS built-in directives and their equiva
For a list of DOM events, see: https://developer.mozilla.org/en-US/docs/Web/Events.
For more information, see the [Event binding](guide/template-syntax#event-binding)
For more information, see the [Event binding](guide/template-syntax#event-binding)
section of the [Template Syntax](guide/template-syntax) page.
</td>
@ -325,6 +324,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-controller
<code-example hideCopy format="">
&lt;div ng-controller="MovieListCtrl as vm">
</code-example>
@ -339,9 +339,8 @@ The following are some of the key AngularJS built-in directives and their equiva
### Component decorator
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component" linenums="false"></code-example>
In Angular, the template no longer specifies its associated controller.
@ -379,6 +378,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-href
<code-example hideCopy format="">
&lt;a ng-href="{{ angularDocsUrl }}">Angular Docs&lt;/a>
</code-example>
@ -389,6 +389,7 @@ The following are some of the key AngularJS built-in directives and their equiva
fetches from that URL.
In AngularJS, the `ng-href` is often used to activate a route as part of navigation.
<code-example hideCopy format="">
&lt;a ng-href="#{{ moviesHash }}">Movies&lt;/a>
</code-example>
@ -401,24 +402,22 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `href` property
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="href" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="href" linenums="false"></code-example>
Angular uses property binding; there is no built-in *href* directive.
Place the element's `href` property in square brackets and set it to a quoted template expression.
For more information see the [Property binding](guide/template-syntax#property-binding)
For more information see the [Property binding](guide/template-syntax#property-binding)
section of the [Template Syntax](guide/template-syntax) page.
In Angular, `href` is no longer used for routing. Routing uses `routerLink`, as shown in the following example.
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="router-link" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="router-link" linenums="false"></code-example>
For more information on routing, see the [RouterLink binding](guide/router#router-link)
For more information on routing, see the [RouterLink binding](guide/router#router-link)
section of the [Routing & Navigation](guide/router) page.
</td>
@ -431,6 +430,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-if
<code-example hideCopy format="">
&lt;table ng-if="movies.length">
</code-example>
@ -446,12 +446,11 @@ The following are some of the key AngularJS built-in directives and their equiva
### *ngIf
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngIf" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngIf" linenums="false"></code-example>
The `*ngIf` directive in Angular works the same as the `ng-if` directive in AngularJS. It removes
The `*ngIf` directive in Angular works the same as the `ng-if` directive in AngularJS. It removes
or recreates a portion of the DOM based on an expression.
In this example, the `<table>` element is removed from the DOM unless the `movies` array has a length.
@ -468,6 +467,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-model
<code-example hideCopy format="">
&lt;input ng-model="vm.favoriteHero"/>
</code-example>
@ -481,16 +481,15 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngModel
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngModel" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngModel" linenums="false"></code-example>
In Angular, **two-way binding** is denoted by `[()]`, descriptively referred to as a "banana in a box". This syntax is a shortcut for defining both property binding (from the component to the view)
and event binding (from the view to the component), thereby providing two-way binding.
For more information on two-way binding with `ngModel`, see the [NgModel&mdash;Two-way binding to
form elements with `[(ngModel)]`](../guide/template-syntax.html#ngModel)
For more information on two-way binding with `ngModel`, see the [NgModel&mdash;Two-way binding to
form elements with `[(ngModel)]`](../guide/template-syntax.html#ngModel)
section of the [Template Syntax](guide/template-syntax) page.
</td>
@ -502,6 +501,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-repeat
<code-example hideCopy format="">
&lt;tr ng-repeat="movie in vm.movies">
</code-example>
@ -517,12 +517,11 @@ The following are some of the key AngularJS built-in directives and their equiva
### *ngFor
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngFor" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngFor" linenums="false"></code-example>
The `*ngFor` directive in Angular is similar to the `ng-repeat` directive in AngularJS. It repeats
The `*ngFor` directive in Angular is similar to the `ng-repeat` directive in AngularJS. It repeats
the associated DOM element for each item in the specified collection.
More accurately, it turns the defined element (`<tr>` in this example) and its contents into a template and
uses that template to instantiate a view for each item in the list.
@ -543,6 +542,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-show
<code-example hideCopy format="">
&lt;h3 ng-show="vm.favoriteHero">
Your favorite hero is: {{vm.favoriteHero}}
@ -560,9 +560,8 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `hidden` property
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="hidden" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="hidden" linenums="false"></code-example>
Angular uses property binding; there is no built-in *show* directive.
@ -573,7 +572,7 @@ The following are some of the key AngularJS built-in directives and their equiva
In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy.
For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)
For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)
section of the [Template Syntax](guide/template-syntax) page.
</td>
@ -585,6 +584,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-src
<code-example hideCopy format="">
&lt;img ng-src="{{movie.imageurl}}">
</code-example>
@ -599,15 +599,14 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `src` property
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="src" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="src" linenums="false"></code-example>
Angular uses property binding; there is no built-in *src* directive.
Place the `src` property in square brackets and set it to a quoted template expression.
For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)
For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)
section of the [Template Syntax](guide/template-syntax) page.
</td>
@ -619,6 +618,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-style
<code-example hideCopy format="">
&lt;div ng-style="{color: colorPreference}">
</code-example>
@ -636,9 +636,8 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngStyle
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngStyle" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngStyle" linenums="false"></code-example>
In Angular, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression.
@ -647,10 +646,10 @@ The following are some of the key AngularJS built-in directives and their equiva
Angular also has **style binding**, which is good way to set a single style. This is shown in the second example.
For more information on style binding, see the [Style binding](guide/template-syntax#style-binding) section of the
For more information on style binding, see the [Style binding](guide/template-syntax#style-binding) section of the
[Template Syntax](guide/template-syntax) page.
For more information on the `ngStyle` directive, see [NgStyle](guide/template-syntax#ngStyle)
For more information on the `ngStyle` directive, see [NgStyle](guide/template-syntax#ngStyle)
section of the [Template Syntax](guide/template-syntax) page.
</td>
@ -662,6 +661,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ng-switch
<code-example hideCopy format="">
&lt;div ng-switch="vm.favoriteHero &&
vm.checkMovieHero(vm.favoriteHero)">
@ -691,9 +691,8 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngSwitch
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngSwitch" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngSwitch" linenums="false"></code-example>
In Angular, the `ngSwitch` directive works similarly.
@ -707,7 +706,7 @@ The following are some of the key AngularJS built-in directives and their equiva
The (*) before `ngSwitchCase` and `ngSwitchDefault` is required in this example.
For more information, see [The NgSwitch directives](guide/template-syntax#ngSwitch)
For more information, see [The NgSwitch directives](guide/template-syntax#ngSwitch)
section of the [Template Syntax](guide/template-syntax) page.
</td>
@ -754,6 +753,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### currency
<code-example hideCopy>
&lt;td>{{movie.price | currency}}&lt;/td>
</code-example>
@ -766,9 +766,8 @@ For more information on pipes, see [Pipes](guide/pipes).
### currency
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="currency" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="currency" linenums="false"></code-example>
The Angular `currency` pipe is similar although some of the parameters have changed.
@ -782,6 +781,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### date
<code-example hideCopy>
&lt;td>{{movie.releaseDate | date}}&lt;/td>
</code-example>
@ -794,9 +794,8 @@ For more information on pipes, see [Pipes](guide/pipes).
### date
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="date" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="date" linenums="false"></code-example>
The Angular `date` pipe is similar.
@ -811,6 +810,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### filter
<code-example hideCopy>
&lt;tr ng-repeat="movie in movieList | filter: {title:listFilter}">
</code-example>
@ -835,6 +835,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### json
<code-example hideCopy>
&lt;pre>{{movie | json}}&lt;/pre>
</code-example>
@ -847,9 +848,8 @@ For more information on pipes, see [Pipes](guide/pipes).
### json
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="json" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="json" linenums="false"></code-example>
The Angular `json` pipe does the same thing.
@ -863,6 +863,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### limitTo
<code-example hideCopy>
&lt;tr ng-repeat="movie in movieList | limitTo:2:0">
</code-example>
@ -876,9 +877,8 @@ For more information on pipes, see [Pipes](guide/pipes).
### slice
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="slice" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="slice" linenums="false"></code-example>
The `SlicePipe` does the same thing but the *order of the parameters is reversed*, in keeping
@ -895,6 +895,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### lowercase
<code-example hideCopy>
&lt;div>{{movie.title | lowercase}}&lt;/div>
</code-example>
@ -907,9 +908,8 @@ For more information on pipes, see [Pipes](guide/pipes).
### lowercase
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="lowercase" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="lowercase" linenums="false"></code-example>
The Angular `lowercase` pipe does the same thing.
@ -936,10 +936,8 @@ For more information on pipes, see [Pipes](guide/pipes).
### number
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="number" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="number" linenums="false"></code-example>
The Angular `number` pipe is similar.
@ -958,7 +956,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### orderBy
<code-example hideCopy>
&lt;tr ng-repeat="movie in movieList | orderBy : 'title'">
</code-example>
@ -1025,6 +1023,7 @@ The Angular code is shown using TypeScript.
### IIFE
<code-example hideCopy>
(function () {
...
@ -1032,7 +1031,7 @@ The Angular code is shown using TypeScript.
</code-example>
In AngularJS, an immediately invoked function expression (or IIFE) around controller code
In AngularJS, an immediately invoked function expression (or IIFE) around controller code
keeps it out of the global namespace.
</td>
@ -1041,10 +1040,10 @@ The Angular code is shown using TypeScript.
### none
This is a nonissue in Angular because ES 2015 modules
This is a nonissue in Angular because ES 2015 modules
handle the namespacing for you.
For more information on modules, see the [Modules](guide/architecture#modules) section of the
For more information on modules, see the [Modules](guide/architecture#modules) section of the
[Architecture Overview](guide/architecture).
</td>
@ -1056,12 +1055,13 @@ The Angular code is shown using TypeScript.
### Angular modules
<code-example hideCopy>
angular.module("movieHunter", ["ngRoute"]);
</code-example>
In AngularJS, an Angular module keeps track of controllers, services, and other code.
In AngularJS, an Angular module keeps track of controllers, services, and other code.
The second argument defines the list of other modules that this module depends upon.
</td>
@ -1069,9 +1069,8 @@ The Angular code is shown using TypeScript.
### NgModules
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" linenums="false"></code-example>
NgModules, defined with the `NgModule` decorator, serve the same purpose:
@ -1090,7 +1089,7 @@ The Angular code is shown using TypeScript.
### Controller registration
<code-example hideCopy>
angular
.module("movieHunter")
@ -1111,9 +1110,8 @@ The Angular code is shown using TypeScript.
### Component decorator
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component" linenums="false"></code-example>
Angular adds a decorator to the component class to provide any required metadata.
@ -1122,7 +1120,7 @@ The Angular code is shown using TypeScript.
This is how you associate a template with logic, which is defined in the component class.
For more information, see the [Components](guide/architecture#components)
For more information, see the [Components](guide/architecture#components)
section of the [Architecture Overview](guide/architecture) page.
</td>
@ -1134,6 +1132,7 @@ The Angular code is shown using TypeScript.
### Controller function
<code-example hideCopy>
function MovieListCtrl(movieService) {
}
@ -1147,16 +1146,15 @@ The Angular code is shown using TypeScript.
### Component class
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="class" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="class" linenums="false"></code-example>
In Angular, you create a component class.
NOTE: If you are using TypeScript with AngularJS, you must use the `export` keyword to export the component class.
For more information, see the [Components](guide/architecture#components)
For more information, see the [Components](guide/architecture#components)
section of the [Architecture Overview](guide/architecture) page.
</td>
@ -1168,6 +1166,7 @@ The Angular code is shown using TypeScript.
### Dependency injection
<code-example hideCopy>
MovieListCtrl.$inject = ['MovieService'];
function MovieListCtrl(movieService) {
@ -1186,16 +1185,15 @@ The Angular code is shown using TypeScript.
### Dependency injection
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="di" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="di" linenums="false"></code-example>
In Angular, you pass in dependencies as arguments to the component class constructor.
This example injects a `MovieService`.
The first parameter's TypeScript type tells Angular what to inject, even after minification.
For more information, see the [Dependency injection](guide/architecture#dependency-injection)
For more information, see the [Dependency injection](guide/architecture#dependency-injection)
section of the [Architecture Overview](guide/architecture).
</td>
@ -1243,6 +1241,7 @@ also encapsulate a style sheet within a specific component.
### Link tag
<code-example hideCopy>
&lt;link href="styles.css" rel="stylesheet" />
</code-example>
@ -1256,9 +1255,8 @@ also encapsulate a style sheet within a specific component.
### Link tag
<code-example hideCopy path="ajs-quick-reference/src/index.html" region="style" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/index.html" region="style" linenums="false"></code-example>
In Angular, you can continue to use the link tag to define the styles for your application in the `index.html` file.
@ -1267,9 +1265,8 @@ also encapsulate a style sheet within a specific component.
### StyleUrls
In Angular, you can use the `styles` or `styleUrls` property of the `@Component` metadata to define
a style sheet for a particular component.
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="style-url" linenums="false">
</code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="style-url" linenums="false"></code-example>
This allows you to set appropriate styles for individual components that wont leak into

View File

@ -233,11 +233,7 @@ for reasons explained [below](guide/testing#q-spec-file-location).
Add the following code to `src/app/1st.spec.ts`.
<code-example path="testing/src/app/1st.spec.ts" title="src/app/1st.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/1st.spec.ts" title="src/app/1st.spec.ts" linenums="false"></code-example>
{@a run-karma}
@ -379,9 +375,7 @@ The `BannerComponent` in `src/app/banner-inline.component.ts` is the simplest co
a good place to start.
It presents the application title at the top of the screen within an `<h1>` tag.
<code-example path="testing/src/app/banner-inline.component.ts" title="src/app/banner-inline.component.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/banner-inline.component.ts" title="src/app/banner-inline.component.ts" linenums="false"></code-example>
@ -395,9 +389,7 @@ for reasons explained in the [FAQ](guide/testing#faq) answer to
Start with ES6 import statements to get access to symbols referenced in the spec.
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="imports" title="src/app/banner-inline.component.spec.ts (imports)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="imports" title="src/app/banner-inline.component.spec.ts (imports)" linenums="false"></code-example>
@ -406,9 +398,7 @@ Start with ES6 import statements to get access to symbols referenced in the spec
Here's the `describe` and the `beforeEach` that precedes the tests:
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="setup" title="src/app/banner-inline.component.spec.ts (beforeEach)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="setup" title="src/app/banner-inline.component.spec.ts (beforeEach)" linenums="false"></code-example>
@ -528,9 +518,7 @@ The tests assert that `el` contains the expected title text.
Jasmine runs the `beforeEach` function before each of these tests
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="tests" title="src/app/banner-inline.component.spec.ts (tests)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="tests" title="src/app/banner-inline.component.spec.ts (tests)" linenums="false"></code-example>
@ -557,9 +545,7 @@ The `TestBed.createComponent` does _not_ trigger change detection.
The fixture does not automatically push the component's `title` property value into the data bound element,
a fact demonstrated in the following test:
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="test-w-o-detect-changes" title="src/app/banner-inline.component.spec.ts (no detectChanges)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner-inline.component.spec.ts" region="test-w-o-detect-changes" title="src/app/banner-inline.component.spec.ts (no detectChanges)" linenums="false"></code-example>
@ -587,25 +573,19 @@ Some testers prefer that the Angular test environment run change detection autom
That's possible by configuring the `TestBed` with the `ComponentFixtureAutoDetect` provider.
First import it from the testing utility library:
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="import-ComponentFixtureAutoDetect" title="src/app/banner.component.detect-changes.spec.ts (import)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="import-ComponentFixtureAutoDetect" title="src/app/banner.component.detect-changes.spec.ts (import)" linenums="false"></code-example>
Then add it to the `providers` array of the testing module configuration:
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="auto-detect" title="src/app/banner.component.detect-changes.spec.ts (AutoDetect)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="auto-detect" title="src/app/banner.component.detect-changes.spec.ts (AutoDetect)" linenums="false"></code-example>
Here are three tests that illustrate how automatic change detection works.
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="auto-detect-tests" title="src/app/banner.component.detect-changes.spec.ts (AutoDetect Tests)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="auto-detect-tests" title="src/app/banner.component.detect-changes.spec.ts (AutoDetect Tests)" linenums="false"></code-example>
@ -642,9 +622,7 @@ There is no harm in calling `detectChanges()` more often than is strictly necess
The application's actual `BannerComponent` behaves the same as the version above but is implemented differently.
It has _external_ template and css files, specified in `templateUrl` and `styleUrls` properties.
<code-example path="testing/src/app/banner.component.ts" title="src/app/banner.component.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/banner.component.ts" title="src/app/banner.component.ts" linenums="false"></code-example>
@ -669,9 +647,7 @@ The logic in the `beforeEach` of the previous spec is split into two `beforeEach
The first `beforeEach` handles asynchronous compilation.
<code-example path="testing/src/app/banner.component.spec.ts" region="async-before-each" title="src/app/banner.component.spec.ts (first beforeEach)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner.component.spec.ts" region="async-before-each" title="src/app/banner.component.spec.ts (first beforeEach)" linenums="false"></code-example>
@ -679,9 +655,7 @@ Notice the `async` function called as the argument to `beforeEach`.
The `async` function is one of the Angular testing utilities and
has to be imported.
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="import-async" title="src/app/banner.component.detect-changes.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/banner.component.detect-changes.spec.ts" region="import-async" title="src/app/banner.component.detect-changes.spec.ts" linenums="false"></code-example>
@ -752,9 +726,7 @@ nor any of the `override...` methods. The `TestBed` throws an error if you try.
A _synchronous_ `beforeEach` containing the remaining setup steps follows the asynchronous `beforeEach`.
<code-example path="testing/src/app/banner.component.spec.ts" region="sync-before-each" title="src/app/banner.component.spec.ts (second beforeEach)" linenums="false">
</code-example>
<code-example path="testing/src/app/banner.component.spec.ts" region="sync-before-each" title="src/app/banner.component.spec.ts (second beforeEach)" linenums="false"></code-example>
@ -813,18 +785,14 @@ Components often have service dependencies.
The `WelcomeComponent` displays a welcome message to the logged in user.
It knows who the user is based on a property of the injected `UserService`:
<code-example path="testing/src/app/welcome.component.ts" title="src/app/welcome.component.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.ts" title="src/app/welcome.component.ts" linenums="false"></code-example>
The `WelcomeComponent` has decision logic that interacts with the service, logic that makes this component worth testing.
Here's the testing module configuration for the spec file, `src/app/welcome.component.spec.ts`:
<code-example path="testing/src/app/welcome.component.spec.ts" region="config-test-module" title="src/app/welcome.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="config-test-module" title="src/app/welcome.component.spec.ts" linenums="false"></code-example>
@ -852,9 +820,7 @@ It is far easier and safer to create and register a test double in place of the
This particular test suite supplies a minimal `UserService` stub that satisfies the needs of the `WelcomeComponent`
and its tests:
<code-example path="testing/src/app/welcome.component.spec.ts" region="user-service-stub" title="src/app/welcome.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="user-service-stub" title="src/app/welcome.component.spec.ts" linenums="false"></code-example>
@ -872,9 +838,7 @@ The safest way to get the injected service, the way that **_always works_**,
is to **get it from the injector of the _component-under-test_**.
The component injector is a property of the fixture's `DebugElement`.
<code-example path="testing/src/app/welcome.component.spec.ts" region="injected-service" title="WelcomeComponent's injector" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="injected-service" title="WelcomeComponent's injector" linenums="false"></code-example>
@ -889,9 +853,7 @@ But it only works when Angular injects the component with the service instance i
Fortunately, in this test suite, the _only_ provider of `UserService` is the root testing module,
so it is safe to call `TestBed.get` as follows:
<code-example path="testing/src/app/welcome.component.spec.ts" region="inject-from-testbed" title="TestBed injector" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="inject-from-testbed" title="TestBed injector" linenums="false"></code-example>
@ -920,9 +882,7 @@ that's provided to the testing module in the body of your test.
The `userService` instance injected into the component is a completely _different_ object,
a clone of the provided `userServiceStub`.
<code-example path="testing/src/app/welcome.component.spec.ts" region="stub-not-injected" title="src/app/welcome.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="stub-not-injected" title="src/app/welcome.component.spec.ts" linenums="false"></code-example>
@ -932,17 +892,13 @@ a clone of the provided `userServiceStub`.
### Final setup and tests
Here's the complete `beforeEach` using `TestBed.get`:
<code-example path="testing/src/app/welcome.component.spec.ts" region="setup" title="src/app/welcome.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="setup" title="src/app/welcome.component.spec.ts" linenums="false"></code-example>
And here are some tests:
<code-example path="testing/src/app/welcome.component.spec.ts" region="tests" title="src/app/welcome.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="tests" title="src/app/welcome.component.spec.ts" linenums="false"></code-example>
@ -982,9 +938,7 @@ The `TwainComponent` handles the display, delegating the server request to the `
Both are in the `src/app/shared` folder because the author intends to display Twain quotes on other pages someday.
Here is the `TwainComponent`.
<code-example path="testing/src/app/shared/twain.component.ts" region="component" title="src/app/shared/twain.component.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/twain.component.ts" region="component" title="src/app/shared/twain.component.ts" linenums="false"></code-example>
@ -994,9 +948,7 @@ It is sufficient to see within `ngOnInit` that `twainService.getQuote` returns a
In general, tests should not make calls to remote servers.
They should emulate such calls. The setup in this `src/app/shared/twain.component.spec.ts` shows one way to do that:
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="setup" title="src/app/shared/twain.component.spec.ts (setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="setup" title="src/app/shared/twain.component.spec.ts (setup)" linenums="false"></code-example>
@ -1009,9 +961,7 @@ This setup is similar to the [`welcome.component.spec` setup](guide/testing#welc
But instead of creating a stubbed service object, it injects the _real_ service (see the testing module `providers`) and
replaces the critical `getQuote` method with a Jasmine spy.
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="spy" title="src/app/shared/twain.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="spy" title="src/app/shared/twain.component.spec.ts" linenums="false"></code-example>
@ -1038,9 +988,7 @@ You can _stub and spy_ at the same time, as shown in [an example below](guide/te
Here are the tests with commentary to follow:
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="tests" title="src/app/shared/twain.component.spec.ts (tests)">
</code-example>
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="tests" title="src/app/shared/twain.component.spec.ts (tests)"></code-example>
@ -1066,9 +1014,7 @@ value becomes available. The test must become _asynchronous_.
Notice the `async` in the third test.
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="async-test" title="src/app/shared/twain.component.spec.ts (async test)" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="async-test" title="src/app/shared/twain.component.spec.ts (async test)" linenums="false"></code-example>
@ -1123,9 +1069,7 @@ The `getQuote` helper method extracts the display element text and the expectati
The fourth test verifies the same component behavior in a different way.
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="fake-async-test" title="src/app/shared/twain.component.spec.ts (fakeAsync test)" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="fake-async-test" title="src/app/shared/twain.component.spec.ts (fakeAsync test)" linenums="false"></code-example>
@ -1185,9 +1129,7 @@ Now you are responsible for chaining promises, handling errors, and calling `don
Here is a `done` version of the previous two tests:
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="done-test" title="src/app/shared/twain.component.spec.ts (done test)" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/twain.component.spec.ts" region="done-test" title="src/app/shared/twain.component.spec.ts (done test)" linenums="false"></code-example>
@ -1222,9 +1164,7 @@ Clicking that hero tells the `DashboardComponent` that the user has selected the
The `DashboardHeroComponent` is embedded in the `DashboardComponent` template like this:
<code-example path="testing/src/app/dashboard/dashboard.component.html" region="dashboard-hero" title="src/app/dashboard/dashboard.component.html (excerpt)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.html" region="dashboard-hero" title="src/app/dashboard/dashboard.component.html (excerpt)" linenums="false"></code-example>
@ -1233,9 +1173,7 @@ to the looping value and listens for the component's `selected` event.
Here's the component's definition:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.ts" region="component" title="src/app/dashboard/dashboard-hero.component.ts (component)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.ts" region="component" title="src/app/dashboard/dashboard-hero.component.ts (component)" linenums="false"></code-example>
@ -1248,9 +1186,7 @@ You can use one of these approaches:
A quick look at the `DashboardComponent` constructor discourages the first approach:
<code-example path="testing/src/app/dashboard/dashboard.component.ts" region="ctor" title="src/app/dashboard/dashboard.component.ts (constructor)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.ts" region="ctor" title="src/app/dashboard/dashboard.component.ts (constructor)" linenums="false"></code-example>
@ -1280,9 +1216,7 @@ so, try the second and third options.
Here's the spec file setup.
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="setup" title="src/app/dashboard/dashboard-hero.component.spec.ts (setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="setup" title="src/app/dashboard/dashboard-hero.component.spec.ts (setup)" linenums="false"></code-example>
@ -1295,9 +1229,7 @@ the way the `DashboardComponent` would set it via the property binding in its re
The first test follows:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="name-test" title="src/app/dashboard/dashboard-hero.component.spec.ts (name test)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="name-test" title="src/app/dashboard/dashboard-hero.component.spec.ts (name test)" linenums="false"></code-example>
@ -1305,9 +1237,7 @@ It verifies that the hero name is propagated to template with a binding.
Because the template passes the hero name through the Angular `UpperCasePipe`,
the test must match the element value with the uppercased name:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.html" title="src/app/dashboard/dashboard-hero.component.html" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.html" title="src/app/dashboard/dashboard-hero.component.html" linenums="false"></code-example>
@ -1330,9 +1260,7 @@ low cost and without resorting to much slower and more complicated end-to-end te
The second test verifies click behavior. Clicking the hero should raise a `selected` event that the
host component (`DashboardComponent` presumably) can hear:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="click-test" title="src/app/dashboard/dashboard-hero.component.spec.ts (click test)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="click-test" title="src/app/dashboard/dashboard-hero.component.spec.ts (click test)" linenums="false"></code-example>
@ -1357,9 +1285,7 @@ The second parameter is the event object passed to the handler.
In this example, the test triggers a "click" event with a null event object.
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="trigger-event-handler" title="src/app/dashboard/dashboard-hero.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="trigger-event-handler" title="src/app/dashboard/dashboard-hero.component.spec.ts" linenums="false"></code-example>
@ -1380,9 +1306,7 @@ Clicking a button, an anchor, or an arbitrary HTML element is a common test task
Make that easy by encapsulating the _click-triggering_ process in a helper such as the `click` function below:
<code-example path="testing/src/testing/index.ts" region="click-event" title="testing/index.ts (click helper)" linenums="false">
</code-example>
<code-example path="testing/src/testing/index.ts" region="click-event" title="testing/index.ts (click helper)" linenums="false"></code-example>
@ -1413,9 +1337,7 @@ If you like it, add it to your own collection of helpers.
Here's the previous test, rewritten using this click helper.
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="click-test-2" title="src/app/dashboard/dashboard-hero.component.spec.ts (click test revised)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="click-test-2" title="src/app/dashboard/dashboard-hero.component.spec.ts (click test revised)" linenums="false"></code-example>
@ -1434,9 +1356,7 @@ But does the `DashboardHeroComponent` work correctly when properly data-bound to
Testing with the actual `DashboardComponent` host is doable but seems more trouble than its worth.
It's easier to emulate the `DashboardComponent` host with a _test host_ like this one:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="test-host" title="src/app/dashboard/dashboard-hero.component.spec.ts (test host)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="test-host" title="src/app/dashboard/dashboard-hero.component.spec.ts (test host)" linenums="false"></code-example>
@ -1451,9 +1371,7 @@ in its `selectedHero` property. Later, the tests check that property to verify t
The setup for the test-host tests is similar to the setup for the stand-alone tests:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="test-host-setup" title="src/app/dashboard/dashboard-hero.component.spec.ts (test host setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="test-host-setup" title="src/app/dashboard/dashboard-hero.component.spec.ts (test host setup)" linenums="false"></code-example>
@ -1471,9 +1389,7 @@ albeit at greater depth in the element tree than before.
The tests themselves are almost identical to the stand-alone version:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="test-host-tests" title="src/app/dashboard/dashboard-hero.component.spec.ts (test-host)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="test-host-tests" title="src/app/dashboard/dashboard-hero.component.spec.ts (test-host)" linenums="false"></code-example>
@ -1492,9 +1408,7 @@ really does find its way up through the event binding to the host component.
Testing the actual `DashboardComponent` seemed daunting because it injects the `Router`.
<code-example path="testing/src/app/dashboard/dashboard.component.ts" region="ctor" title="src/app/dashboard/dashboard.component.ts (constructor)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.ts" region="ctor" title="src/app/dashboard/dashboard.component.ts (constructor)" linenums="false"></code-example>
@ -1503,9 +1417,7 @@ The `Router` has a complicated API and is entwined with other services and appli
Fortunately, the `DashboardComponent` isn't doing much with the `Router`
<code-example path="testing/src/app/dashboard/dashboard.component.ts" region="goto-detail" title="src/app/dashboard/dashboard.component.ts (goToDetail)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.ts" region="goto-detail" title="src/app/dashboard/dashboard.component.ts (goToDetail)" linenums="false"></code-example>
@ -1514,26 +1426,20 @@ As a rule you test the component, not the router,
and care only if the component navigates with the right address under the given conditions.
Stubbing the router with a test implementation is an easy option. This should do the trick:
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="router-stub" title="src/app/dashboard/dashboard.component.spec.ts (Router Stub)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="router-stub" title="src/app/dashboard/dashboard.component.spec.ts (Router Stub)" linenums="false"></code-example>
Now set up the testing module with the test stubs for the `Router` and `HeroService`, and
create a test instance of the `DashboardComponent` for subsequent testing.
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="compile-and-create-body" title="src/app/dashboard/dashboard.component.spec.ts (compile and create)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="compile-and-create-body" title="src/app/dashboard/dashboard.component.spec.ts (compile and create)" linenums="false"></code-example>
The following test clicks the displayed hero and confirms (with the help of a spy) that `Router.navigateByUrl` is called with the expected url.
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="navigate-test" title="src/app/dashboard/dashboard.component.spec.ts (navigate test)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="navigate-test" title="src/app/dashboard/dashboard.component.spec.ts (navigate test)" linenums="false"></code-example>
@ -1544,9 +1450,7 @@ The following test clicks the displayed hero and confirms (with the help of a sp
Notice the `inject` function in the second `it` argument.
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="inject" title="src/app/dashboard/dashboard.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard.component.spec.ts" region="inject" title="src/app/dashboard/dashboard.component.spec.ts" linenums="false"></code-example>
@ -1582,9 +1486,7 @@ That's fine for this test because the `Router` is, and must be, provided by the
If you need a service provided by the component's _own_ injector, call `fixture.debugElement.injector.get` instead:
<code-example path="testing/src/app/welcome.component.spec.ts" region="injected-service" title="Component's injector" linenums="false">
</code-example>
<code-example path="testing/src/app/welcome.component.spec.ts" region="injected-service" title="Component's injector" linenums="false"></code-example>
@ -1629,17 +1531,13 @@ Angular injects the `ActivatedRoute` into the `HeroDetailComponent`,
and the component extracts the `id` so it can fetch the corresponding hero via the `HeroDetailService`.
Here's the `HeroDetailComponent` constructor:
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="ctor" title="src/app/hero/hero-detail.component.ts (constructor)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="ctor" title="src/app/hero/hero-detail.component.ts (constructor)" linenums="false"></code-example>
`HeroDetailComponent` subscribes to `ActivatedRoute.params` changes in its `ngOnInit` method.
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="ng-on-init" title="src/app/hero/hero-detail.component.ts (ngOnInit)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="ng-on-init" title="src/app/hero/hero-detail.component.ts (ngOnInit)" linenums="false"></code-example>
@ -1680,9 +1578,7 @@ Consider placing such helpers in a `testing` folder sibling to the `app` folder.
This sample keeps `ActivatedRouteStub` in `testing/router-stubs.ts`:
<code-example path="testing/src/testing/router-stubs.ts" region="activated-route-stub" title="testing/router-stubs.ts (ActivatedRouteStub)" linenums="false">
</code-example>
<code-example path="testing/src/testing/router-stubs.ts" region="activated-route-stub" title="testing/router-stubs.ts (ActivatedRouteStub)" linenums="false"></code-example>
@ -1727,9 +1623,7 @@ The router stubs in this guide are meant to inspire you. Create your own stubs t
### Testing with the _Observable_ test double
Here's a test demonstrating the component's behavior when the observed `id` refers to an existing hero:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="route-good-id" title="src/app/hero/hero-detail.component.spec.ts (existing id)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="route-good-id" title="src/app/hero/hero-detail.component.spec.ts (existing id)" linenums="false"></code-example>
@ -1748,9 +1642,7 @@ When the `id` cannot be found, the component should re-route to the `HeroListCom
The test suite setup provided the same `RouterStub` [described above](guide/testing#routed-component) which spies on the router without actually navigating.
This test supplies a "bad" id and expects the component to try to navigate.
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="route-bad-id" title="src/app/hero/hero-detail.component.spec.ts (bad id)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="route-bad-id" title="src/app/hero/hero-detail.component.spec.ts (bad id)" linenums="false"></code-example>
@ -1762,9 +1654,7 @@ The component should do something reasonable when there is no `id`.
In this implementation, the component should create and display a new hero.
New heroes have `id=0` and a blank `name`. This test confirms that the component behaves as expected:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="route-no-id" title="src/app/hero/hero-detail.component.spec.ts (no id)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="route-no-id" title="src/app/hero/hero-detail.component.spec.ts (no id)" linenums="false"></code-example>
@ -1799,9 +1689,7 @@ The `HeroDetailComponent` is a simple view with a title, two hero fields, and tw
But there's already plenty of template complexity.
<code-example path="testing/src/app/hero/hero-detail.component.html" title="src/app/hero/hero-detail.component.html" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.html" title="src/app/hero/hero-detail.component.html" linenums="false"></code-example>
@ -1817,9 +1705,7 @@ Even a small form such as this one can produce a mess of tortured conditional se
Tame the madness with a `Page` class that simplifies access to component properties and encapsulates the logic that sets them.
Here's the `Page` class for the `hero-detail.component.spec.ts`
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="page" title="src/app/hero/hero-detail.component.spec.ts (Page)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="page" title="src/app/hero/hero-detail.component.spec.ts (Page)" linenums="false"></code-example>
@ -1828,9 +1714,7 @@ Now the important hooks for component manipulation and inspection are neatly org
A `createComponent` method creates a `page` object and fills in the blanks once the `hero` arrives.
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="create-component" title="src/app/hero/hero-detail.component.spec.ts (createComponent)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="create-component" title="src/app/hero/hero-detail.component.spec.ts (createComponent)" linenums="false"></code-example>
@ -1840,9 +1724,7 @@ There are no distractions: no waiting for promises to resolve and no searching t
Here are a few more `HeroDetailComponent` tests to drive the point home.
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="selected-tests" title="src/app/hero/hero-detail.component.spec.ts (selected tests)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="selected-tests" title="src/app/hero/hero-detail.component.spec.ts (selected tests)" linenums="false"></code-example>
@ -1856,9 +1738,7 @@ Here are a few more `HeroDetailComponent` tests to drive the point home.
## Setup with module imports
Earlier component tests configured the testing module with a few `declarations` like this:
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="compile-components" title="src/app/dashboard/dashboard-hero.component.spec.ts (config)" linenums="false">
</code-example>
<code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="compile-components" title="src/app/dashboard/dashboard-hero.component.spec.ts (config)" linenums="false"></code-example>
@ -1881,9 +1761,7 @@ In addition to the support it receives from the default testing module `CommonMo
One approach is to configure the testing module from the individual pieces as in this example:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-forms-module" title="src/app/hero/hero-detail.component.spec.ts (FormsModule setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-forms-module" title="src/app/hero/hero-detail.component.spec.ts (FormsModule setup)" linenums="false"></code-example>
@ -1892,9 +1770,7 @@ a `SharedModule` to combine these and other frequently requested parts.
The test configuration can use the `SharedModule` too as seen in this alternative setup:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-shared-module" title="src/app/hero/hero-detail.component.spec.ts (SharedModule setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-shared-module" title="src/app/hero/hero-detail.component.spec.ts (SharedModule setup)" linenums="false"></code-example>
@ -1910,9 +1786,7 @@ The `HeroDetailComponent` is part of the `HeroModule` [Feature Module](guide/ngm
including the `SharedModule`.
Try a test configuration that imports the `HeroModule` like this one:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-hero-module" title="src/app/hero/hero-detail.component.spec.ts (HeroModule setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-hero-module" title="src/app/hero/hero-detail.component.spec.ts (HeroModule setup)" linenums="false"></code-example>
@ -1952,9 +1826,7 @@ especially when the feature module is small and mostly self-contained, as featur
The `HeroDetailComponent` provides its own `HeroDetailService`.
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="prototype" title="src/app/hero/hero-detail.component.ts (prototype)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="prototype" title="src/app/hero/hero-detail.component.ts (prototype)" linenums="false"></code-example>
@ -1979,9 +1851,7 @@ There might not be a remote server to call.
Fortunately, the `HeroDetailService` delegates responsibility for remote data access to an injected `HeroService`.
<code-example path="testing/src/app/hero/hero-detail.service.ts" region="prototype" title="src/app/hero/hero-detail.service.ts (prototype)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.service.ts" region="prototype" title="src/app/hero/hero-detail.service.ts (prototype)" linenums="false"></code-example>
@ -2000,9 +1870,7 @@ The `TestBed.overrideComponent` method can replace the component's `providers` w
as seen in the following setup variation:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-override" title="src/app/hero/hero-detail.component.spec.ts (Override setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-override" title="src/app/hero/hero-detail.component.spec.ts (Override setup)" linenums="false"></code-example>
@ -2016,9 +1884,7 @@ Notice that `TestBed.configureTestingModule` no longer provides a (fake) `HeroSe
Focus on the `overrideComponent` method.
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="override-component-method" title="src/app/hero/hero-detail.component.spec.ts (overrideComponent)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="override-component-method" title="src/app/hero/hero-detail.component.spec.ts (overrideComponent)" linenums="false"></code-example>
@ -2069,9 +1935,7 @@ were called by spying on the service methods.
Accordingly, the stub implements its methods as spies:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="hds-spy" title="src/app/hero/hero-detail.component.spec.ts (HeroDetailServiceSpy)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="hds-spy" title="src/app/hero/hero-detail.component.spec.ts (HeroDetailServiceSpy)" linenums="false"></code-example>
@ -2083,9 +1947,7 @@ Accordingly, the stub implements its methods as spies:
Now the tests can control the component's hero directly by manipulating the spy-stub's `testHero`
and confirm that service methods were called.
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="override-tests" title="src/app/hero/hero-detail.component.spec.ts (override tests)" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="override-tests" title="src/app/hero/hero-detail.component.spec.ts (override tests)" linenums="false"></code-example>
@ -2114,17 +1976,13 @@ It also displays a navigation bar with anchors and their `RouterLink` directives
{@a app-component-html}
<code-example path="testing/src/app/app.component.html" title="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="testing/src/app/app.component.html" title="src/app/app.component.html" linenums="false"></code-example>
The component class does nothing.
<code-example path="testing/src/app/app.component.ts" title="src/app/app.component.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/app.component.ts" title="src/app/app.component.ts" linenums="false"></code-example>
@ -2140,9 +1998,7 @@ See why this is worth doing [below](guide/testing#why-stubbed-routerlink-tests).
The test setup should look familiar.
<code-example path="testing/src/app/app.component.spec.ts" region="setup-stubs" title="src/app/app.component.spec.ts (Stub Setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/app.component.spec.ts" region="setup-stubs" title="src/app/app.component.spec.ts (Stub Setup)" linenums="false"></code-example>
@ -2169,9 +2025,7 @@ and throws an error.
The `RouterLinkStubDirective` contributes substantively to the test:
<code-example path="testing/src/testing/router-stubs.ts" region="router-link" title="testing/router-stubs.ts (RouterLinkStubDirective)" linenums="false">
</code-example>
<code-example path="testing/src/testing/router-stubs.ts" region="router-link" title="testing/router-stubs.ts (RouterLinkStubDirective)" linenums="false"></code-example>
@ -2191,9 +2045,7 @@ Tests can inspect that property to confirm the expected _click-to-navigation_ be
A little more setup triggers the initial data binding and gets references to the navigation links:
<code-example path="testing/src/app/app.component.spec.ts" region="test-setup" title="src/app/app.component.spec.ts (test setup)" linenums="false">
</code-example>
<code-example path="testing/src/app/app.component.spec.ts" region="test-setup" title="src/app/app.component.spec.ts (test setup)" linenums="false"></code-example>
@ -2210,9 +2062,7 @@ Angular always adds attached directives to the component's injector.
Here are some tests that leverage this setup:
<code-example path="testing/src/app/app.component.spec.ts" region="tests" title="src/app/app.component.spec.ts (selected tests)" linenums="false">
</code-example>
<code-example path="testing/src/app/app.component.spec.ts" region="tests" title="src/app/app.component.spec.ts (selected tests)" linenums="false"></code-example>
@ -2336,26 +2186,20 @@ based on either a data bound color or a default color (lightgray).
It also sets a custom property of the element (`customProperty`) to `true`
for no reason other than to show that it can.
<code-example path="testing/src/app/shared/highlight.directive.ts" title="src/app/shared/highlight.directive.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/highlight.directive.ts" title="src/app/shared/highlight.directive.ts" linenums="false"></code-example>
It's used throughout the application, perhaps most simply in the `AboutComponent`:
<code-example path="testing/src/app/about.component.ts" title="src/app/about.component.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/about.component.ts" title="src/app/about.component.ts" linenums="false"></code-example>
Testing the specific use of the `HighlightDirective` within the `AboutComponent` requires only the
techniques explored above (in particular the ["Shallow test"](guide/testing#shallow-component-test) approach).
<code-example path="testing/src/app/about.component.spec.ts" region="tests" title="src/app/about.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/about.component.spec.ts" region="tests" title="src/app/about.component.spec.ts" linenums="false"></code-example>
@ -2370,9 +2214,7 @@ do not inspire confidence in the directive's efficacy.
A better solution is to create an artificial test component that demonstrates all ways to apply the directive.
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" title="src/app/shared/highlight.directive.spec.ts (TestComponent)" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" title="src/app/shared/highlight.directive.spec.ts (TestComponent)" linenums="false"></code-example>
@ -2395,9 +2237,7 @@ The initial value is the word "cyan" which should be the background color of the
Here are some tests of this component:
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="selected-tests" title="src/app/shared/highlight.directive.spec.ts (selected tests)">
</code-example>
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="selected-tests" title="src/app/shared/highlight.directive.spec.ts (selected tests)"></code-example>
@ -2477,9 +2317,7 @@ Here are some synchronous and asynchronous unit tests of the `FancyService`
written without assistance from Angular testing utilities.
<code-example path="testing/src/app/bag/bag.no-testbed.spec.ts" region="FancyService" title="src/app/bag/bag.no-testbed.spec.ts">
</code-example>
<code-example path="testing/src/app/bag/bag.no-testbed.spec.ts" region="FancyService" title="src/app/bag/bag.no-testbed.spec.ts"></code-example>
@ -2523,9 +2361,7 @@ In many cases, it's easier to create and _inject_ dependencies by hand.
The `DependentService` is a simple example:
<code-example path="testing/src/app/bag/bag.ts" region="DependentService" title="src/app/bag/bag.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/bag/bag.ts" region="DependentService" title="src/app/bag/bag.ts" linenums="false"></code-example>
@ -2533,9 +2369,7 @@ It delegates its only method, `getValue`, to the injected `FancyService`.
Here are several ways to test it.
<code-example path="testing/src/app/bag/bag.no-testbed.spec.ts" region="DependentService" title="src/app/bag/bag.no-testbed.spec.ts">
</code-example>
<code-example path="testing/src/app/bag/bag.no-testbed.spec.ts" region="DependentService" title="src/app/bag/bag.no-testbed.spec.ts"></code-example>
@ -2566,9 +2400,7 @@ metadata and an interface.
Consider a `TitleCasePipe` that capitalizes the first letter of each word.
Here's a naive implementation with a regular expression.
<code-example path="testing/src/app/shared/title-case.pipe.ts" title="src/app/shared/title-case.pipe.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/shared/title-case.pipe.ts" title="src/app/shared/title-case.pipe.ts" linenums="false"></code-example>
@ -2576,9 +2408,7 @@ Anything that uses a regular expression is worth testing thoroughly.
Use simple Jasmine to explore the expected cases and the edge cases.
<code-example path="testing/src/app/shared/title-case.pipe.spec.ts" region="excerpt" title="src/app/shared/title-case.pipe.spec.ts">
</code-example>
<code-example path="testing/src/app/shared/title-case.pipe.spec.ts" region="excerpt" title="src/app/shared/title-case.pipe.spec.ts"></code-example>
@ -2591,9 +2421,7 @@ They can't tell if the `TitleCasePipe` is working properly as applied in the app
Consider adding component tests such as this one:
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="title-case-pipe" title="src/app/hero/hero-detail.component.spec.ts (pipe test)">
</code-example>
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="title-case-pipe" title="src/app/hero/hero-detail.component.spec.ts (pipe test)"></code-example>
@ -2607,18 +2435,14 @@ The Angular testing utilities are specifically designed to facilitate such tests
Consider this `ButtonComp` component.
<code-example path="testing/src/app/bag/bag.ts" region="ButtonComp" title="src/app/bag/bag.ts (ButtonComp)" linenums="false">
</code-example>
<code-example path="testing/src/app/bag/bag.ts" region="ButtonComp" title="src/app/bag/bag.ts (ButtonComp)" linenums="false"></code-example>
The following Angular test demonstrates that clicking a button in the template leads
to an update of the on-screen message.
<code-example path="testing/src/app/bag/bag.spec.ts" region="ButtonComp" title="src/app/bag/bag.spec.ts (ButtonComp)" linenums="false">
</code-example>
<code-example path="testing/src/app/bag/bag.spec.ts" region="ButtonComp" title="src/app/bag/bag.spec.ts (ButtonComp)" linenums="false"></code-example>
@ -2632,9 +2456,7 @@ exploring many more conditions with less effort.
Here are a set of unit tests that verify the component's outputs in the face of a variety of
component inputs.
<code-example path="testing/src/app/bag/bag.no-testbed.spec.ts" region="ButtonComp" title="src/app/bag/bag.no-testbed.spec.ts (ButtonComp)" linenums="false">
</code-example>
<code-example path="testing/src/app/bag/bag.no-testbed.spec.ts" region="ButtonComp" title="src/app/bag/bag.no-testbed.spec.ts (ButtonComp)" linenums="false"></code-example>
@ -3044,9 +2866,8 @@ Here are the most important static methods, in order of likely utility.
The `TestBed.get` method takes an optional second parameter,
the object to return if Angular can't find the provider
(`null` in this example):
<code-example path="testing/src/app/bag/bag.spec.ts" region="testbed-get" title="src/app/bag/bag.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/bag/bag.spec.ts" region="testbed-get" title="src/app/bag/bag.spec.ts" linenums="false"></code-example>
After calling `get`, the `TestBed` configuration is frozen for the duration of the current spec.
@ -3614,9 +3435,7 @@ predicate that filters the source element's subtree for matching `DebugElement`.
The predicate is any method that takes a `DebugElement` and returns a _truthy_ value.
The following example finds all `DebugElements` with a reference to a template local variable named "content":
<code-example path="testing/src/app/bag/bag.spec.ts" region="custom-predicate" title="src/app/bag/bag.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/bag/bag.spec.ts" region="custom-predicate" title="src/app/bag/bag.spec.ts" linenums="false"></code-example>
@ -3627,9 +3446,7 @@ The Angular `By` class has three static methods for common predicates:
* `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
<code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" title="src/app/hero/hero-list.component.spec.ts" linenums="false">
</code-example>
<code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" title="src/app/hero/hero-list.component.spec.ts" linenums="false"></code-example>
<div class='l' class='hr'>