diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index c2658d7d1..000000000 --- a/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ diff --git a/.editorconfig b/.editorconfig index f2abacf6d..b8a6e5723 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,7 +5,6 @@ root = true charset = utf-8 indent_style = space indent_size = 2 -end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true diff --git a/.gitignore b/.gitignore index f23176b5b..9b3a09fc9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,14 @@ .idea -typings/** node_modules jspm_packages -link-checker-results.txt -**/*npm-debug.log.* -*.js +npm-debug.log +debug.log +src/**/*.js +!src/systemjs.config.extras.js +!src/systemjs.config.js +!src/systemjs-angular-loader.js *.js.map e2e/**/*.js e2e/**/*.js.map _test-output _temp - -!karma*.js -!protractor*.js -!systemjs.config.js -!typings/typings.d.ts -!wallaby.js diff --git a/.travis.yml b/.travis.yml index a20396221..808bc2c4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,5 +16,5 @@ install: - npm install script: - npm run lint - - npm run test-once + - npm run test:once - npm run e2e diff --git a/CHANGELOG.md b/CHANGELOG.md index 07e61fb9c..4c991b119 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,82 @@ +## Angular Documentation QuickStart Changelog +Upgraders: for a fresh start, consider running these commands +* `git clean -xdf` +* `npm install` + + +# 0.4.1 (2017-03-24) +* Replace systemjs-angular-loader with version that works for IE + + +# 0.4.0 (2017-03-24) +* Update to Angular 4.0.0 + + +# 0.3.0 (2017-03-22) +* Remove moduleId with a systemjs loader. + + +# 0.2.22 (2017-01-05) +* Add `non-essential-files.txt` and instructions to use it to README + + +# 0.2.21 (2016-12-14) +* Update to in-memory-web-api v.0.2.1 + + +# 0.2.20 (2016-12-07) +* Update to Angular 2.3.0 + + +# 0.2.19 (2016-11-30) +* remove upgrade mappings from `systemjs.config.js` PR #301 + + +# 0.2.18 (2016-11-30) +* remove `exclude` clause from `tsconfig.json`; it was just confusing people +* karma.config + karma-test-shim can handle multiple spec source paths (issue #294) +* cosmetic `app.component.spec.ts` changes +* cosmetic `karma.config.js` changes + + +# 0.2.17 (2016-11-16) +* Conform to updated QuickStart advice + * removed docker everywhere (was nice but not necessary) + * removed wallaby + * shrink styles.css + * refine tsconfig.json + * `AppComponent` uses interpolation + + +# 0.2.16 (2016-11-14) +* Update to Angular 2.2.0 + + +# 0.2.15 (2016-10-29) +* Revert to Jasmine 2.4.1 because bug in 2.5.x (see [jasmine issue #1231](https://github.com/jasmine/jasmine/issues/1231)) + + +# 0.2.14 (2016-10-29) +* Remove bootstrap.css install +* Angular v2.1.2 + + +# 0.2.13 (2016-10-20) +* Protractor 4 +* Move from `typings` to `@types`. See `tsconfig.json` changes. +* Angular v2.1.1 + + +# 0.2.12 (2016-10-06) +* Angular v2.1.0 + + +# 0.2.11 (2016-10-06) +* Angular v2.0.2 +* License is MIT +* Current testing configuration +* No code changes + # 0.2.10 (2016-09-19) * All "Angular 2" references become just "Angular" diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index eb5aae757..000000000 --- a/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# To build and run with Docker: -# -# $ docker build -t ng-quickstart . -# $ docker run -it --rm -p 3000:3000 -p 3001:3001 ng-quickstart -# -FROM node:latest - -RUN mkdir -p /quickstart /home/nodejs && \ - groupadd -r nodejs && \ - useradd -r -g nodejs -d /home/nodejs -s /sbin/nologin nodejs && \ - chown -R nodejs:nodejs /home/nodejs - -WORKDIR /quickstart -COPY package.json typings.json /quickstart/ -RUN npm install --unsafe-perm=true - -COPY . /quickstart -RUN chown -R nodejs:nodejs /quickstart -USER nodejs - -CMD npm start diff --git a/README.md b/README.md index 9451b0f99..aeccb7d76 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # Angular QuickStart Source [![Build Status][travis-badge]][travis-badge-url] +**This repository is now deprecated. The Angular Quickstart project was a nice starting point for creating Angular applications. Now we recommend using the [Angular CLI](https://github.com/angular/angular-cli) to create new Angular projects.** + +**Starting from 1 November 2017, all the Angular documentation, at [angular.io](https://angular.io), is based on the Angular CLI.** + +**Let's [get started](https://angular.io/guide/quickstart)** + +--- + This repository holds the TypeScript source code of the [angular.io quickstart](https://angular.io/docs/ts/latest/quickstart.html), the foundation for most of the documentation samples and potentially a good starting point for your application. @@ -12,6 +20,24 @@ It exists primarily to get you started quickly with learning and prototyping in We are unlikely to accept suggestions about how to grow this QuickStart into something it is not. Please keep that in mind before posting issues and PRs. +## Updating to a newer version of the Quickstart Repo + +From time to time the QuickStart will be enhanced with support for new features or to reflect +changes to the [official Style Guide](https://angular.io/docs/ts/latest/guide/style-guide.html). + +You can update your existing project to an up-to-date QuickStart by following these instructions: +- Create a new project using the [instructions below](#create-a-new-project-based-on-the-quickstart) +- Copy the code you have in your project's `main.ts` file onto `src/app/main.ts` in the new project +- Copy your old `app` folder into `src/app` +- Delete `src/app/main.ts` if you have one (we now use `src/main.ts` instead) +- Copy your old `index.html`, `styles.css` and `tsconfig.json` into `src/` +- Install all your third party dependencies +- Copy your old `e2e/` folder into `e2e/` +- Copy over any other files you added to your project +- Copy your old `.git` folder into your new project's root + +Now you can continue working on the new project. + ## Prerequisites Node.js and npm are essential to Angular development. @@ -28,33 +54,55 @@ We recommend [nvm](https://github.com/creationix/nvm) for managing multiple vers ## Create a new project based on the QuickStart Clone this repo into new project folder (e.g., `my-proj`). -```bash -git clone https://github.com/angular/quickstart my-proj +```shell +git clone https://github.com/angular/quickstart my-proj cd my-proj ``` We have no intention of updating the source on `angular/quickstart`. -Discard everything "git-like" by deleting the `.git` folder. -```bash -rm -rf .git # non-Windows +Discard the `.git` folder.. +```shell +rm -rf .git # OS/X (bash) rd .git /S/Q # windows ``` +### Delete _non-essential_ files (optional) + +You can quickly delete the _non-essential_ files that concern testing and QuickStart repository maintenance +(***including all git-related artifacts*** such as the `.git` folder and `.gitignore`!) +by entering the following commands while in the project folder: + +##### OS/X (bash) +```shell +xargs rm -rf < non-essential-files.osx.txt +rm src/app/*.spec*.ts +rm non-essential-files.osx.txt +``` + +##### Windows +```shell +for /f %i in (non-essential-files.txt) do del %i /F /S /Q +rd .git /s /q +rd e2e /s /q +``` ### Create a new git repo You could [start writing code](#start-development) now and throw it all away when you're done. If you'd rather preserve your work under source control, consider taking the following steps. Initialize this project as a *local git repo* and make the first commit: -```bash +```shell git init git add . git commit -m "Initial commit" ``` +>Recover the deleted `.gitignore` from the QuickStart repository +if you lost it in the _Delete non-essential files_ step. + Create a *remote repository* for this project on the service of your choice. Grab its address (e.g. *`https://github.com//my-proj.git`*) and push the *local repo* to the *remote*. -```bash +```shell git remote add origin git push -u origin master ``` @@ -64,22 +112,18 @@ git push -u origin master Install the npm packages described in the `package.json` and verify that it works: -**Attention Windows Developers: You must run all of these commands in administrator mode**. - -```bash +```shell npm install npm start ``` -> If the `typings` folder doesn't show up after `npm install` please install them manually with: - -> `npm run typings -- install` +>Doesn't work in _Bash for Windows_ which does not support servers as of January, 2017. The `npm start` command first compiles the application, then simultaneously re-compiles and runs the `lite-server`. Both the compiler and the server watch for file changes. -Shut it down manually with Ctrl-C. +Shut it down manually with `Ctrl-C`. You're ready to write your application. @@ -88,17 +132,16 @@ You're ready to write your application. We've captured many of the most useful commands in npm scripts defined in the `package.json`: * `npm start` - runs the compiler and a server at the same time, both in "watch mode". -* `npm run tsc` - runs the TypeScript compiler once. -* `npm run tsc:w` - runs the TypeScript compiler in watch mode; the process keeps running, awaiting changes to TypeScript files and re-compiling when it sees them. -* `npm run lite` - runs the [lite-server](https://www.npmjs.com/package/lite-server), a light-weight, static file server, written and maintained by +* `npm run build` - runs the TypeScript compiler once. +* `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. +* `npm run serve` - runs the [lite-server](https://www.npmjs.com/package/lite-server), a light-weight, static file server, written and maintained by [John Papa](https://github.com/johnpapa) and [Christopher Martin](https://github.com/cgmartin) with excellent support for Angular apps that use routing. -* `npm run typings` - runs the typings tool. -* `npm run postinstall` - called by *npm* automatically *after* it successfully completes package installation. This script installs the TypeScript definition files this app requires. + Here are the test related scripts: * `npm test` - compiles, runs and watches the karma unit tests -* `npm run e2e` - run protractor e2e tests, written in JavaScript (*e2e-spec.js) +* `npm run e2e` - compiles and run protractor e2e tests, written in Typescript (*e2e-spec.ts) ## Testing @@ -111,9 +154,9 @@ These tools are configured for specific conventions described below. We recommend that you shut down one before starting another.* ### Unit Tests -TypeScript unit-tests are usually in the `app` folder. Their filenames must end in `.spec`. +TypeScript unit-tests are usually in the `src/app` folder. Their filenames must end in `.spec.ts`. -Look for the example `app/app.component.spec.ts`. +Look for the example `src/app/app.component.spec.ts`. Add more `.spec.ts` files as you wish; we configured karma to find them. Run it with `npm test` @@ -121,34 +164,32 @@ Run it with `npm test` That command first compiles the application, then simultaneously re-compiles and runs the karma test-runner. Both the compiler and the karma watch for (different) file changes. -Shut it down manually with Ctrl-C. +Shut it down manually with `Ctrl-C`. Test-runner output appears in the terminal window. We can update our app and our tests in real-time, keeping a weather eye on the console for broken tests. -Karma is occasionally confused and it is often necessary to shut down its browser or even shut the command down (Ctrl-C) and +Karma is occasionally confused and it is often necessary to shut down its browser or even shut the command down (`Ctrl-C`) and restart it. No worries; it's pretty quick. -The `HTML-Reporter` is also wired in. That produces a prettier output; look for it in `~_test-output/tests.html`. - ### End-to-end (E2E) Tests -E2E tests are in the `e2e` directory, side by side with the `app` folder. +E2E tests are in the `e2e` directory, side by side with the `src` folder. Their filenames must end in `.e2e-spec.ts`. Look for the example `e2e/app.e2e-spec.ts`. Add more `.e2e-spec.js` files as you wish (although one usually suffices for small projects); -we configured protractor to find them. +we configured Protractor to find them. Thereafter, run them with `npm run e2e`. -That command first compiles, then simultaneously starts the Http-Server at `localhost:8080` -and launches protractor. +That command first compiles, then simultaneously starts the `lite-server` at `localhost:8080` +and launches Protractor. The pass/fail test results appear at the bottom of the terminal window. A custom reporter (see `protractor.config.js`) generates a `./_test-output/protractor-results.txt` file which is easier to read; this file is excluded from source control. -Shut it down manually with Ctrl-C. +Shut it down manually with `Ctrl-C`. [travis-badge]: https://travis-ci.org/angular/quickstart.svg?branch=master [travis-badge-url]: https://travis-ci.org/angular/quickstart diff --git a/app/app.component.spec.ts b/app/app.component.spec.ts deleted file mode 100644 index 53a68593d..000000000 --- a/app/app.component.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* tslint:disable:no-unused-variable */ -import { AppComponent } from './app.component'; - -import { TestBed } from '@angular/core/testing'; - -import { By } from '@angular/platform-browser'; - -//////// SPECS ///////////// - -/// Delete this -describe('Smoke test', () => { - it('should run a passing test', () => { - expect(true).toEqual(true, 'should pass'); - }); -}); - -describe('AppComponent with TCB', function () { - beforeEach(() => { - TestBed.configureTestingModule({declarations: [AppComponent]}); - }); - - it('should instantiate component', () => { - let fixture = TestBed.createComponent(AppComponent); - expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent'); - }); - - it('should have expected

text', () => { - let fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - - let h1 = fixture.debugElement.query(el => el.name === 'h1').nativeElement; // it works - - h1 = fixture.debugElement.query(By.css('h1')).nativeElement; // preferred - - expect(h1.innerText).toMatch(/angular app/i, '

should say something about "Angular App"'); - }); -}); diff --git a/app/app.component.ts b/app/app.component.ts deleted file mode 100644 index 83919ca76..000000000 --- a/app/app.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'my-app', - template: '

My First Angular App

' -}) -export class AppComponent { } diff --git a/bs-config.e2e.json b/bs-config.e2e.json new file mode 100644 index 000000000..24570dbcc --- /dev/null +++ b/bs-config.e2e.json @@ -0,0 +1,14 @@ +{ + "open": false, + "logLevel": "silent", + "port": 8080, + "server": { + "baseDir": "src", + "routes": { + "/node_modules": "node_modules" + }, + "middleware": { + "0": null + } + } +} diff --git a/bs-config.json b/bs-config.json new file mode 100644 index 000000000..4e5859526 --- /dev/null +++ b/bs-config.json @@ -0,0 +1,8 @@ +{ + "server": { + "baseDir": "src", + "routes": { + "/node_modules": "node_modules" + } + } +} diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts index 8db702bd4..67f5d8d6a 100644 --- a/e2e/app.e2e-spec.ts +++ b/e2e/app.e2e-spec.ts @@ -1,8 +1,8 @@ +import { browser, element, by } from 'protractor'; describe('QuickStart E2E Tests', function () { - let expectedMsg = 'My First Angular App'; - + let expectedMsg = 'Hello Angular'; beforeEach(function () { browser.get(''); diff --git a/tsconfig.json b/e2e/tsconfig.json similarity index 89% rename from tsconfig.json rename to e2e/tsconfig.json index fd1d10190..2c7260d1b 100644 --- a/tsconfig.json +++ b/e2e/tsconfig.json @@ -6,7 +6,7 @@ "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "removeComments": false, + "lib": [ "es2015", "dom" ], "noImplicitAny": true, "suppressImplicitAnyIndexErrors": true } diff --git a/karma-test-shim.js b/karma-test-shim.js index 19fcc89fe..fe5aa7761 100644 --- a/karma-test-shim.js +++ b/karma-test-shim.js @@ -1,4 +1,3 @@ -// #docregion // /*global jasmine, __karma__, window*/ Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing. @@ -7,7 +6,10 @@ Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing. jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; -var builtPath = '/base/app/'; +// builtPaths: root paths for output ("built") files +// get from karma.config.js, then prefix with '/base/' (default is 'src/') +var builtPaths = (__karma__.config.builtPaths || ['src/']) + .map(function(p) { return '/base/'+p;}); __karma__.loaded = function () { }; @@ -19,8 +21,12 @@ function isSpecFile(path) { return /\.spec\.(.*\.)?js$/.test(path); } +// Is a "built" file if is JavaScript file in one of the "built" folders function isBuiltFile(path) { - return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath); + return isJsFile(path) && + builtPaths.reduce(function(keep, bp) { + return keep || (path.substr(0, bp.length) === bp); + }, false); } var allSpecFiles = Object.keys(window.__karma__.files) @@ -28,7 +34,8 @@ var allSpecFiles = Object.keys(window.__karma__.files) .filter(isBuiltFile); System.config({ - baseURL: '/base', + // Base URL for System.js calls. 'base/' is where Karma serves files from. + baseURL: 'base/src', // Extend usual application package list with test folder packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, diff --git a/karma.conf.js b/karma.conf.js index 1e2d29372..5a51e814f 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,23 +1,27 @@ -// #docregion module.exports = function(config) { - var appBase = 'app/'; // transpiled app JS and map files - var appSrcBase = 'app/'; // app source TS files - var appAssets = '/base/app/'; // component assets fetched by Angular's compiler + var appBase = 'src/'; // transpiled app JS and map files + var appSrcBase = appBase; // app source TS files - var testBase = 'testing/'; // transpiled test JS and map files - var testSrcBase = 'testing/'; // test source TS files + // Testing helpers (optional) are conventionally in a folder called `testing` + var testingBase = 'testing/'; // transpiled test JS and map files + var testingSrcBase = 'testing/'; // test source TS files config.set({ basePath: '', frameworks: ['jasmine'], + plugins: [ require('karma-jasmine'), require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), // click "Debug" in browser to see it - require('karma-htmlfile-reporter') // crashing w/ strange socket error + require('karma-jasmine-html-reporter') ], + client: { + builtPaths: [appBase, testingBase], // add more spec base paths as needed + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + customLaunchers: { // From the CLI. Not used here but interesting // chrome setup for travis CI using chromium @@ -26,13 +30,13 @@ module.exports = function(config) { flags: ['--no-sandbox'] } }, + files: [ // System.js for module loading 'node_modules/systemjs/dist/system.src.js', // Polyfills 'node_modules/core-js/client/shim.js', - 'node_modules/reflect-metadata/Reflect.js', // zone.js 'node_modules/zone.js/dist/zone.js', @@ -49,50 +53,39 @@ module.exports = function(config) { // Paths loaded via module imports: // Angular itself - {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false}, - {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, + { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false }, + { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false }, - {pattern: 'systemjs.config.js', included: false, watched: false}, - {pattern: 'systemjs.config.extras.js', included: false, watched: false}, - 'karma-test-shim.js', + { pattern: appBase + '/systemjs.config.js', included: false, watched: false }, + { pattern: appBase + '/systemjs.config.extras.js', included: false, watched: false }, + 'karma-test-shim.js', // optionally extend SystemJS mapping e.g., with barrels // transpiled application & spec code paths loaded via module imports - {pattern: appBase + '**/*.js', included: false, watched: true}, - {pattern: testBase + '**/*.js', included: false, watched: true}, + { pattern: appBase + '**/*.js', included: false, watched: true }, + { pattern: testingBase + '**/*.js', included: false, watched: true }, // Asset (HTML & CSS) paths loaded via Angular's component compiler // (these paths need to be rewritten, see proxies section) - {pattern: appBase + '**/*.html', included: false, watched: true}, - {pattern: appBase + '**/*.css', included: false, watched: true}, + { pattern: appBase + '**/*.html', included: false, watched: true }, + { pattern: appBase + '**/*.css', included: false, watched: true }, // Paths for debugging with source maps in dev tools - {pattern: appSrcBase + '**/*.ts', included: false, watched: false}, - {pattern: appBase + '**/*.js.map', included: false, watched: false}, - {pattern: testSrcBase + '**/*.ts', included: false, watched: false}, - {pattern: testBase + '**/*.js.map', included: false, watched: false} + { pattern: appBase + '**/*.ts', included: false, watched: false }, + { pattern: appBase + '**/*.js.map', included: false, watched: false }, + { pattern: testingSrcBase + '**/*.ts', included: false, watched: false }, + { pattern: testingBase + '**/*.js.map', included: false, watched: false} ], // Proxied base paths for loading assets proxies: { - // required for component assets fetched by Angular's compiler - "/app/": appAssets + // required for modules fetched by SystemJS + '/base/src/node_modules/': '/base/node_modules/' }, exclude: [], preprocessors: {}, - // disabled HtmlReporter; suddenly crashing w/ strange socket error - reporters: ['progress', 'kjhtml'],//'html'], - - // HtmlReporter configuration - htmlReporter: { - // Open this file to see results in browser - outputFile: '_test-output/tests.html', - - // Optional - pageTitle: 'Unit Tests', - subPageTitle: __dirname - }, + reporters: ['progress', 'kjhtml'], port: 9876, colors: true, diff --git a/non-essential-files.osx.txt b/non-essential-files.osx.txt new file mode 100644 index 000000000..653a8db9b --- /dev/null +++ b/non-essential-files.osx.txt @@ -0,0 +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 \ No newline at end of file diff --git a/non-essential-files.txt b/non-essential-files.txt new file mode 100644 index 000000000..644808a66 --- /dev/null +++ b/non-essential-files.txt @@ -0,0 +1,15 @@ +.git +.gitignore +.travis.yml +*.spec*.ts +bs-config.e2e.json +CHANGELOG.md +e2e +favicon.ico +karma.conf.js +karma-test-shim.js +LICENSE +non-essential-files.txt +non-essential-files.osx.txt +protractor.config.js +README.md diff --git a/package.json b/package.json index 36e1729f5..25513978a 100644 --- a/package.json +++ b/package.json @@ -3,62 +3,61 @@ "version": "1.0.0", "description": "QuickStart package.json from the documentation, supplemented with testing support", "scripts": { - "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ", - "docker-build": "docker build -t ng2-quickstart .", - "docker": "npm run docker-build && docker run -it --rm -p 3000:3000 -p 3001:3001 ng2-quickstart", - "pree2e": "npm run webdriver:update", - "e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first", - "lint": "tslint ./app/**/*.ts -t verbose", - "lite": "lite-server", - "postinstall": "typings install", - "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"", - "test-once": "tsc && karma start karma.conf.js --single-run", - "tsc": "tsc", - "tsc:w": "tsc -w", - "typings": "typings", - "webdriver:update": "webdriver-manager update" + "build": "tsc -p src/", + "build:watch": "tsc -p src/ -w", + "build:e2e": "tsc -p e2e/", + "serve": "lite-server -c=bs-config.json", + "serve:e2e": "lite-server -c=bs-config.e2e.json", + "prestart": "npm run build", + "start": "concurrently \"npm run build:watch\" \"npm run serve\"", + "pree2e": "npm run build:e2e", + "e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first", + "preprotractor": "webdriver-manager update", + "protractor": "protractor protractor.config.js", + "pretest": "npm run build", + "test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"", + "pretest:once": "npm run build", + "test:once": "karma start karma.conf.js --single-run", + "lint": "tslint ./src/**/*.ts -t verbose" }, "keywords": [], "author": "", - "license": "ISC", + "license": "MIT", "dependencies": { - "@angular/common": "~2.0.1", - "@angular/compiler": "~2.0.1", - "@angular/core": "~2.0.1", - "@angular/forms": "~2.0.1", - "@angular/http": "~2.0.1", - "@angular/platform-browser": "~2.0.1", - "@angular/platform-browser-dynamic": "~2.0.1", - "@angular/router": "~3.0.1", - "@angular/upgrade": "~2.0.1", + "@angular/common": "~4.3.4", + "@angular/compiler": "~4.3.4", + "@angular/core": "~4.3.4", + "@angular/forms": "~4.3.4", + "@angular/http": "~4.3.4", + "@angular/platform-browser": "~4.3.4", + "@angular/platform-browser-dynamic": "~4.3.4", + "@angular/router": "~4.3.4", - "angular-in-memory-web-api": "~0.1.1", - "bootstrap": "^3.3.7", - "systemjs": "0.19.39", + "angular-in-memory-web-api": "~0.3.0", + "systemjs": "0.19.40", "core-js": "^2.4.1", - "reflect-metadata": "^0.1.8", - "rxjs": "5.0.0-beta.12", - "zone.js": "^0.6.25" + "rxjs": "5.0.1", + "zone.js": "^0.8.4" }, "devDependencies": { - "concurrently": "^3.0.0", + "concurrently": "^3.2.0", "lite-server": "^2.2.2", - "typescript": "^2.0.3", - "typings": "^1.4.0", + "typescript": "~2.1.0", "canonical-path": "0.0.2", - "http-server": "^0.9.0", "tslint": "^3.15.1", - "lodash": "^4.16.2", - "jasmine-core": "~2.5.2", + "lodash": "^4.16.4", + "jasmine-core": "~2.4.1", "karma": "^1.3.0", "karma-chrome-launcher": "^2.0.0", "karma-cli": "^1.0.1", - "karma-htmlfile-reporter": "^0.3.4", "karma-jasmine": "^1.0.2", "karma-jasmine-html-reporter": "^0.2.2", - "protractor": "^3.3.0", - "rimraf": "^2.5.4" + "protractor": "~4.0.14", + "rimraf": "^2.5.4", + + "@types/node": "^6.0.46", + "@types/jasmine": "2.5.36" }, "repository": {} } diff --git a/protractor.config.js b/protractor.config.js index 8b2250590..8d4e0416a 100644 --- a/protractor.config.js +++ b/protractor.config.js @@ -5,7 +5,7 @@ // // AND THEN EVERYTIME ... // 1. Compile with `tsc` -// 2. Make sure the test server (e.g., http-server: localhost:8080) is running. +// 2. Make sure the test server (e.g., lite-server: localhost:8080) is running. // 3. ./node_modules/.bin/protractor protractor.config.js // // To do all steps, try: `npm run e2e` @@ -49,8 +49,6 @@ exports.config = { // console.log('browser.params:' + JSON.stringify(browser.params)); jasmine.getEnv().addReporter(new Reporter( browser.params )) ; - global.sendKeys = sendKeys; - // Allow changing bootstrap mode to NG1 for upgrade tests global.setProtractorToNg1Mode = function() { browser.useAllAngular2AppRoots = false; @@ -66,16 +64,6 @@ exports.config = { } }; -// Hack - because of bug with protractor send keys -function sendKeys(element, str) { - return str.split('').reduce(function (promise, char) { - return promise.then(function () { - return element.sendKeys(char); - }); - }, element.getAttribute('value')); - // better to create a resolved promise here but ... don't know how with protractor; - } - // Custom reporter function Reporter(options) { var _defaultOutputFile = path.resolve(process.cwd(), './_test-output', 'protractor-results.txt'); diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts new file mode 100644 index 000000000..776902446 --- /dev/null +++ b/src/app/app.component.spec.ts @@ -0,0 +1,33 @@ +import { AppComponent } from './app.component'; + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +describe('AppComponent', function () { + let de: DebugElement; + let comp: AppComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AppComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + de = fixture.debugElement.query(By.css('h1')); + }); + + it('should create component', () => expect(comp).toBeDefined() ); + + it('should have expected

text', () => { + fixture.detectChanges(); + const h1 = de.nativeElement; + expect(h1.innerText).toMatch(/angular/i, + '

should say something about "Angular"'); + }); +}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 000000000..7fb173cd0 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: `

Hello {{name}}

`, +}) +export class AppComponent { name = 'Angular'; } diff --git a/app/app.module.ts b/src/app/app.module.ts similarity index 77% rename from app/app.module.ts rename to src/app/app.module.ts index 4f883fa15..357b003a5 100644 --- a/app/app.module.ts +++ b/src/app/app.module.ts @@ -4,8 +4,8 @@ import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; @NgModule({ - imports: [ BrowserModule ], + imports: [ BrowserModule ], declarations: [ AppComponent ], - bootstrap: [ AppComponent ] + bootstrap: [ AppComponent ] }) export class AppModule { } diff --git a/favicon.ico b/src/favicon.ico similarity index 100% rename from favicon.ico rename to src/favicon.ico diff --git a/index.html b/src/index.html similarity index 76% rename from index.html rename to src/index.html index c0b1c4431..832743558 100644 --- a/index.html +++ b/src/index.html @@ -2,6 +2,7 @@ Angular QuickStart + @@ -10,16 +11,15 @@ - - Loading... + Loading AppComponent content here ... diff --git a/app/main.ts b/src/main.ts similarity index 74% rename from app/main.ts rename to src/main.ts index 6af7a5b2a..311c44b76 100644 --- a/app/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app.module'; +import { AppModule } from './app/app.module'; platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 000000000..58e1a7d9a --- /dev/null +++ b/src/styles.css @@ -0,0 +1,5 @@ +h1 { + color: #369; + font-family: Arial, Helvetica, sans-serif; + font-size: 250%; +} diff --git a/src/systemjs-angular-loader.js b/src/systemjs-angular-loader.js new file mode 100644 index 000000000..8b1005444 --- /dev/null +++ b/src/systemjs-angular-loader.js @@ -0,0 +1,49 @@ +var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm; +var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g; +var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g; + +module.exports.translate = function(load){ + if (load.source.indexOf('moduleId') != -1) return load; + + var url = document.createElement('a'); + url.href = load.address; + + var basePathParts = url.pathname.split('/'); + + basePathParts.pop(); + var basePath = basePathParts.join('/'); + + var baseHref = document.createElement('a'); + baseHref.href = this.baseURL; + baseHref = baseHref.pathname; + + if (!baseHref.startsWith('/base/')) { // it is not karma + basePath = basePath.replace(baseHref, ''); + } + + load.source = load.source + .replace(templateUrlRegex, function(match, quote, url){ + var resolvedUrl = url; + + if (url.startsWith('.')) { + resolvedUrl = basePath + url.substr(1); + } + + return 'templateUrl: "' + resolvedUrl + '"'; + }) + .replace(stylesRegex, function(match, relativeUrls) { + var urls = []; + + while ((match = stringRegex.exec(relativeUrls)) !== null) { + if (match[2].startsWith('.')) { + urls.push('"' + basePath + match[2].substr(1) + '"'); + } else { + urls.push('"' + match[2] + '"'); + } + } + + return "styleUrls: [" + urls.join(', ') + "]"; + }); + + return load; +}; diff --git a/src/systemjs.config.extras.js b/src/systemjs.config.extras.js new file mode 100644 index 000000000..027dfe58c --- /dev/null +++ b/src/systemjs.config.extras.js @@ -0,0 +1,11 @@ +/** + * Add barrels and stuff + * Adjust as necessary for your application needs. + */ +// (function (global) { +// System.config({ +// packages: { +// // add packages here +// } +// }); +// })(this); diff --git a/systemjs.config.js b/src/systemjs.config.js similarity index 83% rename from systemjs.config.js rename to src/systemjs.config.js index 0ea776d8f..129704a37 100644 --- a/systemjs.config.js +++ b/src/systemjs.config.js @@ -11,7 +11,7 @@ // map tells the System loader where to look for things map: { // our app is within the app folder - app: 'app', + 'app': 'app', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', @@ -22,24 +22,23 @@ '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', - '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', // other libraries 'rxjs': 'npm:rxjs', - 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { app: { - main: './main.js', - defaultExtension: 'js' + defaultExtension: 'js', + meta: { + './*.js': { + loader: 'systemjs-angular-loader.js' + } + } }, rxjs: { defaultExtension: 'js' - }, - 'angular-in-memory-web-api': { - main: './index.js', - defaultExtension: 'js' } } }); diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 000000000..2c7260d1b --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + } +} diff --git a/styles.css b/styles.css deleted file mode 100644 index 054b417f6..000000000 --- a/styles.css +++ /dev/null @@ -1,142 +0,0 @@ -/* Master Styles */ -h1 { - color: #369; - font-family: Arial, Helvetica, sans-serif; - font-size: 250%; -} -h2, h3 { - color: #444; - font-family: Arial, Helvetica, sans-serif; - font-weight: lighter; -} -body { - margin: 2em; -} -body, input[text], button { - color: #888; - font-family: Cambria, Georgia; -} -a { - cursor: pointer; - cursor: hand; -} -button { - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} -button:disabled { - background-color: #eee; - color: #aaa; - cursor: auto; -} - -/* Navigation link styles */ -nav a { - padding: 5px 10px; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #607D8B; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.router-link-active { - color: #039be5; -} - -/* items class */ -.items { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 24em; -} -.items li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.items li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.items li.selected:hover { - background-color: #BBD8DC; - color: white; -} -.items .text { - position: relative; - top: -3px; -} -.items { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 24em; -} -.items li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.items li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.items li.selected { - background-color: #CFD8DC; - color: white; -} - -.items li.selected:hover { - background-color: #BBD8DC; -} -.items .text { - position: relative; - top: -3px; -} -.items .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} - -/* everywhere else */ -* { - font-family: Arial, Helvetica, sans-serif; -} diff --git a/typings.json b/typings.json deleted file mode 100644 index 146c8759d..000000000 --- a/typings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "globalDependencies": { - "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", - "core-js": "registry:dt/core-js#0.0.0+20160725163759", - "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", - "node": "registry:dt/node#6.0.0+20160831021119", - "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654" - } -} diff --git a/wallaby.js b/wallaby.js deleted file mode 100644 index acc34d35f..000000000 --- a/wallaby.js +++ /dev/null @@ -1,119 +0,0 @@ -// Configuration for the Wallaby Visual Studio Code testing extension -// https://marketplace.visualstudio.com/items?itemName=WallabyJs.wallaby-vscode -// Note: Wallaby is not open source and costs money - -module.exports = function () { - return { - files: [ - // System.js for module loading - {pattern: 'node_modules/systemjs/dist/system.js', instrument: false}, - {pattern: 'systemjs.config.js', instrument: false}, - {pattern: 'systemjs.config.extras.js', instrument: false}, - - // Polyfills - {pattern: 'node_modules/core-js/client/shim.min.js', instrument: false}, - {pattern: 'node_modules/reflect-metadata/Reflect.js', instrument: false}, - - // zone.js - {pattern: 'node_modules/zone.js/dist/zone.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/long-stack-trace-zone.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/proxy.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/sync-test.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/jasmine-patch.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/async-test.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/fake-async-test.js', instrument: false}, - - // application (but not specs) loaded via module imports - {pattern: 'app/**/*+(ts|html|css)', load: false}, - {pattern: 'app/**/*.spec.ts', ignore: true}, - - {pattern: 'testing/**/*+(ts|html|css)', load: false}, - ], - - tests: [ - {pattern: 'app/**/*.spec.ts', load: false} - ], - - middleware: function (app, express) { - app.use('/node_modules', express.static(require('path').join(__dirname, 'node_modules'))); - }, - - testFramework: 'jasmine', - - debug: true, - - bootstrap: bootstrap - }; -}; - -// Like karma-test-shim.js -function bootstrap (wallaby) { - wallaby.delayStart(); - - System.config({ - // Extend usual application package list with test folder - packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, - - // Assume npm: is set in `paths` in systemjs.config - // Map the angular testing umd bundles - map: { - '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', - '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', - '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js', - '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js', - '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', - '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js', - '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js', - '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js', - }, - }); - - System.import('systemjs.config.js') - .then(importSystemJsExtras) - .then(initTestBed) - .then(initTesting); - - /** Optional SystemJS configuration extras. Keep going w/o it */ - function importSystemJsExtras(){ - return System.import('systemjs.config.extras.js') - .catch(function(reason) { - console.log( - 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.' - ); - console.log(reason); - }); - } - - function initTestBed(){ - return Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing') - ]) - - .then(function (providers) { - var coreTesting = providers[0]; - var browserTesting = providers[1]; - - coreTesting.TestBed.initTestEnvironment( - browserTesting.BrowserDynamicTestingModule, - browserTesting.platformBrowserDynamicTesting()); - }) - } - - // Load all spec files and start wallaby - function initTesting () { - return Promise.all( - wallaby.tests.map(function (specFile) { - return System.import(specFile); - }) - ) - .then(function () { - wallaby.start(); - }) - .catch(function (e) { - setTimeout(function () { - throw e; - }, 0); - }); - } -}