99 | git push -u origin master
100 | ```
101 | ## Install npm packages
102 |
103 | > See npm and nvm version notes above
104 |
105 | Install the npm packages described in the `package.json` and verify that it works:
106 |
107 | ```shell
108 | npm install
109 | npm start
110 | ```
111 |
112 | >Doesn't work in _Bash for Windows_ which does not support servers as of January, 2017.
113 |
114 | The `npm start` command first compiles the application,
115 | then simultaneously re-compiles and runs the `lite-server`.
116 | Both the compiler and the server watch for file changes.
117 |
118 | Shut it down manually with `Ctrl-C`.
119 |
120 | You're ready to write your application.
121 |
122 | ### npm scripts
123 |
124 | We've captured many of the most useful commands in npm scripts defined in the `package.json`:
125 |
126 | * `npm start` - runs the compiler and a server at the same time, both in "watch mode".
127 | * `npm run build` - runs the TypeScript compiler once.
128 | * `npm run build:w` - runs the TypeScript compiler in watch mode; the process keeps running, awaiting changes to TypeScript files and re-compiling when it sees them.
129 | * `npm run serve` - runs the [lite-server](https://www.npmjs.com/package/lite-server), a light-weight, static file server, written and maintained by
130 | [John Papa](https://github.com/johnpapa) and
131 | [Christopher Martin](https://github.com/cgmartin)
132 | with excellent support for Angular apps that use routing.
133 |
134 | Here are the test related scripts:
135 | * `npm test` - compiles, runs and watches the karma unit tests
136 | * `npm run e2e` - compiles and run protractor e2e tests, written in Typescript (*e2e-spec.ts)
137 |
138 | ## Testing
139 |
140 | The QuickStart documentation doesn't discuss testing.
141 | This repo adds both karma/jasmine unit test and protractor end-to-end testing support.
142 |
143 | These tools are configured for specific conventions described below.
144 |
145 | *It is unwise and rarely possible to run the application, the unit tests, and the e2e tests at the same time.
146 | We recommend that you shut down one before starting another.*
147 |
148 | ### Unit Tests
149 | TypeScript unit-tests are usually in the `src/app` folder. Their filenames must end in `.spec.ts`.
150 |
151 | Look for the example `src/app/app.component.spec.ts`.
152 | Add more `.spec.ts` files as you wish; we configured karma to find them.
153 |
154 | Run it with `npm test`
155 |
156 | That command first compiles the application, then simultaneously re-compiles and runs the karma test-runner.
157 | Both the compiler and the karma watch for (different) file changes.
158 |
159 | Shut it down manually with `Ctrl-C`.
160 |
161 | Test-runner output appears in the terminal window.
162 | We can update our app and our tests in real-time, keeping a weather eye on the console for broken tests.
163 | Karma is occasionally confused and it is often necessary to shut down its browser or even shut the command down (`Ctrl-C`) and
164 | restart it. No worries; it's pretty quick.
165 |
166 | ### End-to-end (E2E) Tests
167 |
168 | E2E tests are in the `e2e` directory, side by side with the `src` folder.
169 | Their filenames must end in `.e2e-spec.ts`.
170 |
171 | Look for the example `e2e/app.e2e-spec.ts`.
172 | Add more `.e2e-spec.js` files as you wish (although one usually suffices for small projects);
173 | we configured Protractor to find them.
174 |
175 | Thereafter, run them with `npm run e2e`.
176 |
177 | That command first compiles, then simultaneously starts the `lite-server` at `localhost:8080`
178 | and launches Protractor.
179 |
180 | The pass/fail test results appear at the bottom of the terminal window.
181 | A custom reporter (see `protractor.config.js`) generates a `./_test-output/protractor-results.txt` file
182 | which is easier to read; this file is excluded from source control.
183 |
184 | Shut it down manually with `Ctrl-C`.
185 |
186 | [travis-badge]: https://travis-ci.org/angular/quickstart.svg?branch=master
187 | [travis-badge-url]: https://travis-ci.org/angular/quickstart
188 |
--------------------------------------------------------------------------------
/template-syntax/bs-config.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "open": false,
3 | "logLevel": "silent",
4 | "port": 8080,
5 | "server": {
6 | "baseDir": "src",
7 | "routes": {
8 | "/node_modules": "node_modules"
9 | },
10 | "middleware": {
11 | "0": null
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/template-syntax/bs-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server": {
3 | "baseDir": "src",
4 | "routes": {
5 | "/node_modules": "node_modules"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/template-syntax/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | describe('QuickStart E2E Tests', function () {
4 |
5 | let expectedMsg = 'Hello Angular';
6 |
7 | beforeEach(function () {
8 | browser.get('');
9 | });
10 |
11 | it('should display: ' + expectedMsg, function () {
12 | expect(element(by.css('h1')).getText()).toEqual(expectedMsg);
13 | });
14 |
15 | });
16 |
--------------------------------------------------------------------------------
/template-syntax/e2e/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": true,
11 | "suppressImplicitAnyIndexErrors": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/template-syntax/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 'src/')
11 | var builtPaths = (__karma__.config.builtPaths || ['src/'])
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 | // Base URL for System.js calls. 'base/' is where Karma serves files from.
38 | baseURL: 'base/src',
39 | // Extend usual application package list with test folder
40 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
41 |
42 | // Assume npm: is set in `paths` in systemjs.config
43 | // Map the angular testing umd bundles
44 | map: {
45 | '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
46 | '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
47 | '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
48 | '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
49 | '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
50 | '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
51 | '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
52 | '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
53 | },
54 | });
55 |
56 | System.import('systemjs.config.js')
57 | .then(importSystemJsExtras)
58 | .then(initTestBed)
59 | .then(initTesting);
60 |
61 | /** Optional SystemJS configuration extras. Keep going w/o it */
62 | function importSystemJsExtras(){
63 | return System.import('systemjs.config.extras.js')
64 | .catch(function(reason) {
65 | console.log(
66 | 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
67 | );
68 | console.log(reason);
69 | });
70 | }
71 |
72 | function initTestBed(){
73 | return Promise.all([
74 | System.import('@angular/core/testing'),
75 | System.import('@angular/platform-browser-dynamic/testing')
76 | ])
77 |
78 | .then(function (providers) {
79 | var coreTesting = providers[0];
80 | var browserTesting = providers[1];
81 |
82 | coreTesting.TestBed.initTestEnvironment(
83 | browserTesting.BrowserDynamicTestingModule,
84 | browserTesting.platformBrowserDynamicTesting());
85 | })
86 | }
87 |
88 | // Import all spec files and start karma
89 | function initTesting () {
90 | return Promise.all(
91 | allSpecFiles.map(function (moduleName) {
92 | return System.import(moduleName);
93 | })
94 | )
95 | .then(__karma__.start, __karma__.error);
96 | }
97 |
--------------------------------------------------------------------------------
/template-syntax/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 |
3 | var appBase = 'src/'; // transpiled app JS and map files
4 | var appSrcBase = appBase; // app source TS files
5 |
6 | // Testing helpers (optional) are conventionally in a folder called `testing`
7 | var testingBase = 'testing/'; // transpiled test JS and map files
8 | var testingSrcBase = 'testing/'; // 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-jasmine-html-reporter')
18 | ],
19 |
20 | client: {
21 | builtPaths: [appBase, testingBase], // add more spec base paths as needed
22 | clearContext: false // leave Jasmine Spec Runner output visible in browser
23 | },
24 |
25 | customLaunchers: {
26 | // From the CLI. Not used here but interesting
27 | // chrome setup for travis CI using chromium
28 | Chrome_travis_ci: {
29 | base: 'Chrome',
30 | flags: ['--no-sandbox']
31 | }
32 | },
33 |
34 | files: [
35 | // System.js for module loading
36 | 'node_modules/systemjs/dist/system.src.js',
37 |
38 | // Polyfills
39 | 'node_modules/core-js/client/shim.js',
40 |
41 | // zone.js
42 | 'node_modules/zone.js/dist/zone.js',
43 | 'node_modules/zone.js/dist/long-stack-trace-zone.js',
44 | 'node_modules/zone.js/dist/proxy.js',
45 | 'node_modules/zone.js/dist/sync-test.js',
46 | 'node_modules/zone.js/dist/jasmine-patch.js',
47 | 'node_modules/zone.js/dist/async-test.js',
48 | 'node_modules/zone.js/dist/fake-async-test.js',
49 |
50 | // RxJs
51 | { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
52 | { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
53 |
54 | // Paths loaded via module imports:
55 | // Angular itself
56 | { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
57 | { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
58 |
59 | { pattern: appBase + '/systemjs.config.js', included: false, watched: false },
60 | { pattern: appBase + '/systemjs.config.extras.js', included: false, watched: false },
61 | 'karma-test-shim.js', // optionally extend SystemJS mapping e.g., with barrels
62 |
63 | // transpiled application & spec code paths loaded via module imports
64 | { pattern: appBase + '**/*.js', included: false, watched: true },
65 | { pattern: testingBase + '**/*.js', included: false, watched: true },
66 |
67 |
68 | // Asset (HTML & CSS) paths loaded via Angular's component compiler
69 | // (these paths need to be rewritten, see proxies section)
70 | { pattern: appBase + '**/*.html', included: false, watched: true },
71 | { pattern: appBase + '**/*.css', included: false, watched: true },
72 |
73 | // Paths for debugging with source maps in dev tools
74 | { pattern: appBase + '**/*.ts', included: false, watched: false },
75 | { pattern: appBase + '**/*.js.map', included: false, watched: false },
76 | { pattern: testingSrcBase + '**/*.ts', included: false, watched: false },
77 | { pattern: testingBase + '**/*.js.map', included: false, watched: false}
78 | ],
79 |
80 | // Proxied base paths for loading assets
81 | proxies: {
82 | // required for modules fetched by SystemJS
83 | '/base/src/node_modules/': '/base/node_modules/'
84 | },
85 |
86 | exclude: [],
87 | preprocessors: {},
88 | reporters: ['progress', 'kjhtml'],
89 |
90 | port: 9876,
91 | colors: true,
92 | logLevel: config.LOG_INFO,
93 | autoWatch: true,
94 | browsers: ['Chrome'],
95 | singleRun: false
96 | })
97 | }
98 |
--------------------------------------------------------------------------------
/template-syntax/non-essential-files.osx.txt:
--------------------------------------------------------------------------------
1 | .git .gitignore .travis.yml bs-config.e2e.json CHANGELOG.md e2e favicon.ico karma.conf.js karma-test-shim.js LICENSE non-essential-files.txt protractor.config.js README.md
--------------------------------------------------------------------------------
/template-syntax/non-essential-files.txt:
--------------------------------------------------------------------------------
1 | .git
2 | .gitignore
3 | .travis.yml
4 | *.spec*.ts
5 | bs-config.e2e.json
6 | CHANGELOG.md
7 | e2e
8 | favicon.ico
9 | karma.conf.js
10 | karma-test-shim.js
11 | LICENSE
12 | non-essential-files.txt
13 | non-essential-files.osx.txt
14 | protractor.config.js
15 | README.md
16 |
--------------------------------------------------------------------------------
/template-syntax/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-quickstart",
3 | "version": "1.0.0",
4 | "description": "QuickStart package.json from the documentation, supplemented with testing support",
5 | "scripts": {
6 | "build": "tsc -p src/",
7 | "build:watch": "tsc -p src/ -w",
8 | "build:e2e": "tsc -p e2e/",
9 | "serve": "lite-server -c=bs-config.json",
10 | "serve:e2e": "lite-server -c=bs-config.e2e.json",
11 | "prestart": "npm run build",
12 | "start": "concurrently \"npm run build:watch\" \"npm run serve\"",
13 | "pree2e": "npm run build:e2e",
14 | "e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
15 | "preprotractor": "webdriver-manager update",
16 | "protractor": "protractor protractor.config.js",
17 | "pretest": "npm run build",
18 | "test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
19 | "pretest:once": "npm run build",
20 | "test:once": "karma start karma.conf.js --single-run",
21 | "lint": "tslint ./src/**/*.ts -t verbose"
22 | },
23 | "keywords": [],
24 | "author": "",
25 | "license": "MIT",
26 | "dependencies": {
27 | "@angular/common": "~4.3.4",
28 | "@angular/compiler": "~4.3.4",
29 | "@angular/core": "~4.3.4",
30 | "@angular/forms": "~4.3.4",
31 | "@angular/http": "~4.3.4",
32 | "@angular/platform-browser": "~4.3.4",
33 | "@angular/platform-browser-dynamic": "~4.3.4",
34 | "@angular/router": "~4.3.4",
35 |
36 | "angular-in-memory-web-api": "~0.3.0",
37 | "systemjs": "0.19.40",
38 | "core-js": "^2.4.1",
39 | "rxjs": "5.0.1",
40 | "zone.js": "^0.8.4"
41 | },
42 | "devDependencies": {
43 | "concurrently": "^3.2.0",
44 | "lite-server": "^2.2.2",
45 | "typescript": "~2.1.0",
46 |
47 | "canonical-path": "0.0.2",
48 | "tslint": "^3.15.1",
49 | "lodash": "^4.16.4",
50 | "jasmine-core": "~2.4.1",
51 | "karma": "^1.3.0",
52 | "karma-chrome-launcher": "^2.0.0",
53 | "karma-cli": "^1.0.1",
54 | "karma-jasmine": "^1.0.2",
55 | "karma-jasmine-html-reporter": "^0.2.2",
56 | "protractor": "~4.0.14",
57 | "rimraf": "^2.5.4",
58 |
59 | "@types/node": "^6.0.46",
60 | "@types/jasmine": "2.5.36"
61 | },
62 | "repository": {}
63 | }
64 |
--------------------------------------------------------------------------------
/template-syntax/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., lite-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 | // doesn't seem to work.
40 | // resultJsonOutputFile: "foo.json",
41 |
42 | onPrepare: function() {
43 | //// SpecReporter
44 | //var SpecReporter = require('jasmine-spec-reporter');
45 | //jasmine.getEnv().addReporter(new SpecReporter({displayStacktrace: 'none'}));
46 | //// jasmine.getEnv().addReporter(new SpecReporter({displayStacktrace: 'all'}));
47 |
48 | // debugging
49 | // console.log('browser.params:' + JSON.stringify(browser.params));
50 | jasmine.getEnv().addReporter(new Reporter( browser.params )) ;
51 |
52 | // Allow changing bootstrap mode to NG1 for upgrade tests
53 | global.setProtractorToNg1Mode = function() {
54 | browser.useAllAngular2AppRoots = false;
55 | browser.rootEl = 'body';
56 | };
57 | },
58 |
59 | jasmineNodeOpts: {
60 | // defaultTimeoutInterval: 60000,
61 | defaultTimeoutInterval: 10000,
62 | showTiming: true,
63 | print: function() {}
64 | }
65 | };
66 |
67 | // Custom reporter
68 | function Reporter(options) {
69 | var _defaultOutputFile = path.resolve(process.cwd(), './_test-output', 'protractor-results.txt');
70 | options.outputFile = options.outputFile || _defaultOutputFile;
71 |
72 | initOutputFile(options.outputFile);
73 | options.appDir = options.appDir || './';
74 | var _root = { appDir: options.appDir, suites: [] };
75 | log('AppDir: ' + options.appDir, +1);
76 | var _currentSuite;
77 |
78 | this.suiteStarted = function(suite) {
79 | _currentSuite = { description: suite.description, status: null, specs: [] };
80 | _root.suites.push(_currentSuite);
81 | log('Suite: ' + suite.description, +1);
82 | };
83 |
84 | this.suiteDone = function(suite) {
85 | var statuses = _currentSuite.specs.map(function(spec) {
86 | return spec.status;
87 | });
88 | statuses = _.uniq(statuses);
89 | var status = statuses.indexOf('failed') >= 0 ? 'failed' : statuses.join(', ');
90 | _currentSuite.status = status;
91 | log('Suite ' + _currentSuite.status + ': ' + suite.description, -1);
92 | };
93 |
94 | this.specStarted = function(spec) {
95 |
96 | };
97 |
98 | this.specDone = function(spec) {
99 | var currentSpec = {
100 | description: spec.description,
101 | status: spec.status
102 | };
103 | if (spec.failedExpectations.length > 0) {
104 | currentSpec.failedExpectations = spec.failedExpectations;
105 | }
106 |
107 | _currentSuite.specs.push(currentSpec);
108 | log(spec.status + ' - ' + spec.description);
109 | };
110 |
111 | this.jasmineDone = function() {
112 | outputFile = options.outputFile;
113 | //// Alternate approach - just stringify the _root - not as pretty
114 | //// but might be more useful for automation.
115 | // var output = JSON.stringify(_root, null, 2);
116 | var output = formatOutput(_root);
117 | fs.appendFileSync(outputFile, output);
118 | };
119 |
120 | function ensureDirectoryExistence(filePath) {
121 | var dirname = path.dirname(filePath);
122 | if (directoryExists(dirname)) {
123 | return true;
124 | }
125 | ensureDirectoryExistence(dirname);
126 | fs.mkdirSync(dirname);
127 | }
128 |
129 | function directoryExists(path) {
130 | try {
131 | return fs.statSync(path).isDirectory();
132 | }
133 | catch (err) {
134 | return false;
135 | }
136 | }
137 |
138 | function initOutputFile(outputFile) {
139 | ensureDirectoryExistence(outputFile);
140 | var header = "Protractor results for: " + (new Date()).toLocaleString() + "\n\n";
141 | fs.writeFileSync(outputFile, header);
142 | }
143 |
144 | // for output file output
145 | function formatOutput(output) {
146 | var indent = ' ';
147 | var pad = ' ';
148 | var results = [];
149 | results.push('AppDir:' + output.appDir);
150 | output.suites.forEach(function(suite) {
151 | results.push(pad + 'Suite: ' + suite.description + ' -- ' + suite.status);
152 | pad+=indent;
153 | suite.specs.forEach(function(spec) {
154 | results.push(pad + spec.status + ' - ' + spec.description);
155 | if (spec.failedExpectations) {
156 | pad+=indent;
157 | spec.failedExpectations.forEach(function (fe) {
158 | results.push(pad + 'message: ' + fe.message);
159 | });
160 | pad=pad.substr(2);
161 | }
162 | });
163 | pad = pad.substr(2);
164 | results.push('');
165 | });
166 | results.push('');
167 | return results.join('\n');
168 | }
169 |
170 | // for console output
171 | var _pad;
172 | function log(str, indent) {
173 | _pad = _pad || '';
174 | if (indent == -1) {
175 | _pad = _pad.substr(2);
176 | }
177 | console.log(_pad + str);
178 | if (indent == 1) {
179 | _pad = _pad + ' ';
180 | }
181 | }
182 |
183 | }
184 |
--------------------------------------------------------------------------------
/template-syntax/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 | My current hero is {{current.name}}
3 |
4 |
5 |
6 | {{title}}
7 |
8 |
9 |
10 | The sum of 1 + 1 is {{1 + 1}}
11 | The sum of 1 + 1 is not {{1 + 1 + getVal()}}
12 |
14 |
15 |
16 | {{title}}
17 | changed
18 |
19 |
20 |
21 | {{heroInput.value}}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Mental Model
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/template-syntax/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AppComponent } from './app.component';
2 |
3 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4 | import { By } from '@angular/platform-browser';
5 | import { DebugElement } from '@angular/core';
6 |
7 | describe('AppComponent', function () {
8 | let de: DebugElement;
9 | let comp: AppComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [ AppComponent ]
15 | })
16 | .compileComponents();
17 | }));
18 |
19 | beforeEach(() => {
20 | fixture = TestBed.createComponent(AppComponent);
21 | comp = fixture.componentInstance;
22 | de = fixture.debugElement.query(By.css('h1'));
23 | });
24 |
25 | it('should create component', () => expect(comp).toBeDefined() );
26 |
27 | it('should have expected text', () => {
28 | fixture.detectChanges();
29 | const h1 = de.nativeElement;
30 | expect(h1.innerText).toMatch(/angular/i,
31 | ' should say something about "Angular"');
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/template-syntax/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'my-app',
5 | template: `Hello {{name}}
`,
6 | })
7 | export class AppComponent { name = 'Angular'; }
8 |
--------------------------------------------------------------------------------
/template-syntax/src/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 |
--------------------------------------------------------------------------------
/template-syntax/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hzlshen/angular-case/0f60ae7f4517fbabee140bdf386960f7a8e4911d/template-syntax/src/favicon.ico
--------------------------------------------------------------------------------
/template-syntax/src/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 AppComponent content here ...
24 |
25 |
26 |
--------------------------------------------------------------------------------
/template-syntax/src/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app/app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/template-syntax/src/styles.css:
--------------------------------------------------------------------------------
1 | h1 {
2 | color: #369;
3 | font-family: Arial, Helvetica, sans-serif;
4 | font-size: 250%;
5 | }
6 |
--------------------------------------------------------------------------------
/template-syntax/src/systemjs-angular-loader.js:
--------------------------------------------------------------------------------
1 | var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm;
2 | var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
3 | var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g;
4 |
5 | module.exports.translate = function(load){
6 | if (load.source.indexOf('moduleId') != -1) return load;
7 |
8 | var url = document.createElement('a');
9 | url.href = load.address;
10 |
11 | var basePathParts = url.pathname.split('/');
12 |
13 | basePathParts.pop();
14 | var basePath = basePathParts.join('/');
15 |
16 | var baseHref = document.createElement('a');
17 | baseHref.href = this.baseURL;
18 | baseHref = baseHref.pathname;
19 |
20 | if (!baseHref.startsWith('/base/')) { // it is not karma
21 | basePath = basePath.replace(baseHref, '');
22 | }
23 |
24 | load.source = load.source
25 | .replace(templateUrlRegex, function(match, quote, url){
26 | var resolvedUrl = url;
27 |
28 | if (url.startsWith('.')) {
29 | resolvedUrl = basePath + url.substr(1);
30 | }
31 |
32 | return 'templateUrl: "' + resolvedUrl + '"';
33 | })
34 | .replace(stylesRegex, function(match, relativeUrls) {
35 | var urls = [];
36 |
37 | while ((match = stringRegex.exec(relativeUrls)) !== null) {
38 | if (match[2].startsWith('.')) {
39 | urls.push('"' + basePath + match[2].substr(1) + '"');
40 | } else {
41 | urls.push('"' + match[2] + '"');
42 | }
43 | }
44 |
45 | return "styleUrls: [" + urls.join(', ') + "]";
46 | });
47 |
48 | return load;
49 | };
50 |
--------------------------------------------------------------------------------
/template-syntax/src/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 |
--------------------------------------------------------------------------------
/template-syntax/src/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/forms': 'npm:@angular/forms/bundles/forms.umd.js',
25 |
26 | // other libraries
27 | 'rxjs': 'npm:rxjs',
28 | 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
29 | },
30 | // packages tells the System loader how to load when no filename and/or no extension
31 | packages: {
32 | app: {
33 | defaultExtension: 'js',
34 | meta: {
35 | './*.js': {
36 | loader: 'systemjs-angular-loader.js'
37 | }
38 | }
39 | },
40 | rxjs: {
41 | defaultExtension: 'js'
42 | }
43 | }
44 | });
45 | })(this);
46 |
--------------------------------------------------------------------------------
/template-syntax/src/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": true,
11 | "suppressImplicitAnyIndexErrors": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/template-syntax/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 |
--------------------------------------------------------------------------------