├── Chapter 01
├── .DS_Store
├── Builder Pattern
│ ├── builder.js
│ └── index.html
├── README.md
└── calculator
│ ├── calculator.js
│ └── testRunner.html
├── Chapter 02
├── .DS_Store
├── MIT.LICENSE
├── README.md
├── SpecRunner.html
├── lib
│ └── jasmine-2.4.1
│ │ ├── boot.js
│ │ ├── console.js
│ │ ├── jasmine-html.js
│ │ ├── jasmine.css
│ │ ├── jasmine.js
│ │ └── jasmine_favicon.png
├── spec
│ └── mySpec.js
└── src
│ └── mySource.js
├── Chapter 03
├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ └── main.ts
├── e2e
│ └── app.e2e-spec.ts
├── favicon.ico
├── index.html
├── karma-test-shim.js
├── karma.conf.js
├── package.json
├── protractor.config.js
├── styles.css
├── systemjs.config.extras.js
├── systemjs.config.js
├── tsconfig.json
└── tslint.json
├── Chapter 04
├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ └── main.ts
├── e2e
│ └── app.e2e-spec.ts
├── favicon.ico
├── index.html
├── karma-test-shim.js
├── karma.conf.js
├── package.json
├── protractor.config.js
├── styles.css
├── systemjs.config.extras.js
├── systemjs.config.js
├── tsconfig.json
└── tslint.json
├── Chapter 05
├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ └── main.ts
├── debug
│ ├── app.debug.e2e.ts
│ └── debugConf.js
├── e2e
│ └── app.e2e-spec.ts
├── favicon.ico
├── index.html
├── karma-test-shim.js
├── karma.conf.js
├── package.json
├── protractor.config.js
├── styles.css
├── systemjs.config.extras.js
├── systemjs.config.js
├── tsconfig.json
└── tslint.json
├── Chapter 06
├── .dockerignore
├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── Dockerfile
├── LICENSE
├── README.md
├── app
│ ├── app.component.ts
│ ├── app.module.ts
│ └── main.ts
├── favicon.ico
├── index.html
├── karma-test-shim.js
├── karma.conf.js
├── package.json
├── protractor.config.js
├── spec
│ ├── e2e
│ │ └── app.e2e-spec.ts
│ └── unit
│ │ └── app.component.spec.ts
├── styles.css
├── systemjs.config.extras.js
├── systemjs.config.js
├── tsconfig.json
├── tslint.json
└── wallaby.js
├── Chapter 07
├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routes.ts
│ ├── data
│ │ └── people.json
│ ├── main.ts
│ ├── members
│ │ ├── members.component.css
│ │ ├── members.component.html
│ │ ├── members.component.ts
│ │ └── person
│ │ │ ├── person.component.html
│ │ │ └── person.component.ts
│ ├── nav
│ │ ├── navbar.component.css
│ │ ├── navbar.component.html
│ │ └── navbar.component.ts
│ └── view
│ │ ├── view1.component.ts
│ │ └── view2.component.ts
├── favicon.ico
├── index.html
├── karma-test-shim.js
├── karma.conf.js
├── package.json
├── protractor-results.txt
├── protractor.config.js
├── spec
│ └── e2e
│ │ ├── app.e2e-spec.ts
│ │ ├── members.component.e2e-spec.ts
│ │ ├── person.component.e2e-spec.ts
│ │ └── view.e2e-spec.ts
├── styles.css
├── systemjs.config.extras.js
├── systemjs.config.js
├── tsconfig.json
├── tslint.json
└── typing.json
├── Chapter 08
├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routes.ts
│ ├── data
│ │ └── people.json
│ ├── main.ts
│ ├── members
│ │ ├── members.component.css
│ │ ├── members.component.html
│ │ ├── members.component.ts
│ │ └── person
│ │ │ ├── person.component.html
│ │ │ └── person.component.ts
│ ├── nav
│ │ ├── navbar.component.css
│ │ ├── navbar.component.html
│ │ └── navbar.component.ts
│ ├── search
│ │ ├── search.component.html
│ │ └── search.component.ts
│ ├── services
│ │ └── members.service.ts
│ └── view
│ │ ├── view1.component.ts
│ │ └── view2.component.ts
├── favicon.ico
├── index.html
├── karma-test-shim.js
├── karma.conf.js
├── package.json
├── protractor-results.txt
├── protractor.config.js
├── spec
│ ├── e2e
│ │ ├── app.e2e-spec.ts
│ │ ├── members.component.e2e-spec.ts
│ │ ├── person.component.e2e-spec.ts
│ │ └── view.e2e-spec.ts
│ └── unit
│ │ ├── app.component.spec.ts
│ │ ├── members.service.spec.ts
│ │ └── stub
│ │ ├── members.service.stub.ts
│ │ └── router-stubs.ts
├── styles.css
├── systemjs.config.extras.js
├── systemjs.config.js
├── tsconfig.json
├── tslint.json
└── typing.json
├── LICENSE
└── README.md
/Chapter 01/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 01/.DS_Store
--------------------------------------------------------------------------------
/Chapter 01/Builder Pattern/builder.js:
--------------------------------------------------------------------------------
1 |
2 | var bookBuilder = function() {
3 | var _resultBook = {
4 | id: 1,
5 | author: 'Any Author',
6 | dateTime: new Date()
7 | };
8 |
9 | this.build = function() {
10 | return _resultBook;
11 | };
12 |
13 | this.setAuthor = function(author) {
14 | _resultBook.author = author;
15 | return this;
16 | };
17 |
18 | this.setDateTime = function(dateTime) {
19 | _resultBook.dateTime = dateTime;
20 | return this;
21 | };
22 | };
23 |
24 | var validate = function(builtBookToValidate){
25 | if(!builtBookToValidate.author) {
26 | return false;
27 | }
28 | if(!builtBookToValidate.dateTime) {
29 | return false;
30 | }
31 | return true;
32 | };
33 |
34 | var builtBook = new bookBuilder().setAuthor('Ziaul Haq')
35 | .setDateTime(new Date())
36 | .build();
37 |
38 | console.log(builtBook.author); // Ziaul Haq
39 |
40 |
41 | var validBuilder = new bookBuilder().setAuthor('Ziaul Haq')
42 | .setDateTime(new Date())
43 | .build();
44 |
45 | // Validate the object with validate() method
46 | if (validate(validBuilder)) {
47 | console.log('Valid Book created');
48 | }
49 |
50 | var invalidBuilder = new bookBuilder().setAuthor(null).build();
51 |
52 | if (!validate(invalidBuilder)) {
53 | console.log('Invalid Book created as author is null');
54 | }
55 |
56 | var invalidBuilder = new bookBuilder().setDateTime(null).build();
57 |
58 | if (!validate(invalidBuilder)) {
59 | console.log('Invalid Book created as dateTime is null');
60 | }
61 |
--------------------------------------------------------------------------------
/Chapter 01/Builder Pattern/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Test Runner
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter 01/README.md:
--------------------------------------------------------------------------------
1 | # Angular TDD Chapter1 Source
2 |
3 | This repository is for 2 simple test projects.
4 |
5 | 1. Simple calculator testing
6 | 2. Builder pattern
7 |
--------------------------------------------------------------------------------
/Chapter 01/calculator/calculator.js:
--------------------------------------------------------------------------------
1 |
2 | var calculator = {
3 | multiply : function(amount1, amount2) {
4 | return amount1 * amount2;
5 | }
6 | };
7 |
8 | function multipleTest1() {
9 | // Test
10 | var result = calculator.multiply(3, 3);
11 |
12 | // Assert Result is expected
13 | if (result === 9) {
14 | console.log('Test Passed');
15 | } else {
16 | console.log('Test Failed');
17 | }
18 | };
19 |
20 | multipleTest1();
21 |
--------------------------------------------------------------------------------
/Chapter 01/calculator/testRunner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Test Runner
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter 02/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 02/.DS_Store
--------------------------------------------------------------------------------
/Chapter 02/MIT.LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008-2011 Pivotal Labs
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Chapter 02/README.md:
--------------------------------------------------------------------------------
1 | # Angular TDD Chapter2 Source
2 |
3 | This repository is for Jasmine v2.4.1 sample test suite with some very basic test case.
4 |
--------------------------------------------------------------------------------
/Chapter 02/SpecRunner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Jasmine Spec Runner v2.4.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Chapter 02/lib/jasmine-2.4.1/jasmine_favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 02/lib/jasmine-2.4.1/jasmine_favicon.png
--------------------------------------------------------------------------------
/Chapter 02/spec/mySpec.js:
--------------------------------------------------------------------------------
1 |
2 | describe("A sample test suite to test jasmine assertion", function() {
3 | var fetchA;
4 | beforeEach(function() {
5 | spyOn(myObj, "getA").and.returnValue(789);
6 | myObj.setA(123);
7 | fetchA = myObj.getA();
8 | });
9 |
10 | it("tracks that the spy was called", function() {
11 | expect(myObj.getA).toHaveBeenCalled();
12 | });
13 |
14 | it("should not affect other functions", function() {
15 | expect(a).toEqual(123);
16 | });
17 |
18 | it("when called returns the requested value", function() {
19 | expect(fetchA).toEqual(789);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/Chapter 02/src/mySource.js:
--------------------------------------------------------------------------------
1 |
2 | var a,
3 | myObj = {
4 | setA: function(value) {
5 | a = value;
6 | },
7 | getA: function(value) {
8 | return a;
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/Chapter 03/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
16 | # Indentation override
17 | #[lib/**.js]
18 | #[{package.json,.travis.yml}]
19 | #[**/**.js]
20 |
--------------------------------------------------------------------------------
/Chapter 03/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | jspm_packages
4 | npm-debug.*
5 | link-checker-results.txt
6 | app/**/*.js
7 | *.js.map
8 | e2e/**/*.js
9 | e2e/**/*.js.map
10 | _test-output
11 | _temp
12 |
--------------------------------------------------------------------------------
/Chapter 03/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | sudo: required
3 | language: node_js
4 | node_js:
5 | - "5"
6 | os:
7 | - linux
8 | env:
9 | global:
10 | - DBUS_SESSION_BUS_ADDRESS=/dev/null
11 | - DISPLAY=:99.0
12 | - CHROME_BIN=chromium-browser
13 | before_script:
14 | - sh -e /etc/init.d/xvfb start
15 | install:
16 | - npm install
17 | script:
18 | - npm run lint
19 | - npm run test-once
20 | - npm run e2e
21 |
--------------------------------------------------------------------------------
/Chapter 03/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Angular Documentation QuickStart Changelog
2 | Upgraders: for a fresh start, consider running these commands
3 | * `git clean -xdf`
4 | * `npm install`
5 |
6 |
7 | # 0.2.17 (2016-11-16)
8 | * Conform to updated QuickStart advice
9 | * removed docker everywhere (was nice but not necessary)
10 | * removed wallaby
11 | * shrink styles.css
12 | * refine tsconfig.json
13 | * `AppComponent` uses interpolation
14 |
15 |
16 | # 0.2.16 (2016-11-14)
17 | * Update to Angular 2.2.0
18 |
19 |
20 | # 0.2.15 (2016-10-29)
21 | * Revert to Jasmine 2.4.1 because bug in 2.5.x (see [jasmine issue #1231](https://github.com/jasmine/jasmine/issues/1231))
22 |
23 |
24 | # 0.2.14 (2016-10-29)
25 | * Remove bootstrap.css install
26 | * Angular v2.1.2
27 |
28 |
29 | # 0.2.13 (2016-10-20)
30 | * Protractor 4
31 | * Move from `typings` to `@types`. See `tsconfig.json` changes.
32 | * Angular v2.1.1
33 |
34 |
35 | # 0.2.12 (2016-10-06)
36 | * Angular v2.1.0
37 |
38 |
39 | # 0.2.11 (2016-10-06)
40 | * Angular v2.0.2
41 | * License is MIT
42 | * Current testing configuration
43 | * No code changes
44 |
45 |
46 | # 0.2.10 (2016-09-19)
47 | * All "Angular 2" references become just "Angular"
48 | * No code changes
49 |
50 |
51 | # 0.2.9 (2016-09-14)
52 | * Angular 2.0.0 version
53 | * Update to Typescript 2.0.2
54 | * Fix e2e test missing dir
55 |
56 |
57 | # 0.2.8 (2016-09-01)
58 | * remove @angular test libraries from system.js (now in shim)
59 | * update test related files
60 | * wallaby doesn't completely work. Researching.
61 |
62 |
63 | # 0.2.7 (2016-08-31)
64 | * Angular 2 RC6 version
65 | * Updated new forms, router, angular2-in-memory-web-api, karma, core-js, rxjs and zone.js packages
66 | * Removed router-deprecated package
67 | * Updated karma.conf.js and systemjs.config.js
68 |
69 |
70 | # 0.2.6 (2016-08-09)
71 | * Angular 2 RC5 version
72 | * Updated new forms, router and angular2-in-memory-web-api
73 |
74 |
75 | # 0.2.5 (2016-06-30)
76 | * Angular 2 RC4 version
77 | * Updated new forms and router
78 |
79 |
80 | # 0.2.4 (2016-06-21)
81 | * Angular 2 RC3 version
82 | * Add new forms and router
83 | * Add support for TS e2e tests
84 |
85 |
86 | # 0.2.3 (2016-06-15)
87 | * Angular 2 RC2 version
88 |
89 |
90 | # 0.2.2 (2016-05-21)
91 | * Update to Typings 1.x
92 |
93 |
94 | # 0.2.1 (2016-05-03)
95 | * Angular 2 RC01 version
96 |
97 |
98 | # 0.2.0 (2016-05-02)
99 | * Angular 2 RC0 version
100 |
101 |
102 | # 0.1.17 (2016-04-29)
103 | * update packages
104 | * Angular 2 beta 17
105 | * RxJS 5.0.0-beta.6
106 | * a2-in-memory-web-api 0.1.17
107 |
108 |
109 | # 0.1.16 (2016-04-26)
110 | * update packages
111 | * Angular 2 beta 16
112 | * a2-in-memory-web-api 0.1.6
113 | * protractor 3.3.0
114 | * typings 0.8.1
115 | * zone.js 0.6.12
116 |
117 | * added favicon.ico
118 |
119 | * testing
120 | - updated wallaby.js and karma.conf.js
121 | - updated app.component.spec.ts
122 |
123 |
124 |
125 | # 0.1.15 (2016-04-13)
126 | * Add testing support
127 | * npm scripts
128 | * karma/jasmine
129 | * protractor
130 |
131 | * update packages
132 | * Angular 2 beta 15
133 | * lite-server 2.2.0
134 | * systemjs 0.19.26
135 | * typescript 1.8.10
136 | * typings 0.7.12
137 |
138 | * add run packages
139 | * a2-in-memory-web-api
140 |
141 | * add testing dev-dependency packages
142 | * canonical-path: 0.0.2,
143 | * http-server: ^0.9.0,
144 | * jasmine-core: ~2.4.1,
145 | * karma: ^0.13.22,
146 | * karma-chrome-launcher: ^0.2.3,
147 | * karma-cli: ^0.1.2,
148 | * karma-htmlfile-reporter: ^0.2.2,
149 | * karma-jasmine: ^0.3.8,
150 | * protractor: ^3.2.2,
151 | * rimraf: ^2.5.2
152 |
153 |
154 | # 0.1.14 (2016-04-07)
155 | * update packages
156 | * Angular 2 beta 14
157 | * lite-server 2.2.0
158 | * typings 0.7.12
159 |
160 |
161 | # 0.1.13 (2016-03-31)
162 | * update packages
163 | * Angular 2 beta 13
164 |
165 |
166 | # 0.1.12 (2016-03-23)
167 | * update packages
168 | * Angular 2 beta 12
169 | * zones 0.6.6
170 | * remove es6-promise because no longer needed.
171 |
172 |
173 | # 0.1.11 (2016-03-18)
174 | * update packages
175 | * Angular 2 beta 11
176 | * zones 0.6.4
177 | * typescript 1.8.9
178 | * typings 0.7.9
179 |
--------------------------------------------------------------------------------
/Chapter 03/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2016 Google, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Chapter 03/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AppComponent } from './app.component';
2 |
3 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4 |
5 | describe('AppComponent', function () {
6 | let comp: AppComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ AppComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(AppComponent);
18 | comp = fixture.componentInstance;
19 | });
20 |
21 | it('Should define a list object', () => {
22 | expect(comp.items).toBeDefined();
23 | });
24 |
25 | it('Should have 3 items in list', () => {
26 | expect(comp.items.length).toBe(3);
27 | });
28 |
29 | it('List items should be as expected', () => {
30 | expect(comp.items).toEqual(['test','execute','refactor']);
31 | });
32 |
33 | describe('Testing add method', () => {
34 |
35 | beforeEach(() => {
36 | comp.add('new-item');
37 | });
38 |
39 | it('Should have 4 items in list', () => {
40 | expect(comp.items.length).toBe(4);
41 | });
42 |
43 | it('Should add a new item at the end of list', () => {
44 | var lastIndexOfList = comp.items.length - 1;
45 | expect(comp.items[lastIndexOfList]).toEqual('new-item');
46 | });
47 | });
48 |
49 | });
50 |
--------------------------------------------------------------------------------
/Chapter 03/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'my-app',
5 | template: `MY Items
`
6 | })
7 | export class AppComponent {
8 | items:Array;
9 |
10 | constructor() {
11 | this.items = ['test','execute','refactor'];
12 | }
13 |
14 | add(item) {
15 | this.items.push(item);
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/Chapter 03/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 |
4 | import { AppComponent } from './app.component';
5 |
6 | @NgModule({
7 | imports: [ BrowserModule ],
8 | declarations: [ AppComponent ],
9 | bootstrap: [ AppComponent ]
10 | })
11 | export class AppModule { }
12 |
--------------------------------------------------------------------------------
/Chapter 03/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/Chapter 03/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | describe('AppComponent Tests', () => {
4 |
5 | beforeEach(() => {
6 | browser.get('/');
7 | });
8 |
9 | it('Browser should have a defined title', () => {
10 | expect(browser.getTitle()).toEqual('Angular Karma');
11 | });
12 |
13 | });
14 |
--------------------------------------------------------------------------------
/Chapter 03/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 03/favicon.ico
--------------------------------------------------------------------------------
/Chapter 03/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular Karma
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | Loading AppComponent content here ...
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 03/karma-test-shim.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | // /*global jasmine, __karma__, window*/
3 | Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
4 |
5 | // Uncomment to get full stacktrace output. Sometimes helpful, usually not.
6 | // Error.stackTraceLimit = Infinity; //
7 |
8 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
9 |
10 | var builtPath = '/base/app/';
11 |
12 | __karma__.loaded = function () { };
13 |
14 | function isJsFile(path) {
15 | return path.slice(-3) == '.js';
16 | }
17 |
18 | function isSpecFile(path) {
19 | return /\.spec\.(.*\.)?js$/.test(path);
20 | }
21 |
22 | function isBuiltFile(path) {
23 | return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
24 | }
25 |
26 | var allSpecFiles = Object.keys(window.__karma__.files)
27 | .filter(isSpecFile)
28 | .filter(isBuiltFile);
29 |
30 | System.config({
31 | baseURL: 'base',
32 | // Extend usual application package list with test folder
33 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
34 |
35 | // Assume npm: is set in `paths` in systemjs.config
36 | // Map the angular testing umd bundles
37 | map: {
38 | '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
39 | '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
40 | '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
41 | '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
42 | '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
43 | '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
44 | '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
45 | '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
46 | },
47 | });
48 |
49 | System.import('systemjs.config.js')
50 | .then(importSystemJsExtras)
51 | .then(initTestBed)
52 | .then(initTesting);
53 |
54 | /** Optional SystemJS configuration extras. Keep going w/o it */
55 | function importSystemJsExtras(){
56 | return System.import('systemjs.config.extras.js')
57 | .catch(function(reason) {
58 | console.log(
59 | 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
60 | );
61 | console.log(reason);
62 | });
63 | }
64 |
65 | function initTestBed(){
66 | return Promise.all([
67 | System.import('@angular/core/testing'),
68 | System.import('@angular/platform-browser-dynamic/testing')
69 | ])
70 |
71 | .then(function (providers) {
72 | var coreTesting = providers[0];
73 | var browserTesting = providers[1];
74 |
75 | coreTesting.TestBed.initTestEnvironment(
76 | browserTesting.BrowserDynamicTestingModule,
77 | browserTesting.platformBrowserDynamicTesting());
78 | })
79 | }
80 |
81 | // Import all spec files and start karma
82 | function initTesting () {
83 | return Promise.all(
84 | allSpecFiles.map(function (moduleName) {
85 | return System.import(moduleName);
86 | })
87 | )
88 | .then(__karma__.start, __karma__.error);
89 | }
90 |
--------------------------------------------------------------------------------
/Chapter 03/karma.conf.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | module.exports = function(config) {
3 |
4 | config.set({
5 | basePath: '',
6 | frameworks: ['jasmine'],
7 | plugins: [
8 | require('karma-jasmine'),
9 | require('karma-chrome-launcher')
10 | ],
11 |
12 | files: [
13 | // System.js for module loading
14 | 'node_modules/systemjs/dist/system.src.js',
15 |
16 | // Polyfills
17 | 'node_modules/core-js/client/shim.js',
18 | 'node_modules/reflect-metadata/Reflect.js',
19 |
20 | // zone.js
21 | 'node_modules/zone.js/dist/zone.js',
22 | 'node_modules/zone.js/dist/long-stack-trace-zone.js',
23 | 'node_modules/zone.js/dist/proxy.js',
24 | 'node_modules/zone.js/dist/sync-test.js',
25 | 'node_modules/zone.js/dist/jasmine-patch.js',
26 | 'node_modules/zone.js/dist/async-test.js',
27 | 'node_modules/zone.js/dist/fake-async-test.js',
28 |
29 | // RxJs
30 | { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
31 | { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
32 |
33 | // Paths loaded via module imports:
34 | // Angular itself
35 | { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
36 | { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
37 |
38 | { pattern: 'systemjs.config.js', included: false, watched: false },
39 | { pattern: 'systemjs.config.extras.js', included: false, watched: false },
40 | 'karma-test-shim.js',
41 |
42 | { pattern: 'app/**/*.js', included: false, watched: true }
43 | ],
44 |
45 | port: 9876,
46 | colors: true,
47 | autoWatch: true,
48 | browsers: ['Chrome'],
49 | singleRun: false
50 | })
51 | }
52 |
--------------------------------------------------------------------------------
/Chapter 03/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-TDD-chapter-3",
3 | "version": "1.0.0",
4 | "description": "QuickStart package.json from the documentation, supplemented with testing support",
5 | "scripts": {
6 | "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
7 | "e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
8 | "lint": "tslint ./app/**/*.ts -t verbose",
9 | "lite": "lite-server",
10 | "pree2e": "webdriver-manager update",
11 | "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
12 | "test-once": "tsc && karma start karma.conf.js --single-run",
13 | "tsc": "tsc",
14 | "tsc:w": "tsc -w"
15 | },
16 | "keywords": [],
17 | "author": "",
18 | "license": "MIT",
19 | "dependencies": {
20 | "@angular/common": "~2.2.0",
21 | "@angular/compiler": "~2.2.0",
22 | "@angular/core": "~2.2.0",
23 | "@angular/forms": "~2.2.0",
24 | "@angular/http": "~2.2.0",
25 | "@angular/platform-browser": "~2.2.0",
26 | "@angular/platform-browser-dynamic": "~2.2.0",
27 | "@angular/router": "~3.2.0",
28 |
29 | "angular-in-memory-web-api": "~0.1.15",
30 | "systemjs": "0.19.40",
31 | "core-js": "^2.4.1",
32 | "reflect-metadata": "^0.1.8",
33 | "rxjs": "5.0.0-beta.12",
34 | "zone.js": "^0.6.26"
35 | },
36 | "devDependencies": {
37 | "concurrently": "^3.1.0",
38 | "lite-server": "^2.2.2",
39 | "typescript": "^2.0.10",
40 |
41 | "canonical-path": "0.0.2",
42 | "http-server": "^0.9.0",
43 | "tslint": "^3.15.1",
44 | "lodash": "^4.16.4",
45 | "jasmine-core": "~2.4.1",
46 | "karma": "^1.3.0",
47 | "karma-chrome-launcher": "^2.0.0",
48 | "karma-cli": "^1.0.1",
49 | "karma-htmlfile-reporter": "^0.3.4",
50 | "karma-jasmine": "^1.0.2",
51 | "karma-jasmine-html-reporter": "^0.2.2",
52 | "protractor": "4.0.14",
53 | "webdriver-manager": "10.2.5",
54 | "rimraf": "^2.5.4",
55 |
56 | "@types/node": "^6.0.46",
57 | "@types/jasmine": "^2.5.36",
58 | "@types/selenium-webdriver": "^2.53.33"
59 | },
60 | "repository": {}
61 | }
62 |
--------------------------------------------------------------------------------
/Chapter 03/styles.css:
--------------------------------------------------------------------------------
1 | h1 {
2 | color: #369;
3 | font-family: Arial, Helvetica, sans-serif;
4 | font-size: 250%;
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 03/systemjs.config.extras.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Add barrels and stuff
3 | * Adjust as necessary for your application needs.
4 | */
5 | // (function (global) {
6 | // System.config({
7 | // packages: {
8 | // // add packages here
9 | // }
10 | // });
11 | // })(this);
12 |
--------------------------------------------------------------------------------
/Chapter 03/systemjs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function (global) {
6 | System.config({
7 | paths: {
8 | // paths serve as alias
9 | 'npm:': 'node_modules/'
10 | },
11 | // map tells the System loader where to look for things
12 | map: {
13 | // our app is within the app folder
14 | app: 'app',
15 |
16 | // angular bundles
17 | '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
18 | '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
19 | '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
20 | '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
21 | '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
22 | '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
23 | '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
24 | '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
25 | '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
26 | '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
27 | '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
28 |
29 | // other libraries
30 | 'rxjs': 'npm:rxjs',
31 | 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
32 | },
33 | // packages tells the System loader how to load when no filename and/or no extension
34 | packages: {
35 | app: {
36 | main: './main.js',
37 | defaultExtension: 'js'
38 | },
39 | rxjs: {
40 | defaultExtension: 'js'
41 | }
42 | }
43 | });
44 | })(this);
45 |
--------------------------------------------------------------------------------
/Chapter 03/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "lib": [ "es2015", "dom" ],
10 | "noImplicitAny": false,
11 | "suppressImplicitAnyIndexErrors": true
12 | },
13 | "exclude": [
14 | "node_modules/*",
15 | "**/*-aot.ts"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter 03/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "class-name": true,
4 | "comment-format": [
5 | true,
6 | "check-space"
7 | ],
8 | "curly": true,
9 | "eofline": true,
10 | "forin": true,
11 | "indent": [
12 | true,
13 | "spaces"
14 | ],
15 | "label-position": true,
16 | "label-undefined": true,
17 | "max-line-length": [
18 | true,
19 | 140
20 | ],
21 | "member-access": false,
22 | "member-ordering": [
23 | true,
24 | "static-before-instance",
25 | "variables-before-functions"
26 | ],
27 | "no-arg": true,
28 | "no-bitwise": true,
29 | "no-console": [
30 | true,
31 | "debug",
32 | "info",
33 | "time",
34 | "timeEnd",
35 | "trace"
36 | ],
37 | "no-construct": true,
38 | "no-debugger": true,
39 | "no-duplicate-key": true,
40 | "no-duplicate-variable": true,
41 | "no-empty": false,
42 | "no-eval": true,
43 | "no-inferrable-types": true,
44 | "no-shadowed-variable": true,
45 | "no-string-literal": false,
46 | "no-switch-case-fall-through": true,
47 | "no-trailing-whitespace": true,
48 | "no-unused-expression": true,
49 | "no-unused-variable": true,
50 | "no-unreachable": true,
51 | "no-use-before-declare": true,
52 | "no-var-keyword": true,
53 | "object-literal-sort-keys": false,
54 | "one-line": [
55 | true,
56 | "check-open-brace",
57 | "check-catch",
58 | "check-else",
59 | "check-whitespace"
60 | ],
61 | "quotemark": [
62 | true,
63 | "single"
64 | ],
65 | "radix": true,
66 | "semicolon": [
67 | "always"
68 | ],
69 | "triple-equals": [
70 | true,
71 | "allow-null-check"
72 | ],
73 | "typedef-whitespace": [
74 | true,
75 | {
76 | "call-signature": "nospace",
77 | "index-signature": "nospace",
78 | "parameter": "nospace",
79 | "property-declaration": "nospace",
80 | "variable-declaration": "nospace"
81 | }
82 | ],
83 | "variable-name": false,
84 | "whitespace": [
85 | true,
86 | "check-branch",
87 | "check-decl",
88 | "check-operator",
89 | "check-separator",
90 | "check-type"
91 | ]
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Chapter 04/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
16 | # Indentation override
17 | #[lib/**.js]
18 | #[{package.json,.travis.yml}]
19 | #[**/**.js]
20 |
--------------------------------------------------------------------------------
/Chapter 04/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | jspm_packages
4 | npm-debug.*
5 | link-checker-results.txt
6 | app/**/*.js
7 | *.js.map
8 | e2e/**/*.js
9 | e2e/**/*.js.map
10 | _test-output
11 | _temp
12 |
--------------------------------------------------------------------------------
/Chapter 04/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | sudo: required
3 | language: node_js
4 | node_js:
5 | - "5"
6 | os:
7 | - linux
8 | env:
9 | global:
10 | - DBUS_SESSION_BUS_ADDRESS=/dev/null
11 | - DISPLAY=:99.0
12 | - CHROME_BIN=chromium-browser
13 | before_script:
14 | - sh -e /etc/init.d/xvfb start
15 | install:
16 | - npm install
17 | script:
18 | - npm run lint
19 | - npm run test-once
20 | - npm run e2e
21 |
--------------------------------------------------------------------------------
/Chapter 04/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Angular Documentation QuickStart Changelog
2 | Upgraders: for a fresh start, consider running these commands
3 | * `git clean -xdf`
4 | * `npm install`
5 |
6 |
7 | # 0.2.17 (2016-11-16)
8 | * Conform to updated QuickStart advice
9 | * removed docker everywhere (was nice but not necessary)
10 | * removed wallaby
11 | * shrink styles.css
12 | * refine tsconfig.json
13 | * `AppComponent` uses interpolation
14 |
15 |
16 | # 0.2.16 (2016-11-14)
17 | * Update to Angular 2.2.0
18 |
19 |
20 | # 0.2.15 (2016-10-29)
21 | * Revert to Jasmine 2.4.1 because bug in 2.5.x (see [jasmine issue #1231](https://github.com/jasmine/jasmine/issues/1231))
22 |
23 |
24 | # 0.2.14 (2016-10-29)
25 | * Remove bootstrap.css install
26 | * Angular v2.1.2
27 |
28 |
29 | # 0.2.13 (2016-10-20)
30 | * Protractor 4
31 | * Move from `typings` to `@types`. See `tsconfig.json` changes.
32 | * Angular v2.1.1
33 |
34 |
35 | # 0.2.12 (2016-10-06)
36 | * Angular v2.1.0
37 |
38 |
39 | # 0.2.11 (2016-10-06)
40 | * Angular v2.0.2
41 | * License is MIT
42 | * Current testing configuration
43 | * No code changes
44 |
45 |
46 | # 0.2.10 (2016-09-19)
47 | * All "Angular 2" references become just "Angular"
48 | * No code changes
49 |
50 |
51 | # 0.2.9 (2016-09-14)
52 | * Angular 2.0.0 version
53 | * Update to Typescript 2.0.2
54 | * Fix e2e test missing dir
55 |
56 |
57 | # 0.2.8 (2016-09-01)
58 | * remove @angular test libraries from system.js (now in shim)
59 | * update test related files
60 | * wallaby doesn't completely work. Researching.
61 |
62 |
63 | # 0.2.7 (2016-08-31)
64 | * Angular 2 RC6 version
65 | * Updated new forms, router, angular2-in-memory-web-api, karma, core-js, rxjs and zone.js packages
66 | * Removed router-deprecated package
67 | * Updated karma.conf.js and systemjs.config.js
68 |
69 |
70 | # 0.2.6 (2016-08-09)
71 | * Angular 2 RC5 version
72 | * Updated new forms, router and angular2-in-memory-web-api
73 |
74 |
75 | # 0.2.5 (2016-06-30)
76 | * Angular 2 RC4 version
77 | * Updated new forms and router
78 |
79 |
80 | # 0.2.4 (2016-06-21)
81 | * Angular 2 RC3 version
82 | * Add new forms and router
83 | * Add support for TS e2e tests
84 |
85 |
86 | # 0.2.3 (2016-06-15)
87 | * Angular 2 RC2 version
88 |
89 |
90 | # 0.2.2 (2016-05-21)
91 | * Update to Typings 1.x
92 |
93 |
94 | # 0.2.1 (2016-05-03)
95 | * Angular 2 RC01 version
96 |
97 |
98 | # 0.2.0 (2016-05-02)
99 | * Angular 2 RC0 version
100 |
101 |
102 | # 0.1.17 (2016-04-29)
103 | * update packages
104 | * Angular 2 beta 17
105 | * RxJS 5.0.0-beta.6
106 | * a2-in-memory-web-api 0.1.17
107 |
108 |
109 | # 0.1.16 (2016-04-26)
110 | * update packages
111 | * Angular 2 beta 16
112 | * a2-in-memory-web-api 0.1.6
113 | * protractor 3.3.0
114 | * typings 0.8.1
115 | * zone.js 0.6.12
116 |
117 | * added favicon.ico
118 |
119 | * testing
120 | - updated wallaby.js and karma.conf.js
121 | - updated app.component.spec.ts
122 |
123 |
124 |
125 | # 0.1.15 (2016-04-13)
126 | * Add testing support
127 | * npm scripts
128 | * karma/jasmine
129 | * protractor
130 |
131 | * update packages
132 | * Angular 2 beta 15
133 | * lite-server 2.2.0
134 | * systemjs 0.19.26
135 | * typescript 1.8.10
136 | * typings 0.7.12
137 |
138 | * add run packages
139 | * a2-in-memory-web-api
140 |
141 | * add testing dev-dependency packages
142 | * canonical-path: 0.0.2,
143 | * http-server: ^0.9.0,
144 | * jasmine-core: ~2.4.1,
145 | * karma: ^0.13.22,
146 | * karma-chrome-launcher: ^0.2.3,
147 | * karma-cli: ^0.1.2,
148 | * karma-htmlfile-reporter: ^0.2.2,
149 | * karma-jasmine: ^0.3.8,
150 | * protractor: ^3.2.2,
151 | * rimraf: ^2.5.2
152 |
153 |
154 | # 0.1.14 (2016-04-07)
155 | * update packages
156 | * Angular 2 beta 14
157 | * lite-server 2.2.0
158 | * typings 0.7.12
159 |
160 |
161 | # 0.1.13 (2016-03-31)
162 | * update packages
163 | * Angular 2 beta 13
164 |
165 |
166 | # 0.1.12 (2016-03-23)
167 | * update packages
168 | * Angular 2 beta 12
169 | * zones 0.6.6
170 | * remove es6-promise because no longer needed.
171 |
172 |
173 | # 0.1.11 (2016-03-18)
174 | * update packages
175 | * Angular 2 beta 11
176 | * zones 0.6.4
177 | * typescript 1.8.9
178 | * typings 0.7.9
179 |
--------------------------------------------------------------------------------
/Chapter 04/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2016 Google, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Chapter 04/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AppComponent } from './app.component';
2 |
3 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4 |
5 | describe('AppComponent', function () {
6 | let comp: AppComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ AppComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(AppComponent);
18 | comp = fixture.componentInstance;
19 | });
20 |
21 | it('Should define a list object', () => {
22 | expect(comp.items).toBeDefined();
23 | });
24 |
25 | it('Should have 3 items in list', () => {
26 | expect(comp.items.length).toBe(3);
27 | });
28 |
29 | it('List items should be as expected', () => {
30 | expect(comp.items).toEqual(['test','execute','refactor']);
31 | });
32 |
33 | describe('Testing add method', () => {
34 |
35 | beforeEach(() => {
36 | comp.add('new-item');
37 | });
38 |
39 | it('Should have 4 items in list', () => {
40 | expect(comp.items.length).toBe(4);
41 | });
42 |
43 | it('Should add a new item at the end of list', () => {
44 | var lastIndexOfList = comp.items.length - 1;
45 | expect(comp.items[lastIndexOfList]).toEqual('new-item');
46 | });
47 | });
48 |
49 | });
50 |
--------------------------------------------------------------------------------
/Chapter 04/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'my-app',
5 | template: `MY Items
`
6 | })
7 | export class AppComponent {
8 | items:Array;
9 |
10 | constructor() {
11 | this.items = ['test','execute','refactor'];
12 | }
13 |
14 | add(item) {
15 | this.items.push(item);
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/Chapter 04/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 |
4 | import { AppComponent } from './app.component';
5 |
6 | @NgModule({
7 | imports: [ BrowserModule ],
8 | declarations: [ AppComponent ],
9 | bootstrap: [ AppComponent ]
10 | })
11 | export class AppModule { }
12 |
--------------------------------------------------------------------------------
/Chapter 04/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/Chapter 04/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | describe('AppComponent Tests', () => {
4 |
5 | var todoListItems = element.all(by.css('li'));
6 |
7 | beforeEach(() => {
8 | browser.get('/');
9 | });
10 |
11 | it('Browser should have a defined title', () => {
12 | expect(browser.getTitle()).toEqual('Angular Protractor');
13 | });
14 |
15 | it('Should get the number of items as defined in item object', () => {
16 | expect(todoListItems.count()).toBe(3);
17 | });
18 |
19 | it('Should get the first item text as defined', () => {
20 | expect(todoListItems.first().getText()).toEqual('test');
21 | });
22 |
23 | it('Should get the last item text as defined', () => {
24 | expect(todoListItems.last().getText()).toEqual('refactor');
25 | });
26 |
27 | });
28 |
--------------------------------------------------------------------------------
/Chapter 04/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 04/favicon.ico
--------------------------------------------------------------------------------
/Chapter 04/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular Protractor
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | Loading AppComponent content here ...
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 04/karma-test-shim.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | // /*global jasmine, __karma__, window*/
3 | Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
4 |
5 | // Uncomment to get full stacktrace output. Sometimes helpful, usually not.
6 | // Error.stackTraceLimit = Infinity; //
7 |
8 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
9 |
10 | var builtPath = '/base/app/';
11 |
12 | __karma__.loaded = function () { };
13 |
14 | function isJsFile(path) {
15 | return path.slice(-3) == '.js';
16 | }
17 |
18 | function isSpecFile(path) {
19 | return /\.spec\.(.*\.)?js$/.test(path);
20 | }
21 |
22 | function isBuiltFile(path) {
23 | return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
24 | }
25 |
26 | var allSpecFiles = Object.keys(window.__karma__.files)
27 | .filter(isSpecFile)
28 | .filter(isBuiltFile);
29 |
30 | System.config({
31 | baseURL: 'base',
32 | // Extend usual application package list with test folder
33 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
34 |
35 | // Assume npm: is set in `paths` in systemjs.config
36 | // Map the angular testing umd bundles
37 | map: {
38 | '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
39 | '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
40 | '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
41 | '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
42 | '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
43 | '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
44 | '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
45 | '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
46 | },
47 | });
48 |
49 | System.import('systemjs.config.js')
50 | .then(importSystemJsExtras)
51 | .then(initTestBed)
52 | .then(initTesting);
53 |
54 | /** Optional SystemJS configuration extras. Keep going w/o it */
55 | function importSystemJsExtras(){
56 | return System.import('systemjs.config.extras.js')
57 | .catch(function(reason) {
58 | console.log(
59 | 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
60 | );
61 | console.log(reason);
62 | });
63 | }
64 |
65 | function initTestBed(){
66 | return Promise.all([
67 | System.import('@angular/core/testing'),
68 | System.import('@angular/platform-browser-dynamic/testing')
69 | ])
70 |
71 | .then(function (providers) {
72 | var coreTesting = providers[0];
73 | var browserTesting = providers[1];
74 |
75 | coreTesting.TestBed.initTestEnvironment(
76 | browserTesting.BrowserDynamicTestingModule,
77 | browserTesting.platformBrowserDynamicTesting());
78 | })
79 | }
80 |
81 | // Import all spec files and start karma
82 | function initTesting () {
83 | return Promise.all(
84 | allSpecFiles.map(function (moduleName) {
85 | return System.import(moduleName);
86 | })
87 | )
88 | .then(__karma__.start, __karma__.error);
89 | }
90 |
--------------------------------------------------------------------------------
/Chapter 04/karma.conf.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | module.exports = function(config) {
3 |
4 | config.set({
5 | basePath: '',
6 | frameworks: ['jasmine'],
7 | plugins: [
8 | require('karma-jasmine'),
9 | require('karma-chrome-launcher')
10 | ],
11 |
12 | files: [
13 | // System.js for module loading
14 | 'node_modules/systemjs/dist/system.src.js',
15 |
16 | // Polyfills
17 | 'node_modules/core-js/client/shim.js',
18 | 'node_modules/reflect-metadata/Reflect.js',
19 |
20 | // zone.js
21 | 'node_modules/zone.js/dist/zone.js',
22 | 'node_modules/zone.js/dist/long-stack-trace-zone.js',
23 | 'node_modules/zone.js/dist/proxy.js',
24 | 'node_modules/zone.js/dist/sync-test.js',
25 | 'node_modules/zone.js/dist/jasmine-patch.js',
26 | 'node_modules/zone.js/dist/async-test.js',
27 | 'node_modules/zone.js/dist/fake-async-test.js',
28 |
29 | // RxJs
30 | { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
31 | { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
32 |
33 | // Paths loaded via module imports:
34 | // Angular itself
35 | { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
36 | { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
37 |
38 | { pattern: 'systemjs.config.js', included: false, watched: false },
39 | { pattern: 'systemjs.config.extras.js', included: false, watched: false },
40 | 'karma-test-shim.js',
41 |
42 | { pattern: 'app/**/*.js', included: false, watched: true }
43 | ],
44 |
45 | port: 9876,
46 | colors: true,
47 | autoWatch: true,
48 | browsers: ['Chrome'],
49 | singleRun: false
50 | })
51 | }
52 |
--------------------------------------------------------------------------------
/Chapter 04/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-TDD-chapter-4",
3 | "version": "1.0.0",
4 | "description": "QuickStart package.json from the documentation, supplemented with testing support",
5 | "scripts": {
6 | "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
7 | "e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
8 | "lint": "tslint ./app/**/*.ts -t verbose",
9 | "lite": "lite-server",
10 | "pree2e": "webdriver-manager update",
11 | "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
12 | "test-once": "tsc && karma start karma.conf.js --single-run",
13 | "tsc": "tsc",
14 | "tsc:w": "tsc -w"
15 | },
16 | "keywords": [],
17 | "author": "",
18 | "license": "MIT",
19 | "dependencies": {
20 | "@angular/common": "~2.2.0",
21 | "@angular/compiler": "~2.2.0",
22 | "@angular/core": "~2.2.0",
23 | "@angular/forms": "~2.2.0",
24 | "@angular/http": "~2.2.0",
25 | "@angular/platform-browser": "~2.2.0",
26 | "@angular/platform-browser-dynamic": "~2.2.0",
27 | "@angular/router": "~3.2.0",
28 |
29 | "angular-in-memory-web-api": "~0.1.15",
30 | "systemjs": "0.19.40",
31 | "core-js": "^2.4.1",
32 | "reflect-metadata": "^0.1.8",
33 | "rxjs": "5.0.0-beta.12",
34 | "zone.js": "^0.6.26"
35 | },
36 | "devDependencies": {
37 | "concurrently": "^3.1.0",
38 | "lite-server": "^2.2.2",
39 | "typescript": "^2.0.10",
40 |
41 | "canonical-path": "0.0.2",
42 | "http-server": "^0.9.0",
43 | "tslint": "^3.15.1",
44 | "lodash": "^4.16.4",
45 | "jasmine-core": "~2.4.1",
46 | "karma": "^1.3.0",
47 | "karma-chrome-launcher": "^2.0.0",
48 | "karma-cli": "^1.0.1",
49 | "karma-htmlfile-reporter": "^0.3.4",
50 | "karma-jasmine": "^1.0.2",
51 | "karma-jasmine-html-reporter": "^0.2.2",
52 | "protractor": "4.0.14",
53 | "webdriver-manager": "10.2.5",
54 | "rimraf": "^2.5.4",
55 |
56 | "@types/node": "^6.0.46",
57 | "@types/jasmine": "^2.5.36",
58 | "@types/selenium-webdriver": "^2.53.33"
59 | },
60 | "repository": {}
61 | }
62 |
--------------------------------------------------------------------------------
/Chapter 04/protractor.config.js:
--------------------------------------------------------------------------------
1 | // FIRST TIME ONLY- run:
2 | // ./node_modules/.bin/webdriver-manager update
3 | //
4 | // Try: `npm run webdriver:update`
5 | //
6 | // AND THEN EVERYTIME ...
7 | // 1. Compile with `tsc`
8 | // 2. Make sure the test server (e.g., http-server: localhost:8080) is running.
9 | // 3. ./node_modules/.bin/protractor protractor.config.js
10 | //
11 | // To do all steps, try: `npm run e2e`
12 |
13 | var fs = require('fs');
14 | var path = require('canonical-path');
15 | var _ = require('lodash');
16 |
17 |
18 | exports.config = {
19 | directConnect: true,
20 |
21 | // Capabilities to be passed to the webdriver instance.
22 | capabilities: {
23 | 'browserName': 'chrome'
24 | },
25 |
26 | // Framework to use. Jasmine is recommended.
27 | framework: 'jasmine',
28 |
29 | // Spec patterns are relative to this config file
30 | specs: ['**/*e2e-spec.js' ],
31 |
32 |
33 | // For angular tests
34 | useAllAngular2AppRoots: true,
35 |
36 | // Base URL for application server
37 | baseUrl: 'http://localhost:8080',
38 |
39 |
40 | jasmineNodeOpts: {
41 | // defaultTimeoutInterval: 60000,
42 | defaultTimeoutInterval: 10000,
43 | showTiming: true,
44 | print: function() {}
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/Chapter 04/styles.css:
--------------------------------------------------------------------------------
1 | h1 {
2 | color: #369;
3 | font-family: Arial, Helvetica, sans-serif;
4 | font-size: 250%;
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 04/systemjs.config.extras.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Add barrels and stuff
3 | * Adjust as necessary for your application needs.
4 | */
5 | // (function (global) {
6 | // System.config({
7 | // packages: {
8 | // // add packages here
9 | // }
10 | // });
11 | // })(this);
12 |
--------------------------------------------------------------------------------
/Chapter 04/systemjs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function (global) {
6 | System.config({
7 | paths: {
8 | // paths serve as alias
9 | 'npm:': 'node_modules/'
10 | },
11 | // map tells the System loader where to look for things
12 | map: {
13 | // our app is within the app folder
14 | app: 'app',
15 |
16 | // angular bundles
17 | '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
18 | '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
19 | '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
20 | '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
21 | '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
22 | '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
23 | '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
24 | '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
25 | '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
26 | '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
27 | '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
28 |
29 | // other libraries
30 | 'rxjs': 'npm:rxjs',
31 | 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
32 | },
33 | // packages tells the System loader how to load when no filename and/or no extension
34 | packages: {
35 | app: {
36 | main: './main.js',
37 | defaultExtension: 'js'
38 | },
39 | rxjs: {
40 | defaultExtension: 'js'
41 | }
42 | }
43 | });
44 | })(this);
45 |
--------------------------------------------------------------------------------
/Chapter 04/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "lib": [ "es2015", "dom" ],
10 | "noImplicitAny": false,
11 | "suppressImplicitAnyIndexErrors": true
12 | },
13 | "exclude": [
14 | "node_modules/*",
15 | "**/*-aot.ts"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter 04/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "class-name": true,
4 | "comment-format": [
5 | true,
6 | "check-space"
7 | ],
8 | "curly": true,
9 | "eofline": true,
10 | "forin": true,
11 | "indent": [
12 | true,
13 | "spaces"
14 | ],
15 | "label-position": true,
16 | "label-undefined": true,
17 | "max-line-length": [
18 | true,
19 | 140
20 | ],
21 | "member-access": false,
22 | "member-ordering": [
23 | true,
24 | "static-before-instance",
25 | "variables-before-functions"
26 | ],
27 | "no-arg": true,
28 | "no-bitwise": true,
29 | "no-console": [
30 | true,
31 | "debug",
32 | "info",
33 | "time",
34 | "timeEnd",
35 | "trace"
36 | ],
37 | "no-construct": true,
38 | "no-debugger": true,
39 | "no-duplicate-key": true,
40 | "no-duplicate-variable": true,
41 | "no-empty": false,
42 | "no-eval": true,
43 | "no-inferrable-types": true,
44 | "no-shadowed-variable": true,
45 | "no-string-literal": false,
46 | "no-switch-case-fall-through": true,
47 | "no-trailing-whitespace": true,
48 | "no-unused-expression": true,
49 | "no-unused-variable": true,
50 | "no-unreachable": true,
51 | "no-use-before-declare": true,
52 | "no-var-keyword": true,
53 | "object-literal-sort-keys": false,
54 | "one-line": [
55 | true,
56 | "check-open-brace",
57 | "check-catch",
58 | "check-else",
59 | "check-whitespace"
60 | ],
61 | "quotemark": [
62 | true,
63 | "single"
64 | ],
65 | "radix": true,
66 | "semicolon": [
67 | "always"
68 | ],
69 | "triple-equals": [
70 | true,
71 | "allow-null-check"
72 | ],
73 | "typedef-whitespace": [
74 | true,
75 | {
76 | "call-signature": "nospace",
77 | "index-signature": "nospace",
78 | "parameter": "nospace",
79 | "property-declaration": "nospace",
80 | "variable-declaration": "nospace"
81 | }
82 | ],
83 | "variable-name": false,
84 | "whitespace": [
85 | true,
86 | "check-branch",
87 | "check-decl",
88 | "check-operator",
89 | "check-separator",
90 | "check-type"
91 | ]
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Chapter 05/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
16 | # Indentation override
17 | #[lib/**.js]
18 | #[{package.json,.travis.yml}]
19 | #[**/**.js]
20 |
--------------------------------------------------------------------------------
/Chapter 05/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | jspm_packages
4 | npm-debug.*
5 | link-checker-results.txt
6 | app/**/*.js
7 | *.js.map
8 | debug/**/*.e2e.js
9 | debug/**/*.js.map
10 | e2e/**/*.js
11 | e2e/**/*.js.map
12 | _test-output
13 | _temp
14 |
--------------------------------------------------------------------------------
/Chapter 05/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | sudo: required
3 | language: node_js
4 | node_js:
5 | - "5"
6 | os:
7 | - linux
8 | env:
9 | global:
10 | - DBUS_SESSION_BUS_ADDRESS=/dev/null
11 | - DISPLAY=:99.0
12 | - CHROME_BIN=chromium-browser
13 | before_script:
14 | - sh -e /etc/init.d/xvfb start
15 | install:
16 | - npm install
17 | script:
18 | - npm run lint
19 | - npm run test-once
20 | - npm run e2e
21 |
--------------------------------------------------------------------------------
/Chapter 05/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Angular Documentation QuickStart Changelog
2 | Upgraders: for a fresh start, consider running these commands
3 | * `git clean -xdf`
4 | * `npm install`
5 |
6 |
7 | # 0.2.17 (2016-11-16)
8 | * Conform to updated QuickStart advice
9 | * removed docker everywhere (was nice but not necessary)
10 | * removed wallaby
11 | * shrink styles.css
12 | * refine tsconfig.json
13 | * `AppComponent` uses interpolation
14 |
15 |
16 | # 0.2.16 (2016-11-14)
17 | * Update to Angular 2.2.0
18 |
19 |
20 | # 0.2.15 (2016-10-29)
21 | * Revert to Jasmine 2.4.1 because bug in 2.5.x (see [jasmine issue #1231](https://github.com/jasmine/jasmine/issues/1231))
22 |
23 |
24 | # 0.2.14 (2016-10-29)
25 | * Remove bootstrap.css install
26 | * Angular v2.1.2
27 |
28 |
29 | # 0.2.13 (2016-10-20)
30 | * Protractor 4
31 | * Move from `typings` to `@types`. See `tsconfig.json` changes.
32 | * Angular v2.1.1
33 |
34 |
35 | # 0.2.12 (2016-10-06)
36 | * Angular v2.1.0
37 |
38 |
39 | # 0.2.11 (2016-10-06)
40 | * Angular v2.0.2
41 | * License is MIT
42 | * Current testing configuration
43 | * No code changes
44 |
45 |
46 | # 0.2.10 (2016-09-19)
47 | * All "Angular 2" references become just "Angular"
48 | * No code changes
49 |
50 |
51 | # 0.2.9 (2016-09-14)
52 | * Angular 2.0.0 version
53 | * Update to Typescript 2.0.2
54 | * Fix e2e test missing dir
55 |
56 |
57 | # 0.2.8 (2016-09-01)
58 | * remove @angular test libraries from system.js (now in shim)
59 | * update test related files
60 | * wallaby doesn't completely work. Researching.
61 |
62 |
63 | # 0.2.7 (2016-08-31)
64 | * Angular 2 RC6 version
65 | * Updated new forms, router, angular2-in-memory-web-api, karma, core-js, rxjs and zone.js packages
66 | * Removed router-deprecated package
67 | * Updated karma.conf.js and systemjs.config.js
68 |
69 |
70 | # 0.2.6 (2016-08-09)
71 | * Angular 2 RC5 version
72 | * Updated new forms, router and angular2-in-memory-web-api
73 |
74 |
75 | # 0.2.5 (2016-06-30)
76 | * Angular 2 RC4 version
77 | * Updated new forms and router
78 |
79 |
80 | # 0.2.4 (2016-06-21)
81 | * Angular 2 RC3 version
82 | * Add new forms and router
83 | * Add support for TS e2e tests
84 |
85 |
86 | # 0.2.3 (2016-06-15)
87 | * Angular 2 RC2 version
88 |
89 |
90 | # 0.2.2 (2016-05-21)
91 | * Update to Typings 1.x
92 |
93 |
94 | # 0.2.1 (2016-05-03)
95 | * Angular 2 RC01 version
96 |
97 |
98 | # 0.2.0 (2016-05-02)
99 | * Angular 2 RC0 version
100 |
101 |
102 | # 0.1.17 (2016-04-29)
103 | * update packages
104 | * Angular 2 beta 17
105 | * RxJS 5.0.0-beta.6
106 | * a2-in-memory-web-api 0.1.17
107 |
108 |
109 | # 0.1.16 (2016-04-26)
110 | * update packages
111 | * Angular 2 beta 16
112 | * a2-in-memory-web-api 0.1.6
113 | * protractor 3.3.0
114 | * typings 0.8.1
115 | * zone.js 0.6.12
116 |
117 | * added favicon.ico
118 |
119 | * testing
120 | - updated wallaby.js and karma.conf.js
121 | - updated app.component.spec.ts
122 |
123 |
124 |
125 | # 0.1.15 (2016-04-13)
126 | * Add testing support
127 | * npm scripts
128 | * karma/jasmine
129 | * protractor
130 |
131 | * update packages
132 | * Angular 2 beta 15
133 | * lite-server 2.2.0
134 | * systemjs 0.19.26
135 | * typescript 1.8.10
136 | * typings 0.7.12
137 |
138 | * add run packages
139 | * a2-in-memory-web-api
140 |
141 | * add testing dev-dependency packages
142 | * canonical-path: 0.0.2,
143 | * http-server: ^0.9.0,
144 | * jasmine-core: ~2.4.1,
145 | * karma: ^0.13.22,
146 | * karma-chrome-launcher: ^0.2.3,
147 | * karma-cli: ^0.1.2,
148 | * karma-htmlfile-reporter: ^0.2.2,
149 | * karma-jasmine: ^0.3.8,
150 | * protractor: ^3.2.2,
151 | * rimraf: ^2.5.2
152 |
153 |
154 | # 0.1.14 (2016-04-07)
155 | * update packages
156 | * Angular 2 beta 14
157 | * lite-server 2.2.0
158 | * typings 0.7.12
159 |
160 |
161 | # 0.1.13 (2016-03-31)
162 | * update packages
163 | * Angular 2 beta 13
164 |
165 |
166 | # 0.1.12 (2016-03-23)
167 | * update packages
168 | * Angular 2 beta 12
169 | * zones 0.6.6
170 | * remove es6-promise because no longer needed.
171 |
172 |
173 | # 0.1.11 (2016-03-18)
174 | * update packages
175 | * Angular 2 beta 11
176 | * zones 0.6.4
177 | * typescript 1.8.9
178 | * typings 0.7.9
179 |
--------------------------------------------------------------------------------
/Chapter 05/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2016 Google, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Chapter 05/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AppComponent } from './app.component';
2 |
3 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4 |
5 | describe('AppComponent', function () {
6 | let comp: AppComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ AppComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(AppComponent);
18 | comp = fixture.componentInstance;
19 | });
20 |
21 | it('Should define a list object', () => {
22 | expect(comp.items).toBeDefined();
23 | });
24 |
25 | it('Should have 3 items in list', () => {
26 | expect(comp.items.length).toBe(3);
27 | });
28 |
29 | it('List items should be as expected', () => {
30 | expect(comp.items).toEqual(['test','execute','refactor']);
31 | });
32 |
33 | describe('Testing add method', () => {
34 |
35 | beforeEach(() => {
36 | comp.add('new-item');
37 | });
38 |
39 | it('Should have 4 items in list', () => {
40 | expect(comp.items.length).toBe(4);
41 | });
42 |
43 | it('Should add a new item at the end of list', () => {
44 | var lastIndexOfList = comp.items.length - 1;
45 | expect(comp.items[lastIndexOfList]).toEqual('new-item');
46 | });
47 | });
48 |
49 | });
50 |
--------------------------------------------------------------------------------
/Chapter 05/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'my-app',
5 | template: `MY Items
`
6 | })
7 | export class AppComponent {
8 | items:Array;
9 |
10 | constructor() {
11 | this.items = ['test','execute','refactor'];
12 | }
13 |
14 | add(item) {
15 | this.items.push(item);
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/Chapter 05/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 |
4 | import { AppComponent } from './app.component';
5 |
6 | @NgModule({
7 | imports: [ BrowserModule ],
8 | declarations: [ AppComponent ],
9 | bootstrap: [ AppComponent ]
10 | })
11 | export class AppModule { }
12 |
--------------------------------------------------------------------------------
/Chapter 05/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/Chapter 05/debug/app.debug.e2e.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | describe('AppComponent Tests', () => {
4 |
5 | beforeEach(() => {
6 | browser.get('/');
7 | });
8 |
9 | it('Test spec for debug and play', () => {
10 | browser.pause();
11 | //browser.debugger();
12 |
13 | // There is not element with the id=“my_id”, so this will fail the test
14 | expect(element(by.id('my_id')).getText()).toEqual('my text')
15 | });
16 |
17 | });
18 |
--------------------------------------------------------------------------------
/Chapter 05/debug/debugConf.js:
--------------------------------------------------------------------------------
1 |
2 | var fs = require('fs');
3 | var path = require('canonical-path');
4 | var _ = require('lodash');
5 |
6 |
7 | exports.config = {
8 | directConnect: true,
9 |
10 | // Capabilities to be passed to the webdriver instance.
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 |
15 | // Framework to use. Jasmine is recommended.
16 | framework: 'jasmine',
17 |
18 | // Spec patterns are relative to this config file
19 | specs: [
20 | 'app.debug.e2e.js'
21 | ],
22 |
23 |
24 | // For angular tests
25 | useAllAngular2AppRoots: true,
26 |
27 | // Base URL for application server
28 | baseUrl: 'http://localhost:3000/',
29 |
30 |
31 | jasmineNodeOpts: {
32 | // defaultTimeoutInterval: 60000,
33 | defaultTimeoutInterval: 300000,
34 | showTiming: true,
35 | print: function() {}
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/Chapter 05/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | describe('AppComponent Tests', () => {
4 |
5 | var todoListItems = element.all(by.css('li'));
6 |
7 | beforeEach(() => {
8 | browser.get('/');
9 | });
10 |
11 | it('Browser should have a defined title', () => {
12 | expect(browser.getTitle()).toEqual('Angular Protractor');
13 | });
14 |
15 | it('Should get the number of items as defined in item object', () => {
16 | expect(todoListItems.count()).toBe(3);
17 | });
18 |
19 | it('Should get the first item text as defined', () => {
20 | expect(todoListItems.first().getText()).toEqual('test');
21 | });
22 |
23 | it('Should get the last item text as defined', () => {
24 | expect(todoListItems.last().getText()).toEqual('refactor');
25 | });
26 |
27 | });
28 |
--------------------------------------------------------------------------------
/Chapter 05/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 05/favicon.ico
--------------------------------------------------------------------------------
/Chapter 05/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular Protractor
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | Loading AppComponent content here ...
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 05/karma-test-shim.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | // /*global jasmine, __karma__, window*/
3 | Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
4 |
5 | // Uncomment to get full stacktrace output. Sometimes helpful, usually not.
6 | // Error.stackTraceLimit = Infinity; //
7 |
8 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
9 |
10 | var builtPath = '/base/app/';
11 |
12 | __karma__.loaded = function () { };
13 |
14 | function isJsFile(path) {
15 | return path.slice(-3) == '.js';
16 | }
17 |
18 | function isSpecFile(path) {
19 | return /\.spec\.(.*\.)?js$/.test(path);
20 | }
21 |
22 | function isBuiltFile(path) {
23 | return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
24 | }
25 |
26 | var allSpecFiles = Object.keys(window.__karma__.files)
27 | .filter(isSpecFile)
28 | .filter(isBuiltFile);
29 |
30 | System.config({
31 | baseURL: 'base',
32 | // Extend usual application package list with test folder
33 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
34 |
35 | // Assume npm: is set in `paths` in systemjs.config
36 | // Map the angular testing umd bundles
37 | map: {
38 | '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
39 | '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
40 | '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
41 | '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
42 | '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
43 | '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
44 | '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
45 | '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
46 | },
47 | });
48 |
49 | System.import('systemjs.config.js')
50 | .then(importSystemJsExtras)
51 | .then(initTestBed)
52 | .then(initTesting);
53 |
54 | /** Optional SystemJS configuration extras. Keep going w/o it */
55 | function importSystemJsExtras(){
56 | return System.import('systemjs.config.extras.js')
57 | .catch(function(reason) {
58 | console.log(
59 | 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
60 | );
61 | console.log(reason);
62 | });
63 | }
64 |
65 | function initTestBed(){
66 | return Promise.all([
67 | System.import('@angular/core/testing'),
68 | System.import('@angular/platform-browser-dynamic/testing')
69 | ])
70 |
71 | .then(function (providers) {
72 | var coreTesting = providers[0];
73 | var browserTesting = providers[1];
74 |
75 | coreTesting.TestBed.initTestEnvironment(
76 | browserTesting.BrowserDynamicTestingModule,
77 | browserTesting.platformBrowserDynamicTesting());
78 | })
79 | }
80 |
81 | // Import all spec files and start karma
82 | function initTesting () {
83 | return Promise.all(
84 | allSpecFiles.map(function (moduleName) {
85 | return System.import(moduleName);
86 | })
87 | )
88 | .then(__karma__.start, __karma__.error);
89 | }
90 |
--------------------------------------------------------------------------------
/Chapter 05/karma.conf.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | module.exports = function(config) {
3 |
4 | config.set({
5 | basePath: '',
6 | frameworks: ['jasmine'],
7 | plugins: [
8 | require('karma-jasmine'),
9 | require('karma-chrome-launcher')
10 | ],
11 |
12 | files: [
13 | // System.js for module loading
14 | 'node_modules/systemjs/dist/system.src.js',
15 |
16 | // Polyfills
17 | 'node_modules/core-js/client/shim.js',
18 | 'node_modules/reflect-metadata/Reflect.js',
19 |
20 | // zone.js
21 | 'node_modules/zone.js/dist/zone.js',
22 | 'node_modules/zone.js/dist/long-stack-trace-zone.js',
23 | 'node_modules/zone.js/dist/proxy.js',
24 | 'node_modules/zone.js/dist/sync-test.js',
25 | 'node_modules/zone.js/dist/jasmine-patch.js',
26 | 'node_modules/zone.js/dist/async-test.js',
27 | 'node_modules/zone.js/dist/fake-async-test.js',
28 |
29 | // RxJs
30 | { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
31 | { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
32 |
33 | // Paths loaded via module imports:
34 | // Angular itself
35 | { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
36 | { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
37 |
38 | { pattern: 'systemjs.config.js', included: false, watched: false },
39 | { pattern: 'systemjs.config.extras.js', included: false, watched: false },
40 | 'karma-test-shim.js',
41 |
42 | { pattern: 'app/**/*.js', included: false, watched: true }
43 | ],
44 |
45 | port: 9876,
46 | colors: true,
47 | autoWatch: true,
48 | browsers: ['Chrome'],
49 | singleRun: false
50 | })
51 | }
52 |
--------------------------------------------------------------------------------
/Chapter 05/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-TDD-chapter-5",
3 | "version": "1.0.0",
4 | "description": "QuickStart package.json from the documentation, supplemented with testing support",
5 | "scripts": {
6 | "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
7 | "e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
8 | "lint": "tslint ./app/**/*.ts -t verbose",
9 | "lite": "lite-server",
10 | "pree2e": "webdriver-manager update",
11 | "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
12 | "test-once": "tsc && karma start karma.conf.js --single-run",
13 | "tsc": "tsc",
14 | "tsc:w": "tsc -w"
15 | },
16 | "keywords": [],
17 | "author": "",
18 | "license": "MIT",
19 | "dependencies": {
20 | "@angular/common": "~2.2.0",
21 | "@angular/compiler": "~2.2.0",
22 | "@angular/core": "~2.2.0",
23 | "@angular/forms": "~2.2.0",
24 | "@angular/http": "~2.2.0",
25 | "@angular/platform-browser": "~2.2.0",
26 | "@angular/platform-browser-dynamic": "~2.2.0",
27 | "@angular/router": "~3.2.0",
28 |
29 | "angular-in-memory-web-api": "~0.1.15",
30 | "systemjs": "0.19.40",
31 | "core-js": "^2.4.1",
32 | "reflect-metadata": "^0.1.8",
33 | "rxjs": "5.0.0-beta.12",
34 | "zone.js": "^0.6.26"
35 | },
36 | "devDependencies": {
37 | "concurrently": "^3.1.0",
38 | "lite-server": "^2.2.2",
39 | "typescript": "^2.0.10",
40 |
41 | "canonical-path": "0.0.2",
42 | "http-server": "^0.9.0",
43 | "tslint": "^3.15.1",
44 | "lodash": "^4.16.4",
45 | "jasmine-core": "~2.4.1",
46 | "karma": "^1.3.0",
47 | "karma-chrome-launcher": "^2.0.0",
48 | "karma-cli": "^1.0.1",
49 | "karma-htmlfile-reporter": "^0.3.4",
50 | "karma-jasmine": "^1.0.2",
51 | "karma-jasmine-html-reporter": "^0.2.2",
52 | "protractor": "4.0.14",
53 | "webdriver-manager": "10.2.5",
54 | "rimraf": "^2.5.4",
55 |
56 | "@types/node": "^6.0.46",
57 | "@types/jasmine": "^2.5.36",
58 | "@types/selenium-webdriver": "^2.53.33"
59 | },
60 | "repository": {}
61 | }
62 |
--------------------------------------------------------------------------------
/Chapter 05/protractor.config.js:
--------------------------------------------------------------------------------
1 | // FIRST TIME ONLY- run:
2 | // ./node_modules/.bin/webdriver-manager update
3 | //
4 | // Try: `npm run webdriver:update`
5 | //
6 | // AND THEN EVERYTIME ...
7 | // 1. Compile with `tsc`
8 | // 2. Make sure the test server (e.g., http-server: localhost:8080) is running.
9 | // 3. ./node_modules/.bin/protractor protractor.config.js
10 | //
11 | // To do all steps, try: `npm run e2e`
12 |
13 | var fs = require('fs');
14 | var path = require('canonical-path');
15 | var _ = require('lodash');
16 |
17 |
18 | exports.config = {
19 | directConnect: true,
20 |
21 | // Capabilities to be passed to the webdriver instance.
22 | capabilities: {
23 | 'browserName': 'chrome'
24 | },
25 |
26 | // Framework to use. Jasmine is recommended.
27 | framework: 'jasmine',
28 |
29 | // Spec patterns are relative to this config file
30 | specs: ['**/*e2e-spec.js' ],
31 |
32 |
33 | // For angular tests
34 | useAllAngular2AppRoots: true,
35 |
36 | // Base URL for application server
37 | baseUrl: 'http://localhost:3000/',
38 |
39 |
40 | jasmineNodeOpts: {
41 | // defaultTimeoutInterval: 60000,
42 | defaultTimeoutInterval: 10000,
43 | showTiming: true,
44 | print: function() {}
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/Chapter 05/styles.css:
--------------------------------------------------------------------------------
1 | h1 {
2 | color: #369;
3 | font-family: Arial, Helvetica, sans-serif;
4 | font-size: 250%;
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 05/systemjs.config.extras.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Add barrels and stuff
3 | * Adjust as necessary for your application needs.
4 | */
5 | // (function (global) {
6 | // System.config({
7 | // packages: {
8 | // // add packages here
9 | // }
10 | // });
11 | // })(this);
12 |
--------------------------------------------------------------------------------
/Chapter 05/systemjs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function (global) {
6 | System.config({
7 | paths: {
8 | // paths serve as alias
9 | 'npm:': 'node_modules/'
10 | },
11 | // map tells the System loader where to look for things
12 | map: {
13 | // our app is within the app folder
14 | app: 'app',
15 |
16 | // angular bundles
17 | '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
18 | '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
19 | '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
20 | '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
21 | '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
22 | '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
23 | '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
24 | '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
25 | '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
26 | '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
27 | '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
28 |
29 | // other libraries
30 | 'rxjs': 'npm:rxjs',
31 | 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
32 | },
33 | // packages tells the System loader how to load when no filename and/or no extension
34 | packages: {
35 | app: {
36 | main: './main.js',
37 | defaultExtension: 'js'
38 | },
39 | rxjs: {
40 | defaultExtension: 'js'
41 | }
42 | }
43 | });
44 | })(this);
45 |
--------------------------------------------------------------------------------
/Chapter 05/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "lib": [ "es2015", "dom" ],
10 | "noImplicitAny": false,
11 | "suppressImplicitAnyIndexErrors": true
12 | },
13 | "exclude": [
14 | "node_modules/*",
15 | "**/*-aot.ts"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter 05/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "class-name": true,
4 | "comment-format": [
5 | true,
6 | "check-space"
7 | ],
8 | "curly": true,
9 | "eofline": true,
10 | "forin": true,
11 | "indent": [
12 | true,
13 | "spaces"
14 | ],
15 | "label-position": true,
16 | "label-undefined": true,
17 | "max-line-length": [
18 | true,
19 | 140
20 | ],
21 | "member-access": false,
22 | "member-ordering": [
23 | true,
24 | "static-before-instance",
25 | "variables-before-functions"
26 | ],
27 | "no-arg": true,
28 | "no-bitwise": true,
29 | "no-console": [
30 | true,
31 | "debug",
32 | "info",
33 | "time",
34 | "timeEnd",
35 | "trace"
36 | ],
37 | "no-construct": true,
38 | "no-debugger": true,
39 | "no-duplicate-key": true,
40 | "no-duplicate-variable": true,
41 | "no-empty": false,
42 | "no-eval": true,
43 | "no-inferrable-types": true,
44 | "no-shadowed-variable": true,
45 | "no-string-literal": false,
46 | "no-switch-case-fall-through": true,
47 | "no-trailing-whitespace": true,
48 | "no-unused-expression": true,
49 | "no-unused-variable": true,
50 | "no-unreachable": true,
51 | "no-use-before-declare": true,
52 | "no-var-keyword": true,
53 | "object-literal-sort-keys": false,
54 | "one-line": [
55 | true,
56 | "check-open-brace",
57 | "check-catch",
58 | "check-else",
59 | "check-whitespace"
60 | ],
61 | "quotemark": [
62 | true,
63 | "single"
64 | ],
65 | "radix": true,
66 | "semicolon": [
67 | "always"
68 | ],
69 | "triple-equals": [
70 | true,
71 | "allow-null-check"
72 | ],
73 | "typedef-whitespace": [
74 | true,
75 | {
76 | "call-signature": "nospace",
77 | "index-signature": "nospace",
78 | "parameter": "nospace",
79 | "property-declaration": "nospace",
80 | "variable-declaration": "nospace"
81 | }
82 | ],
83 | "variable-name": false,
84 | "whitespace": [
85 | true,
86 | "check-branch",
87 | "check-decl",
88 | "check-operator",
89 | "check-separator",
90 | "check-type"
91 | ]
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Chapter 06/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/Chapter 06/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
16 | # Indentation override
17 | #[lib/**.js]
18 | #[{package.json,.travis.yml}]
19 | #[**/**.js]
20 |
--------------------------------------------------------------------------------
/Chapter 06/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | node_modules
4 | jspm_packages
5 | npm-debug.*
6 | link-checker-results.txt
7 | app/**/*.js
8 | *.js.map
9 | spec/e2e/**/*.js
10 | spec/e2e/**/*.js.map
11 | spec/unit/**/*.js
12 | spec/unit/**/*.js.map
13 | _test-output
14 | _temp
15 |
--------------------------------------------------------------------------------
/Chapter 06/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | sudo: required
3 | language: node_js
4 | node_js:
5 | - "5"
6 | os:
7 | - linux
8 | env:
9 | global:
10 | - DBUS_SESSION_BUS_ADDRESS=/dev/null
11 | - DISPLAY=:99.0
12 | - CHROME_BIN=chromium-browser
13 | before_script:
14 | - sh -e /etc/init.d/xvfb start
15 | install:
16 | - npm install
17 | script:
18 | - npm run lint
19 | - npm run test-once
20 | - npm run e2e
21 |
--------------------------------------------------------------------------------
/Chapter 06/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Angular Documentation QuickStart Changelog
2 | Upgraders: to be sure of a fresh start, consider running these commands
3 | * `git clean -xdf`
4 | * `npm install`
5 | * `npm run webdriver:update`
6 |
7 |
8 | # 0.2.16 (2016-11-14)
9 | * Update to Angular 2.2.0
10 |
11 |
12 | # 0.2.15 (2016-10-29)
13 | * Revert to Jasmine 2.4.1 because bug in 2.5.x (see [jasmine issue #1231](https://github.com/jasmine/jasmine/issues/1231))
14 |
15 |
16 | # 0.2.14 (2016-10-29)
17 | * Remove bootstrap.css install
18 | * Angular v2.1.2
19 |
20 |
21 | # 0.2.13 (2016-10-20)
22 | * Protractor 4
23 | * Move from `typings` to `@types`. See `tsconfig.json` changes.
24 | * Angular v2.1.1
25 |
26 |
27 | # 0.2.12 (2016-10-06)
28 | * Angular v2.1.0
29 |
30 |
31 | # 0.2.11 (2016-10-06)
32 | * Angular v2.0.2
33 | * License is MIT
34 | * Current testing configuration
35 | * No code changes
36 |
37 |
38 | # 0.2.10 (2016-09-19)
39 | * All "Angular 2" references become just "Angular"
40 | * No code changes
41 |
42 |
43 | # 0.2.9 (2016-09-14)
44 | * Angular 2.0.0 version
45 | * Update to Typescript 2.0.2
46 | * Fix e2e test missing dir
47 |
48 |
49 | # 0.2.8 (2016-09-01)
50 | * remove @angular test libraries from system.js (now in shim)
51 | * update test related files
52 | * wallaby doesn't completely work. Researching.
53 |
54 |
55 | # 0.2.7 (2016-08-31)
56 | * Angular 2 RC6 version
57 | * Updated new forms, router, angular2-in-memory-web-api, karma, core-js, rxjs and zone.js packages
58 | * Removed router-deprecated package
59 | * Updated karma.conf.js and systemjs.config.js
60 |
61 |
62 | # 0.2.6 (2016-08-09)
63 | * Angular 2 RC5 version
64 | * Updated new forms, router and angular2-in-memory-web-api
65 |
66 |
67 | # 0.2.5 (2016-06-30)
68 | * Angular 2 RC4 version
69 | * Updated new forms and router
70 |
71 |
72 | # 0.2.4 (2016-06-21)
73 | * Angular 2 RC3 version
74 | * Add new forms and router
75 | * Add support for TS e2e tests
76 |
77 |
78 | # 0.2.3 (2016-06-15)
79 | * Angular 2 RC2 version
80 |
81 |
82 | # 0.2.2 (2016-05-21)
83 | * Update to Typings 1.x
84 |
85 |
86 | # 0.2.1 (2016-05-03)
87 | * Angular 2 RC01 version
88 |
89 |
90 | # 0.2.0 (2016-05-02)
91 | * Angular 2 RC0 version
92 |
93 |
94 | # 0.1.17 (2016-04-29)
95 | * update packages
96 | * Angular 2 beta 17
97 | * RxJS 5.0.0-beta.6
98 | * a2-in-memory-web-api 0.1.17
99 |
100 |
101 | # 0.1.16 (2016-04-26)
102 | * update packages
103 | * Angular 2 beta 16
104 | * a2-in-memory-web-api 0.1.6
105 | * protractor 3.3.0
106 | * typings 0.8.1
107 | * zone.js 0.6.12
108 |
109 | * added favicon.ico
110 |
111 | * testing
112 | - updated wallaby.js and karma.conf.js
113 | - updated app.component.spec.ts
114 |
115 |
116 |
117 | # 0.1.15 (2016-04-13)
118 | * Add testing support
119 | * npm scripts
120 | * karma/jasmine
121 | * protractor
122 |
123 | * update packages
124 | * Angular 2 beta 15
125 | * lite-server 2.2.0
126 | * systemjs 0.19.26
127 | * typescript 1.8.10
128 | * typings 0.7.12
129 |
130 | * add run packages
131 | * a2-in-memory-web-api
132 |
133 | * add testing dev-dependency packages
134 | * canonical-path: 0.0.2,
135 | * http-server: ^0.9.0,
136 | * jasmine-core: ~2.4.1,
137 | * karma: ^0.13.22,
138 | * karma-chrome-launcher: ^0.2.3,
139 | * karma-cli: ^0.1.2,
140 | * karma-htmlfile-reporter: ^0.2.2,
141 | * karma-jasmine: ^0.3.8,
142 | * protractor: ^3.2.2,
143 | * rimraf: ^2.5.2
144 |
145 |
146 | # 0.1.14 (2016-04-07)
147 | * update packages
148 | * Angular 2 beta 14
149 | * lite-server 2.2.0
150 | * typings 0.7.12
151 |
152 |
153 | # 0.1.13 (2016-03-31)
154 | * update packages
155 | * Angular 2 beta 13
156 |
157 |
158 | # 0.1.12 (2016-03-23)
159 | * update packages
160 | * Angular 2 beta 12
161 | * zones 0.6.6
162 | * remove es6-promise because no longer needed.
163 |
164 |
165 | # 0.1.11 (2016-03-18)
166 | * update packages
167 | * Angular 2 beta 11
168 | * zones 0.6.4
169 | * typescript 1.8.9
170 | * typings 0.7.9
171 |
--------------------------------------------------------------------------------
/Chapter 06/Dockerfile:
--------------------------------------------------------------------------------
1 | # To build and run with Docker:
2 | #
3 | # $ docker build -t ng-quickstart .
4 | # $ docker run -it --rm -p 3000:3000 -p 3001:3001 ng-quickstart
5 | #
6 | FROM node:latest
7 |
8 | RUN mkdir -p /quickstart /home/nodejs && \
9 | groupadd -r nodejs && \
10 | useradd -r -g nodejs -d /home/nodejs -s /sbin/nologin nodejs && \
11 | chown -R nodejs:nodejs /home/nodejs
12 |
13 | WORKDIR /quickstart
14 | COPY package.json /quickstart/
15 | RUN npm install --unsafe-perm=true
16 |
17 | COPY . /quickstart
18 | RUN chown -R nodejs:nodejs /quickstart
19 | USER nodejs
20 |
21 | CMD npm start
22 |
--------------------------------------------------------------------------------
/Chapter 06/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2016 Google, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Chapter 06/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'my-app',
5 | template: `My First Angular 2 App
6 |
7 |
8 |
9 | -
10 | {{comment.title}}
11 |
12 | {{comment.likes}}
13 |
14 |
`
15 | })
16 | export class AppComponent {
17 | comments:Array;
18 |
19 | constructor() {
20 | this.comments = [
21 | {title: 'First commemnt', likes: 0}
22 | ];
23 | }
24 |
25 | add(comment) {
26 | var commentObj = {title: comment, likes: 0};
27 | this.comments.unshift(commentObj);
28 | }
29 |
30 | like(comment) {
31 | comment.likes++
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Chapter 06/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { AppComponent } from './app.component';
6 |
7 | @NgModule({
8 | imports: [ BrowserModule, FormsModule ],
9 | declarations: [ AppComponent ],
10 | bootstrap: [ AppComponent ]
11 | })
12 | export class AppModule { }
13 |
--------------------------------------------------------------------------------
/Chapter 06/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/Chapter 06/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 06/favicon.ico
--------------------------------------------------------------------------------
/Chapter 06/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular QuickStart
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | Loading...
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 06/karma-test-shim.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | // /*global jasmine, __karma__, window*/
3 | Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
4 |
5 | // Uncomment to get full stacktrace output. Sometimes helpful, usually not.
6 | // Error.stackTraceLimit = Infinity; //
7 |
8 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
9 |
10 | var builtPath = '/base/';
11 |
12 | __karma__.loaded = function () { };
13 |
14 | function isJsFile(path) {
15 | return path.slice(-3) == '.js';
16 | }
17 |
18 | function isSpecFile(path) {
19 | return /\.spec\.(.*\.)?js$/.test(path);
20 | }
21 |
22 | function isBuiltFile(path) {
23 | return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
24 | }
25 |
26 | var allSpecFiles = Object.keys(window.__karma__.files)
27 | .filter(isSpecFile)
28 | .filter(isBuiltFile);
29 |
30 | System.config({
31 | baseURL: 'base',
32 | // Extend usual application package list with test folder
33 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
34 |
35 | // Assume npm: is set in `paths` in systemjs.config
36 | // Map the angular testing umd bundles
37 | map: {
38 | '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
39 | '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
40 | '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
41 | '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
42 | '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
43 | '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
44 | '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
45 | '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
46 | },
47 | });
48 |
49 | System.import('systemjs.config.js')
50 | .then(importSystemJsExtras)
51 | .then(initTestBed)
52 | .then(initTesting);
53 |
54 | /** Optional SystemJS configuration extras. Keep going w/o it */
55 | function importSystemJsExtras(){
56 | return System.import('systemjs.config.extras.js')
57 | .catch(function(reason) {
58 | console.log(
59 | 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
60 | );
61 | console.log(reason);
62 | });
63 | }
64 |
65 | function initTestBed(){
66 | return Promise.all([
67 | System.import('@angular/core/testing'),
68 | System.import('@angular/platform-browser-dynamic/testing')
69 | ])
70 |
71 | .then(function (providers) {
72 | var coreTesting = providers[0];
73 | var browserTesting = providers[1];
74 |
75 | coreTesting.TestBed.initTestEnvironment(
76 | browserTesting.BrowserDynamicTestingModule,
77 | browserTesting.platformBrowserDynamicTesting());
78 | })
79 | }
80 |
81 | // Import all spec files and start karma
82 | function initTesting () {
83 | return Promise.all(
84 | allSpecFiles.map(function (moduleName) {
85 | return System.import(moduleName);
86 | })
87 | )
88 | .then(__karma__.start, __karma__.error);
89 | }
90 |
--------------------------------------------------------------------------------
/Chapter 06/karma.conf.js:
--------------------------------------------------------------------------------
1 | // #docregion
2 | module.exports = function(config) {
3 |
4 | var appBase = 'app/'; // transpiled app JS and map files
5 | var appSrcBase = 'app/'; // app source TS files
6 | var appAssets = 'base/app/'; // component assets fetched by Angular's compiler
7 |
8 | var testBase = 'spec/unit/'; // transpiled test JS and map files
9 | var testSrcBase = 'spec/unit/'; // test source TS files
10 |
11 | config.set({
12 | basePath: '',
13 | frameworks: ['jasmine'],
14 | plugins: [
15 | require('karma-jasmine'),
16 | require('karma-chrome-launcher'),
17 | require('karma-jasmine-html-reporter'), // click "Debug" in browser to see it
18 | require('karma-htmlfile-reporter') // crashing w/ strange socket error
19 | ],
20 |
21 | customLaunchers: {
22 | // From the CLI. Not used here but interesting
23 | // chrome setup for travis CI using chromium
24 | Chrome_travis_ci: {
25 | base: 'Chrome',
26 | flags: ['--no-sandbox']
27 | }
28 | },
29 | files: [
30 | // System.js for module loading
31 | 'node_modules/systemjs/dist/system.src.js',
32 |
33 | // Polyfills
34 | 'node_modules/core-js/client/shim.js',
35 | 'node_modules/reflect-metadata/Reflect.js',
36 |
37 | // zone.js
38 | 'node_modules/zone.js/dist/zone.js',
39 | 'node_modules/zone.js/dist/long-stack-trace-zone.js',
40 | 'node_modules/zone.js/dist/proxy.js',
41 | 'node_modules/zone.js/dist/sync-test.js',
42 | 'node_modules/zone.js/dist/jasmine-patch.js',
43 | 'node_modules/zone.js/dist/async-test.js',
44 | 'node_modules/zone.js/dist/fake-async-test.js',
45 |
46 | // RxJs
47 | { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
48 | { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
49 |
50 | // Paths loaded via module imports:
51 | // Angular itself
52 | { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
53 | { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
54 |
55 | { pattern: 'systemjs.config.js', included: false, watched: false },
56 | { pattern: 'systemjs.config.extras.js', included: false, watched: false },
57 | 'karma-test-shim.js',
58 |
59 | // transpiled application & spec code paths loaded via module imports
60 | { pattern: appBase + '**/*.js', included: false, watched: true },
61 | { pattern: testBase + '**/*.spec.js', included: false, watched: true },
62 |
63 | // Asset (HTML & CSS) paths loaded via Angular's component compiler
64 | // (these paths need to be rewritten, see proxies section)
65 | //{ pattern: appBase + '**/*.html', included: false, watched: true },
66 | //{ pattern: appBase + '**/*.css', included: false, watched: true },
67 |
68 | // Paths for debugging with source maps in dev tools
69 | { pattern: appSrcBase + '**/*.ts', included: false, watched: false },
70 | { pattern: appBase + '**/*.js.map', included: false, watched: false },
71 | { pattern: testSrcBase + '**/*.ts', included: false, watched: false },
72 | { pattern: testBase + '**/*.js.map', included: false, watched: false }
73 | ],
74 |
75 | // Proxied base paths for loading assets
76 | // proxies: {
77 | // // required for component assets fetched by Angular's compiler
78 | // "/app/": appAssets
79 | // },
80 |
81 | exclude: [],
82 | preprocessors: {},
83 | // disabled HtmlReporter; suddenly crashing w/ strange socket error
84 | reporters: ['progress', 'kjhtml'],//'html'],
85 |
86 | // HtmlReporter configuration
87 | htmlReporter: {
88 | // Open this file to see results in browser
89 | outputFile: '_test-output/tests.html',
90 |
91 | // Optional
92 | pageTitle: 'Unit Tests',
93 | subPageTitle: __dirname
94 | },
95 |
96 | port: 9876,
97 | colors: true,
98 | logLevel: config.LOG_INFO,
99 | autoWatch: true,
100 | browsers: ['Chrome'],
101 | singleRun: true
102 | })
103 | }
104 |
--------------------------------------------------------------------------------
/Chapter 06/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-TDD-chapter-6",
3 | "version": "1.0.0",
4 | "description": "QuickStart package.json from the documentation, supplemented with testing support",
5 | "scripts": {
6 | "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
7 | "docker-build": "docker build -t ng2-quickstart .",
8 | "docker": "npm run docker-build && docker run -it --rm -p 3000:3000 -p 3001:3001 ng2-quickstart",
9 | "pree2e": "npm run webdriver:update",
10 | "e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
11 | "lint": "tslint ./app/**/*.ts -t verbose",
12 | "lite": "lite-server",
13 | "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
14 | "test-once": "tsc && karma start karma.conf.js --single-run",
15 | "tsc": "tsc",
16 | "tsc:w": "tsc -w",
17 | "webdriver:update": "webdriver-manager update"
18 | },
19 | "keywords": [],
20 | "author": "",
21 | "licenses": [
22 | {
23 | "type": "MIT",
24 | "url": "https://github.com/angular/angular.io/blob/master/LICENSE"
25 | }
26 | ],
27 | "dependencies": {
28 | "@angular/common": "~2.2.0",
29 | "@angular/compiler": "~2.2.0",
30 | "@angular/core": "~2.2.0",
31 | "@angular/forms": "~2.2.0",
32 | "@angular/http": "~2.2.0",
33 | "@angular/platform-browser": "~2.2.0",
34 | "@angular/platform-browser-dynamic": "~2.2.0",
35 | "@angular/router": "~3.2.0",
36 | "@angular/upgrade": "~2.2.0",
37 |
38 | "angular-in-memory-web-api": "~0.1.15",
39 | "systemjs": "0.19.40",
40 | "core-js": "^2.4.1",
41 | "reflect-metadata": "^0.1.8",
42 | "rxjs": "5.0.0-beta.12",
43 | "zone.js": "^0.6.26"
44 | },
45 | "devDependencies": {
46 | "concurrently": "^3.1.0",
47 | "lite-server": "^2.2.2",
48 | "typescript": "^2.0.3",
49 |
50 | "canonical-path": "0.0.2",
51 | "http-server": "^0.9.0",
52 | "tslint": "^3.15.1",
53 | "lodash": "^4.16.4",
54 | "jasmine-core": "~2.4.1",
55 | "karma": "^1.3.0",
56 | "karma-chrome-launcher": "^2.0.0",
57 | "karma-cli": "^1.0.1",
58 | "karma-htmlfile-reporter": "^0.3.4",
59 | "karma-jasmine": "^1.0.2",
60 | "karma-jasmine-html-reporter": "^0.2.2",
61 | "protractor": "4.0.14",
62 | "webdriver-manager": "10.2.5",
63 | "rimraf": "^2.5.4",
64 |
65 | "@types/core-js": "^0.9.34",
66 | "@types/node": "^6.0.46",
67 | "@types/jasmine": "^2.5.36",
68 | "@types/selenium-webdriver": "^2.53.33"
69 | },
70 | "repository": {}
71 | }
72 |
--------------------------------------------------------------------------------
/Chapter 06/spec/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | describe('Given I am posting a new comment', () => {
4 | describe('When I push the submit button', () => {
5 | beforeEach(() => {
6 | //Assemble
7 | browser.get('');
8 | var commentInput = element(by.css('input'));
9 | commentInput.sendKeys('a sample comment');
10 | //Act
11 | var submitButton = element(by.buttonText('Submit')).click();
12 | });
13 |
14 | //Assert
15 | it('Should then add the comment', () => {
16 | var comment = element.all(by.css('li')).first();
17 | expect(comment.getText()).toBe('a sample comment like 0');
18 | });
19 | });
20 |
21 | describe('When I like a comment', () => {
22 | var firstComment = null;
23 |
24 | beforeEach(() => {
25 | browser.get('');
26 |
27 | //Assemble
28 | firstComment = element.all(by.css('li')).first();
29 | var likeButton = firstComment.element(by.buttonText('like'));
30 |
31 | //Act
32 | likeButton.click();
33 | });
34 |
35 | //Assert
36 | it('Should increase the number of likes to one', () => {
37 | var commentLikes = firstComment.element(by.css('#likes'));
38 | expect(commentLikes.getText()).toEqual('1');
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/Chapter 06/spec/unit/app.component.spec.ts:
--------------------------------------------------------------------------------
1 |
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { By } from '@angular/platform-browser';
4 | import { DebugElement } from '@angular/core';
5 | import { FormsModule } from '@angular/forms';
6 |
7 | import { AppComponent } from '../../app/app.component';
8 |
9 | describe('AppComponent', function () {
10 | let comp: AppComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async(() => {
14 | TestBed.configureTestingModule({
15 | imports: [ FormsModule ],
16 | declarations: [ AppComponent ]
17 | })
18 | .compileComponents();
19 | }));
20 |
21 | beforeEach(() => {
22 | fixture = TestBed.createComponent(AppComponent);
23 | comp = fixture.componentInstance;
24 |
25 | comp.add('a sample comment');
26 | comp.like(comp.comments[0]);
27 | });
28 |
29 | it('should create component', () => {
30 | expect(comp).toBeDefined();
31 | });
32 |
33 | it('First item in the item should match', () => {
34 | expect(comp.comments[0].title).toBe('a sample comment');
35 | });
36 |
37 | it('Number of likes should increase on like', () => {
38 | expect(comp.comments[0].likes).toEqual(1);
39 | });
40 |
41 | });
42 |
--------------------------------------------------------------------------------
/Chapter 06/styles.css:
--------------------------------------------------------------------------------
1 | /* Master Styles */
2 | h1 {
3 | color: #369;
4 | font-family: Arial, Helvetica, sans-serif;
5 | font-size: 250%;
6 | }
7 | h2, h3 {
8 | color: #444;
9 | font-family: Arial, Helvetica, sans-serif;
10 | font-weight: lighter;
11 | }
12 | body {
13 | margin: 2em;
14 | }
15 | body, input[text], button {
16 | color: #888;
17 | font-family: Cambria, Georgia;
18 | }
19 | a {
20 | cursor: pointer;
21 | cursor: hand;
22 | }
23 | button {
24 | font-family: Arial;
25 | background-color: #eee;
26 | border: none;
27 | padding: 5px 10px;
28 | border-radius: 4px;
29 | cursor: pointer;
30 | cursor: hand;
31 | }
32 | button:hover {
33 | background-color: #cfd8dc;
34 | }
35 | button:disabled {
36 | background-color: #eee;
37 | color: #aaa;
38 | cursor: auto;
39 | }
40 |
41 | /* Navigation link styles */
42 | nav a {
43 | padding: 5px 10px;
44 | text-decoration: none;
45 | margin-top: 10px;
46 | display: inline-block;
47 | background-color: #eee;
48 | border-radius: 4px;
49 | }
50 | nav a:visited, a:link {
51 | color: #607D8B;
52 | }
53 | nav a:hover {
54 | color: #039be5;
55 | background-color: #CFD8DC;
56 | }
57 | nav a.router-link-active {
58 | color: #039be5;
59 | }
60 |
61 | /* items class */
62 | .items {
63 | margin: 0 0 2em 0;
64 | list-style-type: none;
65 | padding: 0;
66 | width: 24em;
67 | }
68 | .items li {
69 | cursor: pointer;
70 | position: relative;
71 | left: 0;
72 | background-color: #EEE;
73 | margin: .5em;
74 | padding: .3em 0;
75 | height: 1.6em;
76 | border-radius: 4px;
77 | }
78 | .items li:hover {
79 | color: #607D8B;
80 | background-color: #DDD;
81 | left: .1em;
82 | }
83 | .items li.selected:hover {
84 | background-color: #BBD8DC;
85 | color: white;
86 | }
87 | .items .text {
88 | position: relative;
89 | top: -3px;
90 | }
91 | .items {
92 | margin: 0 0 2em 0;
93 | list-style-type: none;
94 | padding: 0;
95 | width: 24em;
96 | }
97 | .items li {
98 | cursor: pointer;
99 | position: relative;
100 | left: 0;
101 | background-color: #EEE;
102 | margin: .5em;
103 | padding: .3em 0;
104 | height: 1.6em;
105 | border-radius: 4px;
106 | }
107 | .items li:hover {
108 | color: #607D8B;
109 | background-color: #DDD;
110 | left: .1em;
111 | }
112 | .items li.selected {
113 | background-color: #CFD8DC;
114 | color: white;
115 | }
116 |
117 | .items li.selected:hover {
118 | background-color: #BBD8DC;
119 | }
120 | .items .text {
121 | position: relative;
122 | top: -3px;
123 | }
124 | .items .badge {
125 | display: inline-block;
126 | font-size: small;
127 | color: white;
128 | padding: 0.8em 0.7em 0 0.7em;
129 | background-color: #607D8B;
130 | line-height: 1em;
131 | position: relative;
132 | left: -1px;
133 | top: -4px;
134 | height: 1.8em;
135 | margin-right: .8em;
136 | border-radius: 4px 0 0 4px;
137 | }
138 |
139 | /* everywhere else */
140 | * {
141 | font-family: Arial, Helvetica, sans-serif;
142 | }
143 |
--------------------------------------------------------------------------------
/Chapter 06/systemjs.config.extras.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Add barrels and stuff
3 | * Adjust as necessary for your application needs.
4 | */
5 | // (function (global) {
6 | // System.config({
7 | // packages: {
8 | // // add packages here
9 | // }
10 | // });
11 | // })(this);
12 |
--------------------------------------------------------------------------------
/Chapter 06/systemjs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function (global) {
6 | System.config({
7 | paths: {
8 | // paths serve as alias
9 | 'npm:': 'node_modules/'
10 | },
11 | // map tells the System loader where to look for things
12 | map: {
13 | // our app is within the app folder
14 | app: 'app',
15 |
16 | // angular bundles
17 | '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
18 | '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
19 | '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
20 | '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
21 | '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
22 | '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
23 | '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
24 | '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
25 | '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
26 | '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
27 | '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
28 |
29 | // other libraries
30 | 'rxjs': 'npm:rxjs',
31 | 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
32 | },
33 | // packages tells the System loader how to load when no filename and/or no extension
34 | packages: {
35 | app: {
36 | main: './main.js',
37 | defaultExtension: 'js'
38 | },
39 | rxjs: {
40 | defaultExtension: 'js'
41 | }
42 | }
43 | });
44 | })(this);
45 |
--------------------------------------------------------------------------------
/Chapter 06/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "removeComments": false,
10 | "noImplicitAny": false,
11 | "suppressImplicitAnyIndexErrors": true,
12 | "typeRoots": [
13 | "./node_modules/@types/"
14 | ]
15 | },
16 | "compileOnSave": true,
17 | "exclude": [
18 | "node_modules/*",
19 | "**/*-aot.ts"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/Chapter 06/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "class-name": true,
4 | "comment-format": [
5 | true,
6 | "check-space"
7 | ],
8 | "curly": true,
9 | "eofline": true,
10 | "forin": true,
11 | "indent": [
12 | true,
13 | "spaces"
14 | ],
15 | "label-position": true,
16 | "label-undefined": true,
17 | "max-line-length": [
18 | true,
19 | 140
20 | ],
21 | "member-access": false,
22 | "member-ordering": [
23 | true,
24 | "static-before-instance",
25 | "variables-before-functions"
26 | ],
27 | "no-arg": true,
28 | "no-bitwise": true,
29 | "no-console": [
30 | true,
31 | "debug",
32 | "info",
33 | "time",
34 | "timeEnd",
35 | "trace"
36 | ],
37 | "no-construct": true,
38 | "no-debugger": true,
39 | "no-duplicate-key": true,
40 | "no-duplicate-variable": true,
41 | "no-empty": false,
42 | "no-eval": true,
43 | "no-inferrable-types": true,
44 | "no-shadowed-variable": true,
45 | "no-string-literal": false,
46 | "no-switch-case-fall-through": true,
47 | "no-trailing-whitespace": true,
48 | "no-unused-expression": true,
49 | "no-unused-variable": true,
50 | "no-unreachable": true,
51 | "no-use-before-declare": true,
52 | "no-var-keyword": true,
53 | "object-literal-sort-keys": false,
54 | "one-line": [
55 | true,
56 | "check-open-brace",
57 | "check-catch",
58 | "check-else",
59 | "check-whitespace"
60 | ],
61 | "quotemark": [
62 | true,
63 | "single"
64 | ],
65 | "radix": true,
66 | "semicolon": [
67 | "always"
68 | ],
69 | "triple-equals": [
70 | true,
71 | "allow-null-check"
72 | ],
73 | "typedef-whitespace": [
74 | true,
75 | {
76 | "call-signature": "nospace",
77 | "index-signature": "nospace",
78 | "parameter": "nospace",
79 | "property-declaration": "nospace",
80 | "variable-declaration": "nospace"
81 | }
82 | ],
83 | "variable-name": false,
84 | "whitespace": [
85 | true,
86 | "check-branch",
87 | "check-decl",
88 | "check-operator",
89 | "check-separator",
90 | "check-type"
91 | ]
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Chapter 06/wallaby.js:
--------------------------------------------------------------------------------
1 | // Configuration for the Wallaby Visual Studio Code testing extension
2 | // https://marketplace.visualstudio.com/items?itemName=WallabyJs.wallaby-vscode
3 | // Note: Wallaby is not open source and costs money
4 |
5 | module.exports = function () {
6 | return {
7 | files: [
8 | // System.js for module loading
9 | {pattern: 'node_modules/systemjs/dist/system.js', instrument: false},
10 | {pattern: 'systemjs.config.js', instrument: false},
11 | {pattern: 'systemjs.config.extras.js', instrument: false},
12 |
13 | // Polyfills
14 | {pattern: 'node_modules/core-js/client/shim.min.js', instrument: false},
15 | {pattern: 'node_modules/reflect-metadata/Reflect.js', instrument: false},
16 |
17 | // zone.js
18 | {pattern: 'node_modules/zone.js/dist/zone.js', instrument: false},
19 | {pattern: 'node_modules/zone.js/dist/long-stack-trace-zone.js', instrument: false},
20 | {pattern: 'node_modules/zone.js/dist/proxy.js', instrument: false},
21 | {pattern: 'node_modules/zone.js/dist/sync-test.js', instrument: false},
22 | {pattern: 'node_modules/zone.js/dist/jasmine-patch.js', instrument: false},
23 | {pattern: 'node_modules/zone.js/dist/async-test.js', instrument: false},
24 | {pattern: 'node_modules/zone.js/dist/fake-async-test.js', instrument: false},
25 |
26 | // application (but not specs) loaded via module imports
27 | {pattern: 'app/**/*+(ts|html|css)', load: false},
28 | {pattern: 'app/**/*.spec.ts', ignore: true},
29 |
30 | {pattern: 'testing/**/*+(ts|html|css)', load: false},
31 | ],
32 |
33 | tests: [
34 | {pattern: 'app/**/*.spec.ts', load: false}
35 | ],
36 |
37 | middleware: function (app, express) {
38 | app.use('/node_modules', express.static(require('path').join(__dirname, 'node_modules')));
39 | },
40 |
41 | testFramework: 'jasmine',
42 |
43 | debug: true,
44 |
45 | bootstrap: bootstrap
46 | };
47 | };
48 |
49 | // Like karma-test-shim.js
50 | function bootstrap (wallaby) {
51 | wallaby.delayStart();
52 |
53 | System.config({
54 | // Extend usual application package list with test folder
55 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
56 |
57 | // Assume npm: is set in `paths` in systemjs.config
58 | // Map the angular testing umd bundles
59 | map: {
60 | '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
61 | '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
62 | '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
63 | '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
64 | '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
65 | '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
66 | '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
67 | '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
68 | },
69 | });
70 |
71 | System.import('systemjs.config.js')
72 | .then(importSystemJsExtras)
73 | .then(initTestBed)
74 | .then(initTesting);
75 |
76 | /** Optional SystemJS configuration extras. Keep going w/o it */
77 | function importSystemJsExtras(){
78 | return System.import('systemjs.config.extras.js')
79 | .catch(function(reason) {
80 | console.log(
81 | 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
82 | );
83 | console.log(reason);
84 | });
85 | }
86 |
87 | function initTestBed(){
88 | return Promise.all([
89 | System.import('@angular/core/testing'),
90 | System.import('@angular/platform-browser-dynamic/testing')
91 | ])
92 |
93 | .then(function (providers) {
94 | var coreTesting = providers[0];
95 | var browserTesting = providers[1];
96 |
97 | coreTesting.TestBed.initTestEnvironment(
98 | browserTesting.BrowserDynamicTestingModule,
99 | browserTesting.platformBrowserDynamicTesting());
100 | })
101 | }
102 |
103 | // Load all spec files and start wallaby
104 | function initTesting () {
105 | return Promise.all(
106 | wallaby.tests.map(function (specFile) {
107 | return System.import(specFile);
108 | })
109 | )
110 | .then(function () {
111 | wallaby.start();
112 | })
113 | .catch(function (e) {
114 | setTimeout(function () {
115 | throw e;
116 | }, 0);
117 | });
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/Chapter 07/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
16 | # Indentation override
17 | #[lib/**.js]
18 | #[{package.json,.travis.yml}]
19 | #[**/**.js]
20 |
--------------------------------------------------------------------------------
/Chapter 07/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | node_modules
4 | jspm_packages
5 | npm-debug.*
6 | link-checker-results.txt
7 | app/**/*.js
8 | *.js.map
9 | spec/e2e/**/*.js
10 | spec/e2e/**/*.js.map
11 | spec/unit/**/*.js
12 | spec/unit/**/*.js.map
13 | _test-output
14 | _temp
15 |
--------------------------------------------------------------------------------
/Chapter 07/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | sudo: required
3 | language: node_js
4 | node_js:
5 | - "5"
6 | os:
7 | - linux
8 | env:
9 | global:
10 | - DBUS_SESSION_BUS_ADDRESS=/dev/null
11 | - DISPLAY=:99.0
12 | - CHROME_BIN=chromium-browser
13 | before_script:
14 | - sh -e /etc/init.d/xvfb start
15 | install:
16 | - npm install
17 | script:
18 | - npm run lint
19 | - npm run test-once
20 | - npm run e2e
21 |
--------------------------------------------------------------------------------
/Chapter 07/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Angular Documentation QuickStart Changelog
2 | Upgraders: for a fresh start, consider running these commands
3 | * `git clean -xdf`
4 | * `npm install`
5 |
6 |
7 | # 0.2.19 (2016-11-30)
8 | * remove upgrade mappings from `systemjs.config.js` PR #301
9 |
10 |
11 | # 0.2.18 (2016-11-30)
12 | * remove `exclude` clause from `tsconfig.json`; it was just confusing people
13 | * karma.config + karma-test-shim can handle multiple spec source paths (issue #294)
14 | * cosmetic `app.component.spec.ts` changes
15 | * cosmetic `karma.config.js` changes
16 |
17 |
18 | # 0.2.17 (2016-11-16)
19 | * Conform to updated QuickStart advice
20 | * removed docker everywhere (was nice but not necessary)
21 | * removed wallaby
22 | * shrink styles.css
23 | * refine tsconfig.json
24 | * `AppComponent` uses interpolation
25 |
26 |
27 | # 0.2.16 (2016-11-14)
28 | * Update to Angular 2.2.0
29 |
30 |
31 | # 0.2.15 (2016-10-29)
32 | * Revert to Jasmine 2.4.1 because bug in 2.5.x (see [jasmine issue #1231](https://github.com/jasmine/jasmine/issues/1231))
33 |
34 |
35 | # 0.2.14 (2016-10-29)
36 | * Remove bootstrap.css install
37 | * Angular v2.1.2
38 |
39 |
40 | # 0.2.13 (2016-10-20)
41 | * Protractor 4
42 | * Move from `typings` to `@types`. See `tsconfig.json` changes.
43 | * Angular v2.1.1
44 |
45 |
46 | # 0.2.12 (2016-10-06)
47 | * Angular v2.1.0
48 |
49 |
50 | # 0.2.11 (2016-10-06)
51 | * Angular v2.0.2
52 | * License is MIT
53 | * Current testing configuration
54 | * No code changes
55 |
56 |
57 | # 0.2.10 (2016-09-19)
58 | * All "Angular 2" references become just "Angular"
59 | * No code changes
60 |
61 |
62 | # 0.2.9 (2016-09-14)
63 | * Angular 2.0.0 version
64 | * Update to Typescript 2.0.2
65 | * Fix e2e test missing dir
66 |
67 |
68 | # 0.2.8 (2016-09-01)
69 | * remove @angular test libraries from system.js (now in shim)
70 | * update test related files
71 | * wallaby doesn't completely work. Researching.
72 |
73 |
74 | # 0.2.7 (2016-08-31)
75 | * Angular 2 RC6 version
76 | * Updated new forms, router, angular2-in-memory-web-api, karma, core-js, rxjs and zone.js packages
77 | * Removed router-deprecated package
78 | * Updated karma.conf.js and systemjs.config.js
79 |
80 |
81 | # 0.2.6 (2016-08-09)
82 | * Angular 2 RC5 version
83 | * Updated new forms, router and angular2-in-memory-web-api
84 |
85 |
86 | # 0.2.5 (2016-06-30)
87 | * Angular 2 RC4 version
88 | * Updated new forms and router
89 |
90 |
91 | # 0.2.4 (2016-06-21)
92 | * Angular 2 RC3 version
93 | * Add new forms and router
94 | * Add support for TS e2e tests
95 |
96 |
97 | # 0.2.3 (2016-06-15)
98 | * Angular 2 RC2 version
99 |
100 |
101 | # 0.2.2 (2016-05-21)
102 | * Update to Typings 1.x
103 |
104 |
105 | # 0.2.1 (2016-05-03)
106 | * Angular 2 RC01 version
107 |
108 |
109 | # 0.2.0 (2016-05-02)
110 | * Angular 2 RC0 version
111 |
112 |
113 | # 0.1.17 (2016-04-29)
114 | * update packages
115 | * Angular 2 beta 17
116 | * RxJS 5.0.0-beta.6
117 | * a2-in-memory-web-api 0.1.17
118 |
119 |
120 | # 0.1.16 (2016-04-26)
121 | * update packages
122 | * Angular 2 beta 16
123 | * a2-in-memory-web-api 0.1.6
124 | * protractor 3.3.0
125 | * typings 0.8.1
126 | * zone.js 0.6.12
127 |
128 | * added favicon.ico
129 |
130 | * testing
131 | - updated wallaby.js and karma.conf.js
132 | - updated app.component.spec.ts
133 |
134 |
135 |
136 | # 0.1.15 (2016-04-13)
137 | * Add testing support
138 | * npm scripts
139 | * karma/jasmine
140 | * protractor
141 |
142 | * update packages
143 | * Angular 2 beta 15
144 | * lite-server 2.2.0
145 | * systemjs 0.19.26
146 | * typescript 1.8.10
147 | * typings 0.7.12
148 |
149 | * add run packages
150 | * a2-in-memory-web-api
151 |
152 | * add testing dev-dependency packages
153 | * canonical-path: 0.0.2,
154 | * http-server: ^0.9.0,
155 | * jasmine-core: ~2.4.1,
156 | * karma: ^0.13.22,
157 | * karma-chrome-launcher: ^0.2.3,
158 | * karma-cli: ^0.1.2,
159 | * karma-htmlfile-reporter: ^0.2.2,
160 | * karma-jasmine: ^0.3.8,
161 | * protractor: ^3.2.2,
162 | * rimraf: ^2.5.2
163 |
164 |
165 | # 0.1.14 (2016-04-07)
166 | * update packages
167 | * Angular 2 beta 14
168 | * lite-server 2.2.0
169 | * typings 0.7.12
170 |
171 |
172 | # 0.1.13 (2016-03-31)
173 | * update packages
174 | * Angular 2 beta 13
175 |
176 |
177 | # 0.1.12 (2016-03-23)
178 | * update packages
179 | * Angular 2 beta 12
180 | * zones 0.6.6
181 | * remove es6-promise because no longer needed.
182 |
183 |
184 | # 0.1.11 (2016-03-18)
185 | * update packages
186 | * Angular 2 beta 11
187 | * zones 0.6.4
188 | * typescript 1.8.9
189 | * typings 0.7.9
190 |
--------------------------------------------------------------------------------
/Chapter 07/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2016 Google, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Chapter 07/app/app.component.html:
--------------------------------------------------------------------------------
1 | My First Angular 2 App
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Chapter 07/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | moduleId: module.id,
5 | selector: 'my-app',
6 | templateUrl: 'app.component.html'
7 | })
8 | export class AppComponent {
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/Chapter 07/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import {NgModule} from '@angular/core'
2 | import {BrowserModule} from "@angular/platform-browser";
3 | import {RouterModule} from "@angular/router";
4 | import {FormsModule} from "@angular/forms";
5 | import {HttpModule} from "@angular/http";
6 |
7 |
8 | import {rootRouterConfig} from "./app.routes";
9 | import {AppComponent} from "./app.component";
10 | import {NavbarComponent} from './nav/navbar.component';
11 | import {View1Component} from './view/view1.component';
12 | import {View2Component} from './view/view2.component';
13 | import {MembersComponent} from './members/members.component';
14 | import {PersonComponent} from './members/person/person.component';
15 |
16 | @NgModule({
17 | declarations: [AppComponent, NavbarComponent, View1Component, View2Component, MembersComponent, PersonComponent],
18 | imports : [BrowserModule, FormsModule, HttpModule, RouterModule.forRoot(rootRouterConfig)],
19 | bootstrap : [AppComponent]
20 | })
21 | export class AppModule {
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/Chapter 07/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import {Routes} from '@angular/router';
2 | import {View1Component} from './view/view1.component';
3 | import {View2Component} from './view/view2.component';
4 | import {MembersComponent} from './members/members.component';
5 | import {PersonComponent} from './members/person/person.component';
6 |
7 |
8 | export const rootRouterConfig: Routes = [
9 | {path: '', redirectTo: 'view1', pathMatch: 'full'},
10 | {path: 'view1', component: View1Component},
11 | {path: 'view2', component: View2Component},
12 | {path: 'members', component: MembersComponent},
13 | {path: 'person/:id', component: PersonComponent}
14 | ];
15 |
--------------------------------------------------------------------------------
/Chapter 07/app/data/people.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "name": "Peyton Manning",
5 | "phone": "(303) 567-8910",
6 | "address": {
7 | "street": "1234 Main Street",
8 | "city": "Greenwood Village",
9 | "state": "CO",
10 | "zip": "80111"
11 | }
12 | },
13 | {
14 | "id": 2,
15 | "name": "Demaryius Thomas",
16 | "phone": "(720) 213-9876",
17 | "address": {
18 | "street": "5555 Marion Street",
19 | "city": "Denver",
20 | "state": "CO",
21 | "zip": "80202"
22 | }
23 | },
24 | {
25 | "id": 3,
26 | "name": "Von Miller",
27 | "phone": "(917) 323-2333",
28 | "address": {
29 | "street": "14 Mountain Way",
30 | "city": "Vail",
31 | "state": "CO",
32 | "zip": "81657"
33 | }
34 | }
35 | ]
36 |
--------------------------------------------------------------------------------
/Chapter 07/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 | import { AppModule } from './app.module';
3 |
4 | platformBrowserDynamic().bootstrapModule(AppModule);
5 |
--------------------------------------------------------------------------------
/Chapter 07/app/members/members.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | padding: 0 16px;
4 | }
5 |
6 | table {
7 | margin-top: 10px;
8 | border-collapse: collapse;
9 | }
10 |
11 | th {
12 | text-align: left;
13 | border-bottom: 2px solid #ddd;
14 | padding: 8px;
15 | }
16 |
17 | td {
18 | border-top: 1px solid #ddd;
19 | padding: 8px;
20 | }
21 |
--------------------------------------------------------------------------------
/Chapter 07/app/members/members.component.html:
--------------------------------------------------------------------------------
1 | Members
2 |
3 |
7 |
8 |
9 |
10 |
11 | Name |
12 | Phone |
13 |
14 |
15 |
16 |
17 | {{member.name}} |
18 | {{member.phone}} |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Chapter 07/app/members/members.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Http, Response } from '@angular/http';
3 | import { Router } from '@angular/router';
4 |
5 | import 'rxjs/add/operator/toPromise';
6 | import { Person } from './person/person.component';
7 |
8 | @Component({
9 | selector: 'app-member',
10 | moduleId: module.id,
11 | templateUrl: 'members.component.html',
12 | styleUrls: ['members.component.css']
13 | })
14 | export class MembersComponent implements OnInit {
15 | memberList: Array = [];
16 | query: string;
17 |
18 | constructor(private http:Http, private router:Router) {
19 |
20 | }
21 |
22 | ngOnInit() {
23 | //this.getMembers();
24 | this.search();
25 | }
26 |
27 | viewDetails(id:number) {
28 | this.router.navigate(['/person', id]);
29 | }
30 |
31 | getMembers() {
32 | this.getData()
33 | .then(data => {
34 | data.map(item => {
35 | this.memberList.push(item);
36 | });
37 | })
38 | return this.memberList;
39 | }
40 |
41 | getData() {
42 | return this.http.get('app/data/people.json')
43 | .toPromise()
44 | .then(response => response.json());
45 | }
46 |
47 | search(): void {
48 | this.searchQuery(this.query)
49 | .then(results => this.memberList = results);
50 | }
51 |
52 | searchQuery(q:string) {
53 | if (!q || q === '*') {
54 | q = '';
55 | } else {
56 | q = q.toLowerCase();
57 | }
58 | return this.getData()
59 | .then(data => {
60 | let results:Array = [];
61 | data.map(item => {
62 | if (JSON.stringify(item).toLowerCase().includes(q)) {
63 | results.push(item);
64 | }
65 | });
66 | return results;
67 | });
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Chapter 07/app/members/person/person.component.html:
--------------------------------------------------------------------------------
1 | Member Details
2 |
3 |
4 |
5 |
6 | Name : |
7 | {{person.name}} |
8 |
9 |
10 | Phone: |
11 | {{person.phone}} |
12 |
13 |
14 | Street: |
15 | {{person.address.street}} |
16 |
17 |
18 | City: |
19 | {{person.address.city}} |
20 |
21 |
22 | State: |
23 | {{person.address.state}} |
24 |
25 |
26 | Zip: |
27 | {{person.address.zip}} |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Chapter 07/app/members/person/person.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Http, Response } from '@angular/http';
3 | import { Router, ActivatedRoute, Params } from '@angular/router';
4 | import 'rxjs/add/operator/toPromise';
5 |
6 | @Component({
7 | selector: 'app-person',
8 | moduleId: module.id,
9 | templateUrl: 'person.component.html',
10 | styleUrls: ['../members.component.css']
11 | })
12 | export class PersonComponent implements OnInit {
13 | person: Person;
14 | constructor(private http:Http, private route: ActivatedRoute, private router: Router) {
15 |
16 | }
17 |
18 | ngOnInit() {
19 | this.route.params.forEach((params: Params) => {
20 | let id = +params['id'];
21 | this.getPerson(id).then(person => {
22 | this.person = person;
23 | });
24 | });
25 | }
26 |
27 | getPerson(id:number) {
28 | return this.getData().then(data => data.find(member => member.id === id));
29 | }
30 |
31 | getData() {
32 | return this.http.get('app/data/people.json')
33 | .toPromise()
34 | .then(response => response.json());
35 | }
36 |
37 | }
38 |
39 | export class Person {
40 | id:number;
41 | name:string;
42 | phone:string;
43 | address:Address;
44 |
45 | constructor(obj?:any) {
46 | this.id = obj && Number(obj.id) || null;
47 | this.name = obj && obj.name || null;
48 | this.phone = obj && obj.phone || null;
49 | this.address = obj && obj.address || null;
50 | }
51 | }
52 |
53 | export class Address {
54 | street:string;
55 | city:string;
56 | state:string;
57 | zip:string;
58 |
59 | constructor(obj?:any) {
60 | this.street = obj && obj.street || null;
61 | this.city = obj && obj.city || null;
62 | this.state = obj && obj.state || null;
63 | this.zip = obj && obj.zip || null;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Chapter 07/app/nav/navbar.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | border-color: #e1e1e1;
3 | border-style: solid;
4 | border-width: 0 0 1px;
5 | display: block;
6 | height: 48px;
7 | padding: 0 16px;
8 | }
9 |
10 | nav a {
11 | color: #8f8f8f;
12 | font-size: 14px;
13 | font-weight: 500;
14 | margin-right: 20px;
15 | text-decoration: none;
16 | vertical-align: middle;
17 | }
18 |
19 | nav a.router-link-active {
20 | color: #106cc8;
21 | }
22 |
--------------------------------------------------------------------------------
/Chapter 07/app/nav/navbar.component.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/Chapter 07/app/nav/navbar.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-navbar',
5 | moduleId: module.id,
6 | templateUrl: 'navbar.component.html',
7 | styleUrls: ['navbar.component.css']
8 | })
9 | export class NavbarComponent {}
10 |
--------------------------------------------------------------------------------
/Chapter 07/app/view/view1.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-view1',
5 | template: 'I am view one component
'
6 | })
7 | export class View1Component {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/Chapter 07/app/view/view2.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-view2',
5 | template: 'I am view two component
'
6 | })
7 | export class View2Component {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/Chapter 07/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Angular-Test-Driven-Development-Second-Edition/306153dc7400dd7c063d3494d17d5d14e3c1c41a/Chapter 07/favicon.ico
--------------------------------------------------------------------------------
/Chapter 07/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular 2 QuickStart
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | Loading AppComponent content here ...
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 07/karma-test-shim.js:
--------------------------------------------------------------------------------
1 | // /*global jasmine, __karma__, window*/
2 | Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
3 |
4 | // Uncomment to get full stacktrace output. Sometimes helpful, usually not.
5 | // Error.stackTraceLimit = Infinity; //
6 |
7 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
8 |
9 | // builtPaths: root paths for output ("built") files
10 | // get from karma.config.js, then prefix with '/base/' (default is 'app/')
11 | var builtPaths = (__karma__.config.builtPaths || ['app/'])
12 | .map(function(p) { return '/base/'+p;});
13 |
14 | __karma__.loaded = function () { };
15 |
16 | function isJsFile(path) {
17 | return path.slice(-3) == '.js';
18 | }
19 |
20 | function isSpecFile(path) {
21 | return /\.spec\.(.*\.)?js$/.test(path);
22 | }
23 |
24 | // Is a "built" file if is JavaScript file in one of the "built" folders
25 | function isBuiltFile(path) {
26 | return isJsFile(path) &&
27 | builtPaths.reduce(function(keep, bp) {
28 | return keep || (path.substr(0, bp.length) === bp);
29 | }, false);
30 | }
31 |
32 | var allSpecFiles = Object.keys(window.__karma__.files)
33 | .filter(isSpecFile)
34 | .filter(isBuiltFile);
35 |
36 | System.config({
37 | baseURL: 'base',
38 | // Extend usual application package list with test folder
39 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
40 |
41 | // Assume npm: is set in `paths` in systemjs.config
42 | // Map the angular testing umd bundles
43 | map: {
44 | '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
45 | '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
46 | '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
47 | '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
48 | '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
49 | '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
50 | '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
51 | '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
52 | },
53 | });
54 |
55 | System.import('systemjs.config.js')
56 | .then(importSystemJsExtras)
57 | .then(initTestBed)
58 | .then(initTesting);
59 |
60 | /** Optional SystemJS configuration extras. Keep going w/o it */
61 | function importSystemJsExtras(){
62 | return System.import('systemjs.config.extras.js')
63 | .catch(function(reason) {
64 | console.log(
65 | 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
66 | );
67 | console.log(reason);
68 | });
69 | }
70 |
71 | function initTestBed(){
72 | return Promise.all([
73 | System.import('@angular/core/testing'),
74 | System.import('@angular/platform-browser-dynamic/testing')
75 | ])
76 |
77 | .then(function (providers) {
78 | var coreTesting = providers[0];
79 | var browserTesting = providers[1];
80 |
81 | coreTesting.TestBed.initTestEnvironment(
82 | browserTesting.BrowserDynamicTestingModule,
83 | browserTesting.platformBrowserDynamicTesting());
84 | })
85 | }
86 |
87 | // Import all spec files and start karma
88 | function initTesting () {
89 | return Promise.all(
90 | allSpecFiles.map(function (moduleName) {
91 | return System.import(moduleName);
92 | })
93 | )
94 | .then(__karma__.start, __karma__.error);
95 | }
96 |
--------------------------------------------------------------------------------
/Chapter 07/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 |
3 | var appBase = 'app/'; // transpiled app JS and map files
4 | var appSrcBase = 'app/'; // app source TS files
5 | var appAssets = 'base/app/'; // component assets fetched by Angular's compiler
6 |
7 | var testBase = 'spec/unit/'; // transpiled test JS and map files
8 | var testSrcBase = 'spec/unit/'; // test source TS files
9 |
10 | config.set({
11 | basePath: '',
12 | frameworks: ['jasmine'],
13 |
14 | plugins: [
15 | require('karma-jasmine'),
16 | require('karma-chrome-launcher'),
17 | require('karma-phantomjs-launcher'),
18 | require('karma-jasmine-html-reporter') // click "Debug" in browser to see it
19 | ],
20 |
21 | client: {
22 | builtPaths: [appBase, testBase], // add more spec base paths as needed
23 | clearContext: false // leave Jasmine Spec Runner output visible in browser
24 | },
25 |
26 | customLaunchers: {
27 | // From the CLI. Not used here but interesting
28 | // chrome setup for travis CI using chromium
29 | Chrome_travis_ci: {
30 | base: 'Chrome',
31 | flags: ['--no-sandbox']
32 | }
33 | },
34 |
35 | files: [
36 | // System.js for module loading
37 | 'node_modules/systemjs/dist/system.src.js',
38 |
39 | // Polyfills
40 | 'node_modules/core-js/client/shim.js',
41 | 'node_modules/reflect-metadata/Reflect.js',
42 |
43 | // zone.js
44 | 'node_modules/zone.js/dist/zone.js',
45 | 'node_modules/zone.js/dist/long-stack-trace-zone.js',
46 | 'node_modules/zone.js/dist/proxy.js',
47 | 'node_modules/zone.js/dist/sync-test.js',
48 | 'node_modules/zone.js/dist/jasmine-patch.js',
49 | 'node_modules/zone.js/dist/async-test.js',
50 | 'node_modules/zone.js/dist/fake-async-test.js',
51 |
52 | // RxJs
53 | { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
54 | { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
55 |
56 | // Paths loaded via module imports:
57 | // Angular itself
58 | { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
59 | { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
60 |
61 | { pattern: 'systemjs.config.js', included: false, watched: false },
62 | { pattern: 'systemjs.config.extras.js', included: false, watched: false },
63 | 'karma-test-shim.js', // optionally extend SystemJS mapping e.g., with barrels
64 |
65 | // transpiled application & spec code paths loaded via module imports
66 | { pattern: appBase + '**/*.js', included: false, watched: true },
67 | { pattern: testBase + '**/*.js', included: false, watched: true },
68 |
69 |
70 | // Asset (HTML & CSS) paths loaded via Angular's component compiler
71 | // (these paths need to be rewritten, see proxies section)
72 | { pattern: appBase + '**/*.html', included: false, watched: true },
73 | { pattern: appBase + '**/*.css', included: false, watched: true },
74 |
75 | // Paths for debugging with source maps in dev tools
76 | { pattern: appSrcBase + '**/*.ts', included: false, watched: false },
77 | { pattern: appBase + '**/*.js.map', included: false, watched: false },
78 | { pattern: testSrcBase + '**/*.ts', included: false, watched: false },
79 | { pattern: testBase + '**/*.js.map', included: false, watched: false}
80 | ],
81 |
82 | // Proxied base paths for loading assets
83 | proxies: {
84 | // required for component assets fetched by Angular's compiler
85 | "/app/": appAssets
86 | },
87 |
88 | exclude: [],
89 | preprocessors: {},
90 | reporters: ['progress', 'kjhtml'],
91 |
92 | port: 9876,
93 | colors: true,
94 | logLevel: config.LOG_INFO,
95 | autoWatch: true,
96 | browsers: ['Chrome'],
97 | singleRun: false
98 | })
99 | }
100 |
--------------------------------------------------------------------------------
/Chapter 07/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-TDD-chapter-7",
3 | "version": "1.0.0",
4 | "description": "QuickStart package.json from the documentation, supplemented with testing support",
5 | "scripts": {
6 | "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
7 | "e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
8 | "lint": "tslint ./app/**/*.ts -t verbose",
9 | "lite": "lite-server",
10 | "pree2e": "webdriver-manager update",
11 | "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
12 | "test-once": "tsc && karma start karma.conf.js --single-run",
13 | "tsc": "tsc",
14 | "tsc:w": "tsc -w"
15 | },
16 | "keywords": [],
17 | "author": "",
18 | "license": "MIT",
19 | "dependencies": {
20 | "@angular/common": "~2.2.0",
21 | "@angular/compiler": "~2.2.0",
22 | "@angular/core": "~2.2.0",
23 | "@angular/forms": "~2.2.0",
24 | "@angular/http": "~2.2.0",
25 | "@angular/platform-browser": "~2.2.0",
26 | "@angular/platform-browser-dynamic": "~2.2.0",
27 | "@angular/router": "~3.2.0",
28 | "angular-in-memory-web-api": "~0.1.15",
29 | "core-js": "^2.4.1",
30 | "reflect-metadata": "^0.1.8",
31 | "rxjs": "5.0.0-beta.12",
32 | "systemjs": "0.19.40",
33 | "zone.js": "^0.6.26"
34 | },
35 | "devDependencies": {
36 | "concurrently": "^3.1.0",
37 | "lite-server": "^2.2.2",
38 | "typescript": "^2.0.10",
39 | "canonical-path": "0.0.2",
40 | "http-server": "^0.9.0",
41 | "tslint": "^3.15.1",
42 | "lodash": "^4.16.4",
43 | "jasmine-core": "~2.4.1",
44 | "karma": "^1.3.0",
45 | "karma-chrome-launcher": "^2.0.0",
46 | "karma-cli": "^1.0.1",
47 | "karma-jasmine": "^1.0.2",
48 | "karma-jasmine-html-reporter": "^0.2.2",
49 | "karma-phantomjs-launcher": "^1.0.2",
50 | "protractor": "4.0.14",
51 | "webdriver-manager": "10.2.5",
52 | "rimraf": "^2.5.4",
53 | "@types/node": "^6.0.46",
54 | "@types/jasmine": "^2.5.36",
55 | "@types/selenium-webdriver": "^2.53.33"
56 | },
57 | "repository": {}
58 | }
59 |
--------------------------------------------------------------------------------
/Chapter 07/protractor-results.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Chapter 07/spec/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | // describe('Given page has a page title and navigation menu', () => {
4 | // beforeEach( () => {
5 | // browser.get('');
6 | // });
7 | //
8 | // it('Page should have a header title as expected ', function () {
9 | // expect(element(by.css('h1')).getText()).toEqual('My First Angular 2 App');
10 | // });
11 | //
12 | // it('should have