diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000000..d1c2c2b349
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,30 @@
+module.exports = {
+ "globals": {
+ "describe": true,
+ "beforeEach": true,
+ "it": true,
+ "expect": true
+ },
+ "env": {
+ "node": true
+ },
+ "extends": "eslint:recommended",
+ "rules": {
+ "indent": [
+ "error",
+ 2
+ ],
+ "linebreak-style": [
+ "error",
+ "unix"
+ ],
+ "quotes": [
+ "error",
+ "single"
+ ],
+ "semi": [
+ "error",
+ "always"
+ ]
+ }
+};
\ No newline at end of file
diff --git a/.firebaserc b/.firebaserc
new file mode 100644
index 0000000000..2ef123c5bd
--- /dev/null
+++ b/.firebaserc
@@ -0,0 +1,6 @@
+{
+ "projects": {
+ "live": "angular-io",
+ "ngdocsdev": "ngdocsdev"
+ }
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b6d52bd9b9..679af37907 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,10 +21,12 @@ _.*
**/resources/zips
public/docs/xref-*.*
_zip-output
-www
+www*
npm-debug*.log*
*.plnkr.html
plnkr.html
+*.eplnkr.html
+eplnkr.html
*plnkr.no-link.html
public/docs/*/latest/guide/cheatsheet.json
protractor-results.txt
diff --git a/.nvmrc b/.nvmrc
index 7ed6ff82de..1e8b314962 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-5
+6
diff --git a/.travis.yml b/.travis.yml
index 755b29e6a7..c8c12208bc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@ dist: trusty
sudo: required
language: node_js
node_js:
- - "5"
+ - "6"
os:
- linux
env:
@@ -10,20 +10,20 @@ env:
- DBUS_SESSION_BUS_ADDRESS=/dev/null
- DISPLAY=:99.0
- CHROME_BIN=chromium-browser
- - LATEST_RELEASE=2.0.0-rc.4
+ # using SHA instead of version to fix build-compile issue
+ - LATEST_RELEASE=cfc12c653970c9ad6d807a6a8ebff58edbc568a0
- TASK_FLAGS="--dgeni-log=warn"
- # - TASK_FLAGS=""
matrix:
- TASK=lint
- TASK="run-e2e-tests --fast" SCRIPT=examples-install.sh
- TASK="run-e2e-tests --fast" SCRIPT=examples-install-preview.sh
- - TASK=build-compile SCRIPT=deploy-install.sh WAIT="travis_wait 50"
- - TASK=build-compile SCRIPT=deploy-install-preview.sh WAIT="travis_wait 50"
+ - TASK=build-compile SCRIPT=deploy-install.sh WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v"
+ - TASK=build-compile SCRIPT=deploy-install-preview.sh WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v"
matrix:
fast_finish: true
allow_failures:
- env: TASK="run-e2e-tests --fast" SCRIPT=examples-install-preview.sh
- - env: TASK=build-compile SCRIPT=deploy-install-preview.sh WAIT="travis_wait 50"
+ - env: TASK=build-compile SCRIPT=deploy-install-preview.sh WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v"
before_install:
- source ./scripts/env-set.sh
- ./scripts/before-install.sh
@@ -34,3 +34,4 @@ before_script:
- sh -e /etc/init.d/xvfb start
script:
- $WAIT gulp $TASK $TASK_FLAGS
+ - if [[ -n "$POST_SCRIPT" ]]; then ./scripts/$POST_SCRIPT; fi
diff --git a/README.md b/README.md
index 0731e20550..c291cccc6e 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Angular.io
[![Build Status][travis-badge]][travis-badge-url]
-Angular.io is site for Angular 2 **documentation** .
+Angular.io is site for Angular **documentation** .
This site also includes links to other helpful angular resources including
Angular 2, Angular 1, Angular Material, and AngularFire.
@@ -21,16 +21,18 @@ Filing issues is helpful but **pull requests** that improve the docs are even be
Learn how to [contribute to Angular.io](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
+> **IMPORTANT**: Do _NOT_ make changes to cached files under `public/docs/ts/_cache`. Cached files are updated through a separate workflow.
+
## Development Setup
This site relies heavily on node and npm.
1. Make sure you are using at least node v.5+ and latest npm;
if not install [nvm](https://github.com/creationix/nvm) to get node going on your machine.
-1. install these npm packages *globally*: `npm install -g harp gulp`
+1. Install these npm packages *globally*: `npm install -g harp gulp`
-1. clone this repo and the [angular source code repo](https://github.com/angular/angular) to the same parent directory.
-The two cloned repo directories must be sibling.
+1. Clone this repo, the [angular/angular source code repo](https://github.com/angular/angular), and the [dart-lang/angular2 source code repo](https://github.com/dart-lang/angular2) to the same parent directory.
+The three cloned repo directories must be siblings, with the latter two repo directories named **angular** and **angular-dart**, respectively.
1. cd into root directory `angular.io/`
@@ -71,11 +73,11 @@ If you are only going to work on a specific part of the docs, such as the dev gu
## Code Sample Development
All documentation is supported by sample code and plunkers.
-Such code resides in the `public/docs/_examples` directory, under chapter-specific directories, further divided by language track.
+Such code resides in the `public/docs/_examples` directory, under page-specific directories, further divided by language track.
For example, the TypeScript QuickStart sample is in `public/docs/_examples/quickstart/ts`.
-All samples are in a consistent directory structure using the same styles and the same npm packages, including the latest release of Angular 2.
+All samples are in a consistent directory structure using the same styles and the same npm packages, including the latest release of Angular.
This consistency is possible in part thanks to gulp-driven tooling.
To run the samples locally and confirm that they work properly,
take the following extra steps to prepare the environment:
diff --git a/gulpfile.js b/gulpfile.js
index c6e15ae13f..80b6839cde 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -45,7 +45,8 @@ var STYLES_SOURCE_PATH = path.join(TOOLS_PATH, 'styles-builder/less');
var docShredder = require(path.resolve(TOOLS_PATH, 'doc-shredder/doc-shredder'));
var exampleZipper = require(path.resolve(TOOLS_PATH, '_example-zipper/exampleZipper'));
-var plunkerBuilder = require(path.resolve(TOOLS_PATH, 'plunker-builder/plunkerBuilder'));
+var regularPlunker = require(path.resolve(TOOLS_PATH, 'plunker-builder/regularPlunker'));
+var embeddedPlunker = require(path.resolve(TOOLS_PATH, 'plunker-builder/embeddedPlunker'));
var fsUtils = require(path.resolve(TOOLS_PATH, 'fs-utils/fsUtils'));
const isSilent = !!argv.silent;
@@ -72,9 +73,10 @@ var _apiShredOptions = {
logLevel: _dgeniLogLevel
};
+const relDartDocApiDir = path.join('doc', 'api');
var _apiShredOptionsForDart = {
lang: 'dart',
- examplesDir: path.resolve(ngPathFor('dart'), 'examples'),
+ examplesDir: path.resolve(ngPathFor('dart'), 'example'),
fragmentsDir: path.join(DOCS_PATH, '_fragments/_api'),
zipDir: path.join(RESOURCES_PATH, 'zips/api'),
logLevel: _dgeniLogLevel
@@ -89,15 +91,12 @@ var _excludeMatchers = _excludePatterns.map(function(excludePattern){
var _exampleBoilerplateFiles = [
'.editorconfig',
'a2docs.css',
- 'karma.conf.js',
- 'karma-test-shim.js',
'package.json',
'styles.css',
'systemjs.config.js',
'tsconfig.json',
'tslint.json',
- 'typings.json',
- 'wallaby.js'
+ 'typings.json'
];
var _exampleDartWebBoilerPlateFiles = ['a2docs.css', 'styles.css'];
@@ -118,22 +117,35 @@ var _styleLessName = 'a2docs.less';
// or a regex pattern to match any one of 'ts', 'js', or 'dart'.
// Default: 'ts|js' except for the "full site build" tasks (see below),
// for which it is 'all'.
-//
-var lang, langs, buildDartApiDocs = false;
+
+// langs and skipLangs partition ['ts', 'js', 'dart'].
+var lang, langs, skipLangs, buildDartApiDocs = false;
function configLangs(langOption) {
- const fullSiteBuildTasks = ['build-compile', 'check-serve', 'check-deploy'];
+ const fullSiteBuildTasks = ['build-compile', 'check-deploy', 'harp-compile'];
const buildAllDocs = argv['_'] &&
fullSiteBuildTasks.some((task) => argv['_'].indexOf(task) >= 0);
const langDefault = buildAllDocs ? 'all' : 'ts|js';
- lang = (langOption || langDefault).toLowerCase();
- if (lang === 'all') lang = 'ts|js|dart';
- langs = lang.match(/\w+/g); // the languages in `lang` as an array
- gutil.log('Building docs for: ' + lang);
+ if (langOption === '') {
+ lang = '';
+ langs = [];
+ } else {
+ lang = (langOption || langDefault).toLowerCase();
+ if (lang === 'all') lang = 'ts|js|dart';
+ langs = lang.match(/\w+/g); // the languages in `lang` as an array
+ }
+ gutil.log(`Building docs for: [${langs}]`);
if (langs.indexOf('dart') >= 0) {
buildDartApiDocs = true;
// For Dart, be proactive about checking for the repo
checkAngularProjectPath(ngPathFor('dart'));
+ } else {
+ argv.pub = false;
}
+ skipLangs = [];
+ ['ts', 'js', 'dart'].forEach(lang => {
+ if (langs.indexOf(lang) < 0) skipLangs.push(lang);
+ });
+ gutil.log(`Skipped languages: [${skipLangs}]`);
}
configLangs(argv.lang);
@@ -344,10 +356,15 @@ function runE2eDartTests(appDir, outputFile) {
gutil.log('http-server failed to launch over ' + deployDir);
return false;
}
- var pubUpgradeSpawnInfo = spawnExt('pub', ['upgrade'], { cwd: appDir });
- var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) {
- return spawnExt('pub', ['build'], { cwd: appDir }).promise;
- });
+ if (argv.pub === false) {
+ var prepPromise = Promise.resolve(true);
+ gutil.log('Skipping pub upgrade and pub build (--no-pub flag present)');
+ } else {
+ var pubUpgradeSpawnInfo = spawnExt('pub', ['upgrade'], { cwd: appDir });
+ var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) {
+ return spawnExt('pub', ['build'], { cwd: appDir }).promise;
+ });
+ }
return runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile);
}
@@ -441,10 +458,10 @@ gulp.task('add-example-boilerplate', function(done) {
// copies boilerplate files to locations
// where an example app is found
gulp.task('_copy-example-boilerplate', function (done) {
- if (!argv.fast) buildStyles(copyExampleBoilerplate, done);
+ return argv.fast ? done() : buildStyles(copyExampleBoilerplate, done);
});
-//Builds Angular 2 Docs CSS file from Bootstrap npm LESS source
+//Builds Angular Docs CSS file from Bootstrap npm LESS source
//and copies the result to the _examples folder to be included as
//part of the example boilerplate.
function buildStyles(cb, done){
@@ -504,23 +521,42 @@ gulp.task('remove-example-boilerplate', function() {
// either release or current build packages
// Examples:
// gulp install-example-angular --build // use current build packages
+// gulp install-example-angular --build=2.0.0-b43f954 // use tagged packages
// gulp install-example-angular // restore release packages
+//
+// Find the tags here: https://github.com/angular/core-builds/releases
gulp.task('install-example-angular', installExampleAngular);
function installExampleAngular() {
var sources;
var template;
var libs = [
- 'core', 'common', 'compiler',
+ 'core', 'common', 'compiler', 'compiler-cli',
'platform-browser', 'platform-browser-dynamic',
'forms', 'http', 'router', 'upgrade'];
+ var build = argv.build;
+ if (build) {
+ if (typeof build === 'string') {
+ build = (build[0]==='#' ? '' : '#') + build;
+ } else {
+ build = '';
+ }
+ } else{
+ build = 'npm';
+ }
// Like: "angular/core-builds" or "@angular/core"
- sources = libs.map( lib => argv.build ? `angular/${lib}-builds` : `@angular/${lib}`);
+ sources = libs.map( lib => {
+ return build === 'npm'
+ ? `@angular/${lib}`
+ : `git+https://github.com/angular/${lib}-builds${build}`;
+ });
+
+ if (argv.build) { sources.push('@angular/tsc-wrapped');} // tsc-wrapped needed for builds
sources.push('@angular/router-deprecated');
- gutil.log(`Installing Angular npm packages from ${argv.build ? 'BUILD' : 'RELEASE'}`);
+ gutil.log(`Installing Angular packages from ${build === 'npm' ? 'NPM' : 'BUILD ' + build}`);
var spawnInfo = spawnExt('rm', ['-rf', 'node_modules/@angular'], { cwd: EXAMPLES_PATH});
return spawnInfo.promise
@@ -594,8 +630,10 @@ gulp.task('build-dart-api-docs', ['_shred-api-examples', 'dartdoc'], function()
return buildApiDocsForDart();
});
+// Using the --build flag will use systemjs.config.plunker.build.js (for preview builds)
gulp.task('build-plunkers', ['_copy-example-boilerplate'], function() {
- return plunkerBuilder.buildPlunkers(EXAMPLES_PATH, LIVE_EXAMPLES_PATH, { errFn: gutil.log, build: argv.build });
+ regularPlunker.buildPlunkers(EXAMPLES_PATH, LIVE_EXAMPLES_PATH, { errFn: gutil.log, build: argv.build });
+ return embeddedPlunker.buildPlunkers(EXAMPLES_PATH, LIVE_EXAMPLES_PATH, { errFn: gutil.log, build: argv.build, targetSelf: argv.targetSelf });
});
gulp.task('build-dart-cheatsheet', [], function() {
@@ -604,20 +642,20 @@ gulp.task('build-dart-cheatsheet', [], function() {
gulp.task('dartdoc', ['pub upgrade'], function() {
const ngRepoPath = ngPathFor('dart');
- if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'doc'))) {
- gutil.log('Skipping dartdoc: --fast flag enabled and "doc" dir exists');
+ if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, relDartDocApiDir))) {
+ gutil.log(`Skipping dartdoc: --fast flag enabled and api dir exists (${relDartDocApiDir})`);
return true;
}
checkAngularProjectPath(ngRepoPath);
const topLevelLibFilePath = path.resolve(ngRepoPath, 'lib', 'angular2.dart');
const tmpPath = topLevelLibFilePath + '.disabled';
- if (!fs.existsSync(topLevelLibFilePath)) throw new Error(`Missing file: ${topLevelLibFilePath}`);
- fs.renameSync(topLevelLibFilePath, tmpPath);
+ renameIfExistsSync(topLevelLibFilePath, tmpPath);
gutil.log(`Hiding top-level angular2 library: ${topLevelLibFilePath}`);
- const dartdoc = spawnExt('dartdoc', ['--output', 'doc/api', '--add-crossdart'], { cwd: ngRepoPath});
+ // Remove dartdoc '--add-crossdart' flag while we are fixing links to API pages.
+ const dartdoc = spawnExt('dartdoc', ['--output', relDartDocApiDir], { cwd: ngRepoPath});
return dartdoc.promise.finally(() => {
gutil.log(`Restoring top-level angular2 library: ${topLevelLibFilePath}`);
- fs.renameSync(tmpPath, topLevelLibFilePath);
+ renameIfExistsSync(tmpPath, topLevelLibFilePath);
})
});
@@ -678,12 +716,12 @@ gulp.task('git-changed-examples', ['_shred-devguide-examples'], function(){
});
});
-gulp.task('harp-compile', [], function() {
+gulp.task('harp-compile', () => {
return harpCompile()
});
-gulp.task('serve', [], function() {
- // Harp will serve files from workspace.
+gulp.task('harp-serve', () => {
+ // Harp will watch and serve workspace files.
const cmd = 'npm run harp -- server .';
gutil.log('Launching harp server (over project files)');
gutil.log(` > ${cmd}`);
@@ -691,7 +729,7 @@ gulp.task('serve', [], function() {
return execPromise(cmd);
});
-gulp.task('serve-www', [], function() {
+gulp.task('serve-www', () => {
// Serve generated site.
return execPromise('npm run live-server ./www');
});
@@ -700,13 +738,6 @@ gulp.task('build-compile', ['build-docs'], function() {
return harpCompile();
});
-gulp.task('check-serve', ['build-docs'], function() {
- return harpCompile().then(function() {
- gutil.log('Launching live-server over ./www');
- return execPromise('npm run live-server ./www');
- });
-});
-
gulp.task('check-deploy', ['build-docs'], function() {
return harpCompile().then(function() {
gutil.log('compile ok');
@@ -802,7 +833,7 @@ gulp.task('_shred-clean-devguide', function(cb) {
gulp.task('_shred-api-examples', ['_shred-clean-api'], function() {
const promises = [];
gutil.log('Shredding API examples for languages: ' + langs.join(', '));
- langs.forEach((lang) => {
+ langs.forEach(lang => {
if (lang === 'js') return; // JS is handled via TS.
checkAngularProjectPath(ngPathFor(lang));
const options = lang == 'dart' ? _apiShredOptionsForDart : _apiShredOptions;
@@ -852,26 +883,40 @@ gulp.task('lint', function() {
function harpCompile() {
// Supposedly running in production makes harp faster
// and less likely to drown in node_modules.
- env({
- vars: { NODE_ENV: "production" }
- });
+ env({ vars: { NODE_ENV: "production" } });
gutil.log("NODE_ENV: " + process.env.NODE_ENV);
+ if(skipLangs && fs.existsSync('www') && backupApiHtmlFilesExist('www')) {
+ gutil.log(`Harp site recompile: skipping recompilation of API docs for [${skipLangs}]`);
+ gutil.log(`API docs will be copied from existing www folder.`)
+ del.sync('www-backup'); // remove existing backup if it exists
+ renameIfExistsSync('www', 'www-backup');
+ } else {
+ gutil.log(`Harp full site compile, including API docs for all languages.`);
+ if (skipLangs)
+ gutil.log(`Ignoring API docs skip set (${skipLangs}) because full ` +
+ `site has not been built yet or some API HTML files are missing.`);
+ }
+
var deferred = Q.defer();
gutil.log('running harp compile...');
showHideExampleNodeModules('hide');
+ showHideApiDir('hide');
var spawnInfo = spawnExt('npm',['run','harp', '--', 'compile', '.', './www' ]);
spawnInfo.promise.then(function(x) {
gutil.log("NODE_ENV: " + process.env.NODE_ENV);
showHideExampleNodeModules('show');
+ showHideApiDir('show');
if (x !== 0) {
deferred.reject(x)
} else {
+ restoreApiHtml();
deferred.resolve(x);
}
}).catch(function(e) {
gutil.log("NODE_ENV: " + process.env.NODE_ENV);
showHideExampleNodeModules('show');
+ showHideApiDir('show');
deferred.reject(e);
});
return deferred.promise;
@@ -970,6 +1015,54 @@ function showHideExampleNodeModules(showOrHide) {
}
}
+// Show/hide the API docs harp source folder for every lang in skipLangs.
+function showHideApiDir(showOrHide) {
+ skipLangs.forEach(lang => {
+ _showHideApiDir(lang, showOrHide);
+ });
+}
+
+// Rename the API docs harp source folder for lang to/from 'api' to '_api-tmp-foo'.
+function _showHideApiDir(lang, showOrHide) {
+ const vers = 'latest';
+ const basePath = path.join(DOCS_PATH, lang, vers);
+ const apiDirPath = path.join(basePath, 'api');
+ const disabledApiDirPath = path.join(basePath, '_api-tmp-hide-from-jade');
+ const args = showOrHide == 'hide'
+ ? [apiDirPath, disabledApiDirPath]
+ : [disabledApiDirPath, apiDirPath];
+ renameIfExistsSync(...args);
+}
+
+// For each lang in skipLangs, copy the API dir from www-backup to www.
+function restoreApiHtml() {
+ const vers = 'latest';
+ skipLangs.forEach(lang => {
+ const relApiDir = path.join('docs', lang, vers, 'api');
+ const wwwApiSubdir = path.join('www', relApiDir);
+ const backupApiSubdir = path.join('www-backup', relApiDir);
+ if (fs.existsSync(backupApiSubdir) || argv.forceSkipApi !== true) {
+ gutil.log(`cp ${backupApiSubdir} ${wwwApiSubdir}`)
+ fs.copySync(backupApiSubdir, wwwApiSubdir);
+ }
+ });
+}
+
+// For each lang in skipLangs, ensure API dir exists in www-backup
+function backupApiHtmlFilesExist(folderName) {
+ const vers = 'latest';
+ var result = 1;
+ skipLangs.forEach(lang => {
+ const relApiDir = path.join('docs', lang, vers, 'api');
+ const backupApiSubdir = path.join(folderName, relApiDir);
+ if (!fs.existsSync(backupApiSubdir)) {
+ gutil.log(`WARNING: API docs HTML folder doesn't exist: ${backupApiSubdir}`);
+ result = 0;
+ }
+ });
+ return result;
+}
+
// Copies fileNames into destPaths, setting the mode of the
// files at the destination as optional_destFileMode if given.
// returns a promise
@@ -1069,11 +1162,16 @@ function watchAndSync(options, cb) {
var browserSync = require('browser-sync').create();
browserSync.init({proxy: 'localhost:9000'});
+ // When using the --focus=name flag, only **/name/**/*.* example files and
+ // **/name.jade files are watched. This is useful for performance reasons.
+ // Example: gulp serve-and-sync --focus=architecture
+ var focus = argv.focus;
+
if (options.devGuide) {
- devGuideExamplesWatch(_devguideShredOptions, browserSync.reload);
+ devGuideExamplesWatch(_devguideShredOptions, browserSync.reload, focus);
}
if (options.devGuideJade) {
- devGuideSharedJadeWatch( { jadeDir: DOCS_PATH}, browserSync.reload);
+ devGuideSharedJadeWatch( { jadeDir: DOCS_PATH}, browserSync.reload, focus);
}
if (options.apiDocs) {
apiSourceWatch(browserSync.reload);
@@ -1088,11 +1186,10 @@ function watchAndSync(options, cb) {
// returns a promise;
function askDeploy() {
-
prompt.start();
var schema = {
name: 'shouldDeploy',
- description: 'Deploy to Firebase? (y/n): ',
+ description: 'Deploy to Firebase? (y/n)',
type: 'string',
pattern: /Y|N|y|n/,
message: "Respond with either a 'y' or 'n'",
@@ -1114,7 +1211,7 @@ function filterOutExcludedPatterns(fileNames, excludeMatchers) {
}
function apiSourceWatch(postBuildAction) {
- var srcPattern = [path.join(ANGULAR_PROJECT_PATH, 'modules/@angular/src/**/*.*')];
+ var srcPattern = [path.join(ANGULAR_PROJECT_PATH, 'modules/@angular/**/*.*')];
gulp.watch(srcPattern, {readDelay: 500}, function (event, done) {
gutil.log('API source changed');
gutil.log('Event type: ' + event.event); // added, changed, or deleted
@@ -1141,8 +1238,9 @@ function apiExamplesWatch(postShredAction) {
});
}
-function devGuideExamplesWatch(shredOptions, postShredAction) {
- var includePattern = path.join(shredOptions.examplesDir, '**/*.*');
+function devGuideExamplesWatch(shredOptions, postShredAction, focus) {
+ var watchPattern = focus ? '**/' + focus + '/**/*.*' : '**/*.*';
+ var includePattern = path.join(shredOptions.examplesDir, watchPattern);
// removed this version because gulp.watch has the same glob issue that dgeni has.
// var excludePattern = '!' + path.join(shredOptions.examplesDir, '**/node_modules/**/*.*');
// gulp.watch([includePattern, excludePattern], {readDelay: 500}, function (event, done) {
@@ -1158,8 +1256,9 @@ function devGuideExamplesWatch(shredOptions, postShredAction) {
});
}
-function devGuideSharedJadeWatch(shredOptions, postShredAction) {
- var includePattern = path.join(DOCS_PATH, '**/*.jade');
+function devGuideSharedJadeWatch(shredOptions, postShredAction, focus) {
+ var watchPattern = focus ? '**/' + focus + '.jade' : '**/*.jade';
+ var includePattern = path.join(DOCS_PATH, watchPattern);
// removed this version because gulp.watch has the same glob issue that dgeni has.
// var excludePattern = '!' + path.join(shredOptions.jadeDir, '**/node_modules/**/*.*');
// gulp.watch([includePattern, excludePattern], {readDelay: 500}, function (event, done) {
@@ -1235,15 +1334,14 @@ function buildDartCheatsheet() {
function buildApiDocsForDart() {
- const apiDir = 'api';
const vers = 'latest';
const dab = require('./tools/dart-api-builder/dab')(ANGULAR_IO_PROJECT_PATH);
const log = dab.log;
log.level = _dgeniLogLevel;
const dabInfo = dab.dartPkgConfigInfo;
- dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, apiDir);
- dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'doc', apiDir);
+ dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, 'api');
+ dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), relDartDocApiDir);
// Exclude API entries for developer/internal libraries. Also exclude entries for
// the top-level catch all "angular2" library (otherwise every entry appears twice).
dabInfo.excludeLibRegExp = new RegExp(/^(?!angular2)|\.testing|_|codegen|^angular2$/);
@@ -1455,3 +1553,12 @@ function checkAngularProjectPath(_ngPath) {
if (fs.existsSync(ngPath)) return;
throw new Error('API related tasks require the angular2 repo to be at ' + ngPath);
}
+
+function renameIfExistsSync(oldPath, newPath) {
+ if (fs.existsSync(oldPath)) {
+ gutil.log(`Rename: mv ${oldPath} ${newPath}`);
+ fs.renameSync(oldPath, newPath);
+ } else {
+ gutil.log(`renameIfExistsSync cannot rename, path not found: ${oldPath}`);
+ }
+}
diff --git a/harp.json b/harp.json
index 629364440f..4a8328d35e 100644
--- a/harp.json
+++ b/harp.json
@@ -85,7 +85,7 @@
"picture": "/resources/images/bios/tobias.jpg",
"twitter": "tbosch1009",
"website": "https://plus.google.com/+TobiasBosch",
- "bio": "Tobias Bosch is a software engineer at Google. He is part of the Angular core team and works on Angular 2.",
+ "bio": "Tobias Bosch is a software engineer at Google. He is part of the Angular core team and works on Angular.",
"type": "Google"
},
@@ -184,7 +184,7 @@
"picture": "/resources/images/bios/hansl.jpg",
"twitter": "hanslatwork",
"website": "http://www.codingatwork.com/",
- "bio": "Hans is a software engineer at Google on the Angular team and was previously at Slack. He works everyday to help make it easier for everyone to create beautiful, consistent web applications using Angular2, using Material Design components and the CLI tool.",
+ "bio": "Hans is a software engineer at Google on the Angular team and was previously at Slack. He works everyday to help make it easier for everyone to create beautiful, consistent web applications using Angular, using Material Design components and the CLI tool.",
"type": "Google"
},
@@ -316,6 +316,12 @@
"bio": "Max Sills is Angular's Open Source lawyer.",
"type": "Google"
},
+ "shannon": {
+ "name": "Shannon Ayres",
+ "picture": "/resources/images/bios/shannon.jpg",
+ "bio": "Shannon is a technical editor in Developer Relations at Google. She loves movies, especially Sunset Boulevard, and her favorite TV show is The Walking Dead. Her mission: Righting wrong writing!",
+ "type": "Google"
+ },
"pawel": {
"name": "Pawel Kozlowski",
@@ -354,7 +360,7 @@
"picture": "/resources/images/bios/marclaval.jpg",
"twitter": "marclaval",
"website": "https://github.com/mlaval",
- "bio": "Marc is a manager at Amadeus where he leads the team in charge of developing and recommending UI frameworks for the company. He is also an open source developer and a contributor to Angular 2.",
+ "bio": "Marc is a manager at Amadeus where he leads the team in charge of developing and recommending UI frameworks for the company. He is also an open source developer and a contributor to Angular.",
"type": "Community"
},
@@ -372,7 +378,7 @@
"picture": "/resources/images/bios/patrick-stapleton.jpg",
"twitter": "gdi2290",
"website": "https://angularclass.com",
- "bio": "Also know as PatrickJS where JS stands for his middle and last names. Patrick is very active in Open-Source with over 4,300+ contributions in the last year alone on projects such as Angular2, AngularJS, FalcorJS, Docker, Bootstrap, gulp, and redis to name a few. He is also working on the development of Angular 2 server-side rendering as Universal Angular 2 and teaching Modern Web Development at AngularClass. He was previously the CTO of Keychain Logistics, a HackReactor Instructor and Alum.",
+ "bio": "Also know as PatrickJS where JS stands for his middle and last names. Patrick is very active in Open-Source with over 4,300+ contributions in the last year alone on projects such as Angular2, AngularJS, FalcorJS, Docker, Bootstrap, gulp, and redis to name a few. He is also working on the development of Angular server-side rendering as Universal Angular and teaching Modern Web Development at AngularClass. He was previously the CTO of Keychain Logistics, a HackReactor Instructor and Alum.",
"type": "Community"
},
@@ -391,6 +397,7 @@
"bio": "Ward is an all-around developer with JavaScript, node, and .net chops. He's a frequent conference speaker and podcaster, trainer, Google Developer Expert for Angular, Microsoft MVP, and PluralSight author. He is also president of IdeaBlade, an enterprise software consulting firm and the makers of breeze.js. He would like to get more sleep and spend more time in the mountains.",
"type": "Community"
},
+
"johnpapa": {
"name": "John Papa",
"picture": "/resources/images/bios/john-papa.jpg",
@@ -399,6 +406,7 @@
"bio": "John is a Google Developer Expert, Microsoft Regional Director and MVP, frequent author of courses for Pluralsight, a former technology Evangelist for Microsoft front end teams, and author of the popular Angular Style Guide. He can often be found speaking around the world at keynotes and sessions for many conferences. You can always find John at johnpapa.net or on twitter at @john_papa.",
"type": "Community"
},
+
"martinstaffa": {
"name": "Martin Staffa",
"picture": "/resources/images/bios/martinstaffa.jpg",
@@ -406,6 +414,7 @@
"bio": "Martin is an English major turned web developer who loves frontend stuff. He's been part of the Angular 1 team since 2014. If you can't find him roaming the Github issue queues, he's probably out with his camera somewhere.",
"type": "Community"
},
+
"topherfangio": {
"name": "Topher Fangio",
"picture": "/resources/images/bios/topherfangio.jpg",
@@ -414,6 +423,7 @@
"bio": "Topher loves the web and how it empowers new forms of creativity, connection and business. He is currently a core contributor on the Angular Material project and sometimes blogs about random things.",
"type": "Community"
},
+
"filipesilva": {
"name": "Filipe Silva",
"picture": "/resources/images/bios/filipe-silva.jpg",
@@ -422,6 +432,7 @@
"bio": "Filipe is a passion-driven developer that always strives for the most elegant solution for each problem. He is currently an author for Angular.io, a core contributor for Angular-CLI and senior front end engineer at KonnectAgain. When not busy going through PRs, you can find him scouring reddit for new dinner recipes to cook or enjoying a craft beer in Dublin.",
"type": "Community"
},
+
"teropa": {
"name": "Tero Parviainen",
"picture": "/resources/images/bios/teropa.jpg",
@@ -430,15 +441,17 @@
"bio": "Tero is an independent software developer and writer. He's been building web applications for his whole professional career, and has almost figured out how to do vertical centering in CSS.",
"type": "Community"
},
- "deborah": {
+
+ "deborah": {
"name": "Deborah Kurata",
"picture": "/resources/images/bios/deborah.jpg",
"twitter": "deborahkurata",
"website": "http://blogs.msmvps.com/deborahk/",
"bio": "Deborah is an independent software developer and author. She is author of several Pluralsight courses including: 'Angular 2: Getting Started'",
"type": "Community"
- },
- "jesusrodriguez": {
+ },
+
+ "jesusrodriguez": {
"name": "Jesús Rodríguez",
"picture": "/resources/images/bios/jesus-rodriguez.jpg",
"twitter": "foxandxss",
@@ -446,6 +459,7 @@
"bio": "Jesus is an open source lover, a book author and editor, and AngularUI lead developer. He is currently a core contributor to the UI Bootstrap project.",
"type": "Community"
},
+
"torgeirhelgevold": {
"name": "Torgeir Helgevold",
"picture": "/resources/images/bios/torgeirhelgevold.jpg",
@@ -454,6 +468,7 @@
"bio": "Torgeir (Tor) is a front-end architect with a passion for JavaScript development. He is also an author for angular.io and an active tech blogger.",
"type": "Community"
},
+
"fatimaremtullah": {
"name": "Fatima Remtullah",
"picture": "/resources/images/bios/fatima.jpg",
@@ -462,6 +477,7 @@
"bio": "Fatima is a Product Designer and Front-End Developer. When she is not nerding out she is probably eating an abundance of cookies.",
"type": "Community"
},
+
"eric": {
"name": "Eric Jimenez",
"picture": "/resources/images/bios/eric.jpg",
@@ -470,6 +486,7 @@
"bio": "Eric is a gamer, writer, and programmer.",
"type": "Community"
},
+
"mikeryan": {
"name": "Mike Ryan",
"picture": "/resources/images/bios/mikeryan.jpg",
@@ -477,7 +494,8 @@
"website": "https://medium.com/@MikeRyan52",
"bio": "Mike Ryan is a Software Engineer at Synapse Wireless, working on solving challenging problems in the internet-of-things space. He is an advocate of reactive programming and a core contributor to the ngrx project.",
"type": "Community"
- },
+ },
+
"rex": {
"name": "Rex Ye",
"picture": "/resources/images/bios/rex.jpg",
@@ -485,6 +503,7 @@
"bio": "Rex is a full-stack developer. He maintains the Angular.cn website with his old pal Ralph Wang and he plays a key role in bridging between the Chinese Angular community and the world-wide community. He loves playing with flashy new technologies and enjoys the challenge of mastering new skills. His biggest challenge to date is figuring out how to sooth a crying 4-month-old baby.",
"type": "Community"
},
+
"ralph": {
"name": "Ralph Wang",
"picture": "/resources/images/bios/ralph.jpg",
@@ -492,6 +511,7 @@
"bio": "Ralph(Zhicheng Wang) is a senior consultant at ThoughWorks and also a GDE. He is a technology enthusiast and he is a passionate advocate of “Simplicity, Professionalism and Sharing”. In his eighteen years of R&D career, he worked as tester, R&D engineer, project manager, product manager and CTO. He is looking forward to the birth of his baby.",
"type": "Community"
},
+
"brandonroberts": {
"name": "Brandon Roberts",
"picture": "/resources/images/bios/brandonroberts.jpg",
@@ -500,12 +520,28 @@
"bio": "Brandon is a front-end developer for a game studio developing web applications for STEM-based learning games. He is also a natural born troubleshooter who helps solve Angular issues on Github and Gitter support channels, particularly dealing with routing. He is also a member of the Angular docs team.",
"type": "Community"
},
+
"crisbeto": {
"name": "Kristiyan Kostadinov",
"picture": "/resources/images/bios/crisbeto.jpg",
"website": "http://crisbeto.com/",
"bio": "Kristiyan is a front-end developer, passionate open-source contributor and a core team member on Angular Material.",
"type": "Community"
+ },
+
+ "gkalpak": {
+ "name": "Georgios Kalpakas",
+ "picture": "/resources/images/bios/gkalpak.jpg",
+ "website": "https://github.com/gkalpak",
+ "bio": "George is a Software Engineer with a passion for chess, robotics and automating stuff. He has a strong need to know how things work (so if you already know, he'd love to have a talk with you). He has been a member of the AngularJS team since 2014. When not doing geeky stuff, he is probably trying to convince his wife and kids to apply programming principles in real life. (Or is it the other way around?)",
+ "type": "Community"
+ },
+ "kapunahelewong": {
+ "name": "Kapunahele Wong",
+ "picture": "/resources/images/bios/kapunahelewong.jpg",
+ "website": " https://github.com/kapunahelewong",
+ "bio": "Kapunahele is a front-end developer at Capital One. She loves just about anything to do with JavaScript, Angular and electronics. She enjoys mapping Hawaiian star names and constellations to Western ones and loves dancing native Hawaiian hula.",
+ "type": "Community"
}
}
}
diff --git a/package.json b/package.json
index 2e848d239c..5ab4ceea6d 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "angular.io",
"version": "0.0.0",
"private": true,
- "description": "Angular 2 documentation",
+ "description": "Angular documentation",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
@@ -36,20 +36,19 @@
"cross-spawn": "^4.0.0",
"del": "^2.2.0",
"dgeni": "^0.4.0",
- "dgeni-packages": "^0.13.1",
+ "dgeni-packages": "^0.16.0",
"diff": "^2.1.3",
"fs-extra": "^0.30.0",
"globby": "^4.0.0",
- "grunt-sass": "^1.2.0",
"gulp": "^3.5.6",
"gulp-env": "0.4.0",
- "gulp-sass": "^2.3.2",
"gulp-less": "^3.1.0",
+ "gulp-sass": "^2.3.2",
"gulp-task-listing": "^1.0.1",
"gulp-tslint": "^5.0.0",
"gulp-util": "^3.0.6",
"gulp-watch": "^4.3.4",
- "harp": "^0.20.3",
+ "harp": "0.21.0-pre.1",
"html2jade": "^0.8.4",
"indent-string": "^2.1.0",
"jasmine-core": "^2.3.4",
@@ -71,7 +70,7 @@
"protractor": "^3.0.0",
"q": "^1.4.1",
"tree-kill": "^1.0.0",
- "tslint": "^3.2.2",
+ "tslint": "^3.15.1",
"yargs": "^4.7.1"
},
"dependencies": {
diff --git a/public/_data.json b/public/_data.json
index 1232f0a1de..29ba83dab4 100644
--- a/public/_data.json
+++ b/public/_data.json
@@ -2,7 +2,7 @@
"index": {
"hero": "home",
"title": "One framework.",
- "subtitle": "Mobile and desktop."
+ "subtitle": "Mobile & desktop."
},
"features": {
diff --git a/public/_includes/_footer.jade b/public/_includes/_footer.jade
index a186b59ca8..1cb22a54d2 100644
--- a/public/_includes/_footer.jade
+++ b/public/_includes/_footer.jade
@@ -8,7 +8,7 @@ else
- var styleguide = "/docs/ts/latest/styleguide.html"
.main-footer
- nav.background-blue-grey-900.grid-fluid
+ nav.background-midnight.grid-fluid
.c3.main-footer-branding
.logo-inverse-large
@@ -17,7 +17,7 @@ else
h3.text-headline RESOURCES
ul.text-body
- // TODO: (ericjim) make a libraries page to showcase all angular 2 libraries
+ // TODO: (ericjim) make a libraries page to showcase all angular libraries
//li Libraries
li About
li Books & Training
@@ -51,7 +51,7 @@ else
ul.text-body
li 中文版
- footer(class="background-steel")
- small.text-caption Powered by Google ©2010-2016. Code licensed under an MIT-style License . Documentation licensed under CC BY 4.0 .
- a(aria-label="View Style Guide" href=styleguide title="Style Guide" class="styleguide-trigger text-snow")
+ footer(class="background-midnight")
+ small.text-caption Powered by Google ©2010-2016. Code licensed under an MIT-style License . Documentation licensed under CC BY 4.0 .
+ a(aria-label="View Style Guide" href=styleguide title="Style Guide" class="styleguide-trigger")
span.icon-favorite
diff --git a/public/_includes/_head-include.jade b/public/_includes/_head-include.jade
index 2e46febe96..a0c7429fa1 100644
--- a/public/_includes/_head-include.jade
+++ b/public/_includes/_head-include.jade
@@ -12,7 +12,7 @@ if title == "Angular"
else if language
title #{title} - #{language}
else
- title #{title} - Angular 2
+ title #{title} - Angular
meta(charset="utf-8")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
@@ -22,14 +22,14 @@ meta(name="robots" content="all")
meta(name="referrer" content="origin")
meta(name="viewport" id="viewport" content="width=device-width, initial-scale=1")
-meta(property="og:title" content="Angular 2")
+meta(property="og:title" content="Angular")
meta(property="og:image" content="/resources/images/logos/standard/shield-large.png")
meta(property="og:image:type" content="image/png")
meta(property="og:image:width" content="184")
meta(property="og:image:height" content="200")
meta(property="og:description" content="#{description}")
-meta(itemprop="name" content="Angular 2")
+meta(itemprop="name" content="Angular")
meta(itemprop="description" content="#{description}")
meta(itemprop="image" content="https://angular.io/resources/images/logos/standard/shield-large.png")
@@ -57,4 +57,4 @@ link(rel="stylesheet" href="/resources/css/main.css")
-
\ No newline at end of file
+
diff --git a/public/_includes/_hero-home.jade b/public/_includes/_hero-home.jade
index a1d34a334a..4aa964bfce 100644
--- a/public/_includes/_hero-home.jade
+++ b/public/_includes/_hero-home.jade
@@ -1,13 +1,18 @@
-header(class="background-sky")
- .hero.background-superhero-paper.is-large
- h1.text-headline.hero-logo #{title} #{subtitle}
+header(class="background-sky l-relative")
- .hero-cta
- a(href="/docs/ts/latest/quickstart.html" class="md-raised button button-large button-plain" md-button) Get Started
+ .hero.background-superhero-paper.is-large
+ img(class="hero-logo" src='/resources/images/logos/angular2/angular.svg')
+ h1.text-headline #{title} #{subtitle}
+ a(href="/docs/ts/latest/quickstart.html" class="hero-cta md-raised button button-large button-plain" md-button) Get Started
- .banner.banner-floaty
- .banner-ng-annoucement
- div(class="banner-text" align="center")
- p Join us for AngularConnect in London, UK this September!
- div(class="banner-button")
- a(href="http://angularconnect.com/?utm_source=angular&utm_medium=banner&utm_campaign=angular-banner" target="_blank" class="button md-button") Register now
\ No newline at end of file
+
+ announcement-bar
+ .announcement-bar-slide.clearfix
+ img(src="/resources/images/logos/angular2/angular-logo-banner.png")
+ p Angular 2.0 Final Release Now Live!
+ a(href="http://angularjs.blogspot.com/2016/09/angular2-final.html" target="_blank" class="button " + "md-button") Learn More
+
+ .announcement-bar-slide.clearfix
+ img(src="/resources/images/logos/ng-europe/ng-europe-logo.png")
+ p Join us for ng-europe in Paris , France this October!
+ a(href="https://ngeurope.org/?utm_source=angular&utm_medium=banner&utm_campaign=angular-banner" target="_blank" class="button md-button") Register now
\ No newline at end of file
diff --git a/public/_includes/_hero.jade b/public/_includes/_hero.jade
index 3a27ed9d2b..efeb8b0480 100644
--- a/public/_includes/_hero.jade
+++ b/public/_includes/_hero.jade
@@ -13,27 +13,27 @@
if current.path[4] && current.path[3] == 'api'
- var textFormat = 'is-standard-case'
-header(class="hero background-sky", style=fixHeroCss ? "height:auto" : "")
- div(class="inner-header")
- h1(class="hero-title text-display-1 #{textFormat}") #{headerTitle}
- if useBadges
- span(class="badges")
- if docType
- span(class="status-badge").
- #{renamer(capitalize(docType))}
- if stability
- span(layout="row" class="status-badge")
- // badge circle is filled based on stability by matching a css selector in _hero.scss
- span(class="status-circle status-#{stability}")
- span Stability: #{capitalize(stability)}
- if security
- span(class="status-badge security-risk-badge").
- Security Risk
+header.hero.background-sky
+ h1(class="hero-title #{textFormat}") #{headerTitle}
+
+ if useBadges
+ if stability
+ span(class="badge is-#{stability}").
+ #{capitalize(stability)}
+ if security
+ span(class="badge is-deprecated").
+ Security Risk
+
+ //CLEAR FLOAT ELEMENTS
+ .clear
if subtitle
- h2.hero-subtitle.text-subhead #{subtitle}
+ h2.hero-subtitle #{subtitle}
+
+ else if docType
+ h2.hero-subtitle #{renamer(capitalize(docType))}
+
+
+if current.path[3] == 'api' && current.path[1] == 'dart'
+ block breadcrumbs
- else if current.path[3] == 'api' && current.path[1] == 'dart'
- block breadcrumbs
- else if current.path[0] == "docs"
- != partial("_version-dropdown")
diff --git a/public/_includes/_main-nav.jade b/public/_includes/_main-nav.jade
index 272a54d702..677d081d8d 100644
--- a/public/_includes/_main-nav.jade
+++ b/public/_includes/_main-nav.jade
@@ -1,15 +1,14 @@
- var language = current.path[1] || 'ts'
- if (language !== 'ts' || language !== 'js' || language !== 'dart') { language = 'ts'; }
-md-toolbar(class="main-nav background-regal l-pinned-top l-layer-5",scroll-y-offset-element)
- nav
- h1 Angular by Google
+nav(class="main-nav l-pinned-top l-layer-5", scroll-y-offset-element)
+ h1 Angular by Google
- button(class="main-nav-button main-nav-mobile-trigger l-right" aria-label="View Menu" ng-click="appCtrl.toggleMainMenu($event)" md-button) Site Menu
+ button(class="main-nav-button main-nav-mobile-trigger l-right" aria-label="View Menu" ng-click="appCtrl.toggleMainMenu($event)" md-button) Site Menu
- ul(ng-class="appCtrl.showMainNav ? 'is-visible' : ''")
- li.l-left Features
- li.l-left Docs
- li.l-left Events
- li.l-left News
- li.l-right Get Started
+ ul(ng-class="appCtrl.showMainNav ? 'is-visible' : ''")
+ li.l-left Features
+ li.l-left Docs
+ li.l-left Events
+ li.l-left News
+ li.l-right Get Started
diff --git a/public/_includes/_scripts-include.jade b/public/_includes/_scripts-include.jade
index 9b4cd8048b..f02d7cce14 100644
--- a/public/_includes/_scripts-include.jade
+++ b/public/_includes/_scripts-include.jade
@@ -28,6 +28,7 @@ script(src="/resources/js/directives/cheatsheet.js")
script(src="/resources/js/directives/api-list.js")
script(src="/resources/js/directives/bio.js")
script(src="/resources/js/directives/bold.js")
+script(src="/resources/js/directives/announcement-bar.js")
script(src="/resources/js/directives/code.js")
script(src="/resources/js/directives/copy.js")
script(src="/resources/js/directives/code-tabs.js")
@@ -64,4 +65,4 @@ script(src="//www.gstatic.com/feedback/api.js" type="text/javascript")
script.
- (function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}})(document,"script","twitter-wjs");
\ No newline at end of file
+ (function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}})(document,"script","twitter-wjs");
diff --git a/public/_includes/_util-fns.jade b/public/_includes/_util-fns.jade
index 152fbe4bfd..0d10a5b301 100644
--- a/public/_includes/_util-fns.jade
+++ b/public/_includes/_util-fns.jade
@@ -38,6 +38,15 @@
//- Location of sample code
- var _liveLink = 'live link';
+//- NgModule related
+- var _AppModuleVsAppComp = 'AppModule'
+- var _appModuleTsVsAppCompTs = 'app/app.module.ts'
+- var _appModuleTsVsMainTs = 'app/app.module.ts'
+- var _bootstrapModule = 'bootstrapModule'
+- var _moduleVsComp = 'module'
+- var _moduleVsRootComp = 'module'
+- var _platformBrowserDynamicVsBootStrap = 'platformBrowserDynamic'
+
//- Other
- var _truthy = 'truthy';
- var _falsey = 'falsey';
@@ -74,14 +83,14 @@ mixin makeExample(_filePath, region, _title, stylePatterns)
- var format = attributes.format || defaultFormat;
- if (attributes.format === '.') format = '';
- var avoid = !!attributes.avoid;
+ - var avoidClass = avoid ? 'is-anti-pattern' : '';
- if (title)
- if (avoid)
- .example-title.avoid AVOID: #{title}
- else
- .example-title #{title}
- code-example(language="#{language}" format="#{format}")
- != styleString(frag, stylePatterns)
+ div(class="code-example #{avoidClass}")
+ if (title)
+ header
+ h4 #{title}
+ code-example(language="#{language}" format="#{format}")
+ != styleString(frag, stylePatterns)
//- Like makeExample, but: (1) doesn't show line numbers. (2) If region
//- is omitted and title is 'foo (r)' then region is taken as 'r'.
@@ -89,14 +98,14 @@ mixin makeExample(_filePath, region, _title, stylePatterns)
//- ending is given or is just (), then the title will be suffixed with
//- either "(excerpt)", or "(#{_region})" when _region is defined.
mixin makeExcerpt(_filePath, _region, _title, stylePatterns)
- - var matches = _filePath.match(/(.*)\s+\(([\w ]*)\)$/);
+ - var matches = _filePath.match(/(.*)\s+\(([^\)]*)\)$/);
- var parenText;
- if (matches) { _filePath = matches[1]; parenText = matches[2]; }
- var adjustments = adjustExamplePathAndTitle({filePath:_filePath, title:_title});
- var filePath = adjustments.filePath;
- var title = adjustments.title;
- - var region = _region || parenText;
- - var excerpt = !region || parenText === '' ? 'excerpt' : parenText || region;
+ - var region = _region || (_region === '' ? '' : parenText);
+ - var excerpt = parenText || region || 'excerpt';
- if (title) title = title + ' (' + excerpt + ')';
+makeExample(filePath, region, title, stylePatterns)(format='.')
@@ -133,76 +142,78 @@ mixin makeJson( filePath, jsonConfig, title, stylePatterns)
- var json = unescapeHtml(frag);
- var jsonExtract = extractJson(json, jsonConfig);
- var avoid = !!attributes.avoid;
+ - var avoidClass = avoid ? 'is-anti-pattern' : '';
- if (title)
- if (avoid)
- .example-title.avoid #{title}
- else
- .example-title #{title}
- code-example(language="#{language}" format="#{format}")
- if (jsonExtract == 'ERROR')
- err ERROR: Unable to extract json using config: "#{jsonConfig.toString()}"
- else
- != styleString(jsonExtract, stylePatterns)
+ div(class="code-example #{avoidClass}")
+ if (title)
+ header
+ h4 #{title}
+ code-example(language="#{language}" format="#{format}")
+ if (jsonExtract == 'ERROR')
+ err ERROR: Unable to extract json using config: "#{jsonConfig.toString()}"
+ else
+ != styleString(jsonExtract, stylePatterns)
-- // Open (and close) an explanation
. See QuickStart
-script.
- function why(id, backTo) {
- var id = "#"+id;
- var el = document.querySelector(id);
- el.hidden=el.hidden=!el.hidden;
+if !jade2ng
+ //- Open (and close) an explanation
. See QuickStart
+ script.
+ function why(id, backTo) {
+ var id = "#"+id;
+ var el = document.querySelector(id);
+ el.hidden=el.hidden=!el.hidden;
- if (el.hidden && backTo){
- // the next line is required to work around a bug in WebKit (Chrome / Safari)
- location.href = "#";
- location.href = "#" + backTo;
+ if (el.hidden && backTo){
+ // the next line is required to work around a bug in WebKit (Chrome / Safari)
+ location.href = "#";
+ location.href = "#" + backTo;
+ }
}
- }
-script.
- function verbose(isVerbose) {
- isVerbose = !! isVerbose;
- var el = document.querySelector('button.verbose.off');
- el.style.display = isVerbose ? 'block' : 'none';
- var el = document.querySelector('button.verbose.on');
- el.style.display = isVerbose ? 'none' : 'block';
+ script.
+ function verbose(isVerbose) {
+ isVerbose = !! isVerbose;
+ var el = document.querySelector('button.verbose.off');
+ el.style.display = isVerbose ? 'block' : 'none';
+ var el = document.querySelector('button.verbose.on');
+ el.style.display = isVerbose ? 'none' : 'block';
- CCSStylesheetRuleStyle('main','.l-verbose-section', 'display',
- isVerbose ? 'block' : 'none');
- }
+ CCSStylesheetRuleStyle('main','.l-verbose-section', 'display',
+ isVerbose ? 'block' : 'none');
+ }
-script.
- function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
- /* returns the value of the element style of the rule in the stylesheet
- * If no value is given, reads the value
- * If value is given, the value is changed and returned
- * If '' (empty string) is given, erases the value.
- * The browser will apply the default one
- *
- * string stylesheet: part of the .css name to be recognized, e.g. 'default'
- * string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td'
- * string style: camelCase element style, e.g. 'fontSize'
- * string value optional : the new value
- */
- var CCSstyle = undefined, rules, sheet;
- for(var m in document.styleSheets){
- sheet = document.styleSheets[m];
- if(sheet.href && sheet.href.indexOf(stylesheet) != -1){
- rules = sheet[document.all ? 'rules' : 'cssRules'];
- for(var n in rules){
- console.log(rules[n].selectorText);
- if(rules[n].selectorText == selectorText){
- CCSstyle = rules[n].style;
- break;
+ script.
+ function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
+ /* returns the value of the element style of the rule in the stylesheet
+ * If no value is given, reads the value
+ * If value is given, the value is changed and returned
+ * If '' (empty string) is given, erases the value.
+ * The browser will apply the default one
+ *
+ * string stylesheet: part of the .css name to be recognized, e.g. 'default'
+ * string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td'
+ * string style: camelCase element style, e.g. 'fontSize'
+ * string value optional : the new value
+ */
+ var CCSstyle = undefined, rules, sheet;
+ for(var m in document.styleSheets){
+ sheet = document.styleSheets[m];
+ if(sheet.href && sheet.href.indexOf(stylesheet) != -1){
+ rules = sheet[document.all ? 'rules' : 'cssRules'];
+ for(var n in rules){
+ console.log(rules[n].selectorText);
+ if(rules[n].selectorText == selectorText){
+ CCSstyle = rules[n].style;
+ break;
+ }
+ }
+ break;
}
}
- break;
- }
+ if(value == undefined)
+ return CCSstyle[style]
+ else
+ return CCSstyle[style] = value
}
- if(value == undefined)
- return CCSstyle[style]
- else
- return CCSstyle[style] = value
- }
+
//---------------------------------------------------------------------------------------------------------
//- Converts the given project-relative path (like 'app/main.ts')
//- to a doc folder relative path (like 'quickstart/ts/app/main.ts')
@@ -213,8 +224,8 @@ script.
- // E.g. of a project relative path is 'app/main.ts'
- if (ex.title === null || ex.title === undefined) {
- // Title is not given so take it to be ex.filePath.
-- // Is title like styles.1.css? Then drop the '.1' qualifier:
-- var matches = ex.filePath.match(/^(.*)\.\d(\.\w+)$/);
+- // Title like styles.1.css or foo_1.dart? Then drop the '.1' or '_1' qualifier:
+- var matches = ex.filePath.match(/^(.*)[\._]\d(\.\w+)$/);
- ex.title = matches ? matches[1] + matches[2] : ex.filePath;
- }
- ex.filePath = getExampleName() + '/' + _docsFor + '/' + ex.filePath;
@@ -289,7 +300,7 @@ script.
- } else {
- // ``` gets translated to
.....
and we need
- // to remove this from the fragment prefix is 11 long and suffix is 13 long
-- frag = frag.substring(11, frag.length-13);
+- frag = jade2ng ? frag : frag.substring(11, frag.length-13);
- // Uncomment next line for debugging.
- // frag = "FileName: " + fullFileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs() + "\n" + frag;
- return frag;
diff --git a/public/_includes/_version-dropdown.jade b/public/_includes/_version-dropdown.jade
index 6bba60975a..2b5162b391 100644
--- a/public/_includes/_version-dropdown.jade
+++ b/public/_includes/_version-dropdown.jade
@@ -5,7 +5,7 @@
- var version = ''
- var page = ''
-
+//- Replace _ underscores with . dots
if current.path[2]
- var version = current.path[2].replace(/\_+/gm, ".")
@@ -33,32 +33,31 @@ else if current.path[3]
else
- var page = current.path[3] + '.html'
-
+//- VERSION TREE CREATOR MIXIN
mixin tree(directory, urlPrefix, name, latest)
- ul
- for val, semvar in directory
- if semvar !== '.git' && semvar !== '_data'
- - var libVersion = (semvar == "latest") ? latest : semvar.replace(/\_+/gm, ".")
- li
#{name} #{libVersion}
+ for val, semvar in directory
+ if semvar !== '.git' && semvar !== '_data'
+ - var libVersion = (semvar == "latest") ? latest : semvar.replace(/\_+/gm, ".")
+ li
#{name} #{libVersion}
-
+//- BUTTON TITLE GENERATION
if language == 'ts'
if version == "latest"
- - var title = 'Angular 2 for TypeScript'
+ - var title = 'Angular for TypeScript'
else
- var title = 'Angular ' + version + ' for TypeScript'
if language == 'js'
if version == "latest"
- - var title = 'Angular 2 for JavaScript'
+ - var title = 'Angular for JavaScript'
else
- var title = 'Angular ' + version + ' for JavaScript'
if language == 'dart'
if version == "latest"
- - var title = 'Angular 2 for Dart'
+ - var title = 'Angular for Dart'
else
- var title = 'Angular ' + version + ' for Dart'
@@ -69,7 +68,9 @@ nav.dropdown
div(class="overlay ng-hide" ng-click="appCtrl.toggleVersionMenu($event)" ng-show="appCtrl.showMenu")
- div(class="dropdown-menu" ng-class="appCtrl.showMenu ? 'is-visible' : ''")
- mixin tree(public.docs.ts, "/docs/ts", "Angular 2 for TypeScript")
- mixin tree(public.docs.js, "/docs/js", "Angular 2 for JavaScript")
- mixin tree(public.docs.dart, "/docs/dart", "Angular 2 for Dart")
+ ul(class="dropdown-menu" ng-class="appCtrl.showMenu ? 'is-visible' : ''")
+ mixin tree(public.docs.ts, "/docs/ts", "Angular for TypeScript")
+ mixin tree(public.docs.js, "/docs/js", "Angular for JavaScript")
+ //- Disable cross-language link for API entry pages (but keep for top API search page):
+ if ! (current.path[3] === 'api' && public.docs[current.path[1]][current.path[2]][current.path[3]][current.path[4]])
+ mixin tree(public.docs.dart, "/docs/dart", "Angular for Dart")
diff --git a/public/contribute.jade b/public/contribute.jade
index 002c8da4a1..994d46a36d 100644
--- a/public/contribute.jade
+++ b/public/contribute.jade
@@ -3,11 +3,11 @@
p We'd love for you to contribute to our source code and to make Angular projects even better.
.l-sub-section
- h3 Angular 2
+ h3 Angular
- p Angular 2 is a next generation mobile and desktop application development platform.
+ p Angular is a next generation mobile and desktop application development platform.
- a(href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md" class="button" md-button) Contribute to Angular 2
+ a(href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md" class="button" md-button) Contribute to Angular
.l-sub-section
h3 Angular for JavaScript or Dart
diff --git a/public/docs/_examples/_protractor/package.json b/public/docs/_examples/_protractor/package.json
index eca5cae41f..1e12742c38 100644
--- a/public/docs/_examples/_protractor/package.json
+++ b/public/docs/_examples/_protractor/package.json
@@ -13,7 +13,9 @@
"license": "ISC",
"devDependencies": {
"protractor": "^3.3.0",
- "typings": "^1.0.4"
+ "typings": "^1.0.4",
+ "ts-node": "^1.3.0",
+ "typescript": "^2.0.2"
},
"repository": {}
}
diff --git a/public/docs/_examples/_protractor/protractor.config.js b/public/docs/_examples/_protractor/protractor.config.js
index fc68f03b98..2452bea764 100644
--- a/public/docs/_examples/_protractor/protractor.config.js
+++ b/public/docs/_examples/_protractor/protractor.config.js
@@ -26,7 +26,7 @@ exports.config = {
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
- // For angular2 tests
+ // For angular tests
useAllAngular2AppRoots: true,
// Base URL for application server
diff --git a/public/docs/_examples/animations/e2e-spec.ts b/public/docs/_examples/animations/e2e-spec.ts
index e2e9b64b9b..31eefbf345 100644
--- a/public/docs/_examples/animations/e2e-spec.ts
+++ b/public/docs/_examples/animations/e2e-spec.ts
@@ -4,7 +4,7 @@
* The tests here basically just checking that the end styles
* of each animation are in effect.
*
- * Relies on the Angular 2 testability only becoming stable once
+ * Relies on the Angular testability only becoming stable once
* animation(s) have finished.
*
* Ideally we'd use https://developer.mozilla.org/en-US/docs/Web/API/Document/getAnimations
@@ -289,6 +289,19 @@ describe('Animation Tests', () => {
});
});
+ describe('callbacks', () => {
+ it('fires a callback on start and done', () => {
+ addActiveHero();
+ browser.manage().logs().get('browser').then((logs) => {
+ const animationMessages = logs.filter((log) => {
+ return log.message.indexOf('Animation') !== -1 ? true : false;
+ });
+
+ expect(animationMessages.length).toBeGreaterThan(0);
+ });
+ });
+ });
+
function addActiveHero(sleep?: number) {
sleep = sleep || 500;
element(by.buttonText('Add active hero')).click();
diff --git a/public/docs/_examples/animations/ts/app/hero-list-auto.component.ts b/public/docs/_examples/animations/ts/app/hero-list-auto.component.ts
index 621d144a1f..39d69f2c91 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-auto.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-auto.component.ts
@@ -17,7 +17,7 @@ import { Heroes } from './hero.service';
template: `
+ [@shrinkOut]="'in'">
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-basic.component.ts b/public/docs/_examples/animations/ts/app/hero-list-basic.component.ts
index 4bd42e1616..c74ef90b8b 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-basic.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-basic.component.ts
@@ -27,7 +27,7 @@ import { Heroes } from './hero.service';
template: `
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-combined-transitions.component.ts b/public/docs/_examples/animations/ts/app/hero-list-combined-transitions.component.ts
index 09f1137d82..7fe59f9ab9 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-combined-transitions.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-combined-transitions.component.ts
@@ -20,7 +20,7 @@ import { Heroes } from './hero.service';
template: `
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-enter-leave-states.component.ts b/public/docs/_examples/animations/ts/app/hero-list-enter-leave-states.component.ts
index f9cb6ef31c..6e6fe6cd3f 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-enter-leave-states.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-enter-leave-states.component.ts
@@ -18,7 +18,7 @@ import { Heroes } from './hero.service';
+ [@heroState]="hero.state">
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-enter-leave.component.ts b/public/docs/_examples/animations/ts/app/hero-list-enter-leave.component.ts
index e9c195d610..a37efb6464 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-enter-leave.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-enter-leave.component.ts
@@ -17,7 +17,7 @@ import { Heroes } from './hero.service';
template: `
+ [@flyInOut]="'in'">
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-groups.component.ts b/public/docs/_examples/animations/ts/app/hero-list-groups.component.ts
index d6753c1ac6..70fb11d426 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-groups.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-groups.component.ts
@@ -17,7 +17,7 @@ import { Heroes } from './hero.service';
template: `
+ [@flyInOut]="'in'">
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-inline-styles.component.ts b/public/docs/_examples/animations/ts/app/hero-list-inline-styles.component.ts
index c38750297a..e22bd3121f 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-inline-styles.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-inline-styles.component.ts
@@ -19,7 +19,7 @@ import { Heroes } from './hero.service';
template: `
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-multistep.component.ts b/public/docs/_examples/animations/ts/app/hero-list-multistep.component.ts
index 0af3dfd167..adea35047c 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-multistep.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-multistep.component.ts
@@ -6,7 +6,8 @@ import {
style,
animate,
transition,
- keyframes
+ keyframes,
+ AnimationTransitionEvent
} from '@angular/core';
import { Heroes } from './hero.service';
@@ -14,14 +15,18 @@ import { Heroes } from './hero.service';
@Component({
moduleId: module.id,
selector: 'hero-list-multistep',
+ // #docregion template
template: `
+ (@flyInOut.start)="animationStarted($event)"
+ (@flyInOut.done)="animationDone($event)"
+ [@flyInOut]="'in'">
{{hero.name}}
`,
+ // #enddocregion template
styleUrls: ['hero-list.component.css'],
/* The element here always has the state "in" when it
* is present. We animate two transitions: From void
@@ -54,4 +59,12 @@ import { Heroes } from './hero.service';
})
export class HeroListMultistepComponent {
@Input() heroes: Heroes;
+
+ animationStarted(event: AnimationTransitionEvent) {
+ console.warn('Animation started: ', event);
+ }
+
+ animationDone(event: AnimationTransitionEvent) {
+ console.warn('Animation done: ', event);
+ }
}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-timings.component.ts b/public/docs/_examples/animations/ts/app/hero-list-timings.component.ts
index bba68095a6..07fdcfb828 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-timings.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-timings.component.ts
@@ -16,7 +16,7 @@ import { Heroes } from './hero.service';
template: `
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/app/hero-list-twoway.component.ts b/public/docs/_examples/animations/ts/app/hero-list-twoway.component.ts
index 7ec8060ee7..d5c9b2a3dd 100644
--- a/public/docs/_examples/animations/ts/app/hero-list-twoway.component.ts
+++ b/public/docs/_examples/animations/ts/app/hero-list-twoway.component.ts
@@ -20,7 +20,7 @@ import { Heroes } from './hero.service';
template: `
{{hero.name}}
diff --git a/public/docs/_examples/animations/ts/index.html b/public/docs/_examples/animations/ts/index.html
index 9e36248524..76a7b93356 100644
--- a/public/docs/_examples/animations/ts/index.html
+++ b/public/docs/_examples/animations/ts/index.html
@@ -7,7 +7,7 @@
-
+
diff --git a/public/docs/_examples/animations/ts/plnkr.json b/public/docs/_examples/animations/ts/plnkr.json
index 5a4139282b..4fface319e 100644
--- a/public/docs/_examples/animations/ts/plnkr.json
+++ b/public/docs/_examples/animations/ts/plnkr.json
@@ -1,5 +1,5 @@
{
- "description": "Angular 2 Animations",
+ "description": "Angular Animations",
"files":[
"!**/*.d.ts",
"!**/*.js"
diff --git a/public/docs/_examples/architecture/dart/pubspec.yaml b/public/docs/_examples/architecture/dart/pubspec.yaml
index 4da6837c0b..e2e648537b 100644
--- a/public/docs/_examples/architecture/dart/pubspec.yaml
+++ b/public/docs/_examples/architecture/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/architecture/dart/web/index.html b/public/docs/_examples/architecture/dart/web/index.html
index a422e64542..840f107c53 100644
--- a/public/docs/_examples/architecture/dart/web/index.html
+++ b/public/docs/_examples/architecture/dart/web/index.html
@@ -1,7 +1,7 @@
- Architecture of Angular 2
+ Architecture of Angular
diff --git a/public/docs/_examples/architecture/e2e-spec.ts b/public/docs/_examples/architecture/e2e-spec.ts
index 54bf9be8f2..0bdcdd0069 100644
--- a/public/docs/_examples/architecture/e2e-spec.ts
+++ b/public/docs/_examples/architecture/e2e-spec.ts
@@ -10,7 +10,7 @@ class Hero {
describe('Architecture', () => {
- const expectedTitle = 'Architecture of Angular 2';
+ const expectedTitle = 'Architecture of Angular';
const expectedH2 = ['Hero List', 'Sales Tax Calculator'];
beforeAll(() => browser.get(''));
diff --git a/public/docs/_examples/architecture/ts/app/backend.service.ts b/public/docs/_examples/architecture/ts/app/backend.service.ts
index a49de94fde..e47cfc8ace 100644
--- a/public/docs/_examples/architecture/ts/app/backend.service.ts
+++ b/public/docs/_examples/architecture/ts/app/backend.service.ts
@@ -13,7 +13,7 @@ const HEROES = [
export class BackendService {
constructor(private logger: Logger) {}
- getAll(type: Type): PromiseLike {
+ getAll(type: Type): PromiseLike {
if (type === Hero) {
// TODO get from the database
return Promise.resolve(HEROES);
diff --git a/public/docs/_examples/architecture/ts/app/mini-app.ts b/public/docs/_examples/architecture/ts/app/mini-app.ts
index 8a35a607a2..b064428be3 100644
--- a/public/docs/_examples/architecture/ts/app/mini-app.ts
+++ b/public/docs/_examples/architecture/ts/app/mini-app.ts
@@ -13,7 +13,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'my-app',
- template: 'Welcome to Angular 2'
+ template: 'Welcome to Angular'
})
export class AppComponent {
constructor(logger: Logger) {
diff --git a/public/docs/_examples/architecture/ts/index.html b/public/docs/_examples/architecture/ts/index.html
index e365c39f02..090bd17c7b 100644
--- a/public/docs/_examples/architecture/ts/index.html
+++ b/public/docs/_examples/architecture/ts/index.html
@@ -1,7 +1,7 @@
- Architecture of Angular 2
+ Architecture of Angular
diff --git a/public/docs/_examples/architecture/ts/mini-app.html b/public/docs/_examples/architecture/ts/mini-app.html
index a17a191e90..ecb7dd21ae 100644
--- a/public/docs/_examples/architecture/ts/mini-app.html
+++ b/public/docs/_examples/architecture/ts/mini-app.html
@@ -1,7 +1,7 @@
- Architecture of Angular 2
+ Architecture of Angular
diff --git a/public/docs/_examples/architecture/ts/plnkr.json b/public/docs/_examples/architecture/ts/plnkr.json
index 3acf69014c..9a4180a9d4 100644
--- a/public/docs/_examples/architecture/ts/plnkr.json
+++ b/public/docs/_examples/architecture/ts/plnkr.json
@@ -1,5 +1,5 @@
{
- "description": "Intro to Angular2",
+ "description": "Intro to Angular",
"files":[
"!**/*.d.ts",
"!**/*.js",
diff --git a/public/docs/_examples/attribute-directives/dart/pubspec.yaml b/public/docs/_examples/attribute-directives/dart/pubspec.yaml
index 2afe4114d8..79904bff12 100644
--- a/public/docs/_examples/attribute-directives/dart/pubspec.yaml
+++ b/public/docs/_examples/attribute-directives/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.1.ts b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.1.ts
index 4cacc0d22e..7e81cb736f 100644
--- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.1.ts
+++ b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.1.ts
@@ -1,10 +1,10 @@
/* tslint:disable:no-unused-variable */
// #docregion
-import { Directive, ElementRef, Input } from '@angular/core';
+import { Directive, ElementRef, Input, Renderer } from '@angular/core';
@Directive({ selector: '[myHighlight]' })
export class HighlightDirective {
- constructor(el: ElementRef) {
- el.nativeElement.style.backgroundColor = 'yellow';
+ constructor(el: ElementRef, renderer: Renderer) {
+ renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'yellow');
}
}
diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts
index 8dec85912e..aa8f08752d 100644
--- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts
+++ b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts
@@ -1,6 +1,6 @@
/* tslint:disable:no-unused-variable */
// #docregion
-import { Directive, ElementRef, HostListener, Input } from '@angular/core';
+import { Directive, ElementRef, HostListener, Input, Renderer } from '@angular/core';
@Directive({
selector: '[myHighlight]'
@@ -8,9 +8,7 @@ import { Directive, ElementRef, HostListener, Input } from '@angular/core';
export class HighlightDirective {
// #docregion ctor
- private el: HTMLElement;
-
- constructor(el: ElementRef) { this.el = el.nativeElement; }
+ constructor(private el: ElementRef, private renderer: Renderer) { }
// #enddocregion ctor
// #docregion mouse-methods, host
@@ -28,7 +26,7 @@ export class HighlightDirective {
// #enddocregion host
private highlight(color: string) {
- this.el.style.backgroundColor = color;
+ this.renderer.setElementStyle(this.el.nativeElement, 'backgroundColor', color);
}
// #enddocregion mouse-methods
diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts
index 2ebcd3a995..618ac3ade3 100644
--- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts
+++ b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts
@@ -1,6 +1,6 @@
// #docplaster
// #docregion full
-import { Directive, ElementRef, HostListener, Input } from '@angular/core';
+import { Directive, ElementRef, HostListener, Input, Renderer } from '@angular/core';
@Directive({
selector: '[myHighlight]'
@@ -8,9 +8,8 @@ import { Directive, ElementRef, HostListener, Input } from '@angular/core';
// #docregion class
export class HighlightDirective {
private _defaultColor = 'red';
- private el: HTMLElement;
- constructor(el: ElementRef) { this.el = el.nativeElement; }
+ constructor(private el: ElementRef, private renderer: Renderer) { }
// #enddocregion class
// #docregion defaultColor
@@ -34,7 +33,7 @@ export class HighlightDirective {
}
private highlight(color: string) {
- this.el.style.backgroundColor = color;
+ this.renderer.setElementStyle(this.el.nativeElement, 'backgroundColor', color);
}
}
// #enddocregion class
diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.module.ts b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.module.ts
index 08391524b9..dec4a4e223 100644
--- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.module.ts
+++ b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.module.ts
@@ -2,17 +2,16 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { MovieListComponent } from './movie-list.component';
-import { routes } from './app.routes';
+import { routing } from './app.routing';
@NgModule({
imports: [
BrowserModule,
FormsModule,
- RouterModule.forRoot(routes, {})
+ routing
],
declarations: [
AppComponent,
diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.routes.ts b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.routes.ts
deleted file mode 100644
index 67aa75ed25..0000000000
--- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.routes.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-// #docregion
-import { RouterConfig } from '@angular/router';
-
-import { MovieListComponent } from './movie-list.component';
-
-export const routes: RouterConfig = [
- { path: '', redirectTo: '/movies', pathMatch: 'full' },
- { path: 'movies', component: MovieListComponent }
-];
diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.routing.ts b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.routing.ts
new file mode 100644
index 0000000000..fb042725eb
--- /dev/null
+++ b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.routing.ts
@@ -0,0 +1,12 @@
+// #docregion
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { MovieListComponent } from './movie-list.component';
+
+const routes: Routes = [
+ { path: '', redirectTo: '/movies', pathMatch: 'full' },
+ { path: 'movies', component: MovieListComponent }
+];
+
+export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/hero.png b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/hero.png
index b60c3ecc30..2a128ac367 100644
Binary files a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/hero.png and b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/hero.png differ
diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/ng-logo.png b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/ng-logo.png
index 7929242740..1e488b1a49 100644
Binary files a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/ng-logo.png and b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/ng-logo.png differ
diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/villain.png b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/villain.png
index d1e71cf00b..26697d1a42 100644
Binary files a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/villain.png and b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/villain.png differ
diff --git a/public/docs/_examples/cb-aot-compiler/e2e-spec.ts b/public/docs/_examples/cb-aot-compiler/e2e-spec.ts
new file mode 100644
index 0000000000..fe72681ee3
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/e2e-spec.ts
@@ -0,0 +1,25 @@
+///
+'use strict';
+/* tslint:disable:quotemark */
+describe('AOT Compilation', function () {
+
+ beforeAll(function () {
+ browser.get('');
+ });
+
+ it('should load page and click button', function (done) {
+ let headingSelector = element.all(by.css('h1')).get(0);
+ expect(headingSelector.getText()).toEqual('My First Angular App');
+
+ expect(element.all(by.xpath('//div[text()="Magneta"]')).get(0).isPresent()).toBe(true);
+ expect(element.all(by.xpath('//div[text()="Bombasto"]')).get(0).isPresent()).toBe(true);
+ expect(element.all(by.xpath('//div[text()="Magma"]')).get(0).isPresent()).toBe(true);
+ expect(element.all(by.xpath('//div[text()="Tornado"]')).get(0).isPresent()).toBe(true);
+
+ let toggleButton = element.all(by.css('button')).get(0);
+ toggleButton.click().then(function() {
+ expect(headingSelector.isPresent()).toBe(false);
+ done();
+ });
+ });
+});
diff --git a/public/docs/_examples/cb-aot-compiler/ts/.gitignore b/public/docs/_examples/cb-aot-compiler/ts/.gitignore
new file mode 100644
index 0000000000..f2e297bbd3
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/.gitignore
@@ -0,0 +1,5 @@
+**/*.ngfactory.ts
+**/*.metadata.json
+dist
+!app/tsconfig.json
+!rollup.js
\ No newline at end of file
diff --git a/public/docs/_examples/cb-aot-compiler/ts/app/app.component.html b/public/docs/_examples/cb-aot-compiler/ts/app/app.component.html
new file mode 100644
index 0000000000..4d7dd8c63f
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/app/app.component.html
@@ -0,0 +1,7 @@
+
+Toggle Heading
+My First Angular App
+
+List of Heroes
+{{hero}}
+
diff --git a/public/docs/_examples/cb-aot-compiler/ts/app/app.component.ts b/public/docs/_examples/cb-aot-compiler/ts/app/app.component.ts
new file mode 100644
index 0000000000..8352eb83f3
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/app/app.component.ts
@@ -0,0 +1,17 @@
+// #docregion
+// #docregion
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ templateUrl: 'app.component.html'
+})
+export class AppComponent {
+ showHeading = true;
+ heroes = ['Magneta', 'Bombasto', 'Magma', 'Tornado'];
+
+ toggleHeading() {
+ this.showHeading = !this.showHeading;
+ }
+
+}
diff --git a/public/docs/_examples/cb-aot-compiler/ts/app/app.module.ts b/public/docs/_examples/cb-aot-compiler/ts/app/app.module.ts
new file mode 100644
index 0000000000..b4fc185c24
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/app/app.module.ts
@@ -0,0 +1,12 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+
+import { AppComponent } from './app.component';
+
+@NgModule({
+ imports: [ BrowserModule ],
+ declarations: [ AppComponent ],
+ bootstrap: [ AppComponent ]
+})
+export class AppModule { }
diff --git a/public/docs/_examples/cb-aot-compiler/ts/app/main-jit.ts b/public/docs/_examples/cb-aot-compiler/ts/app/main-jit.ts
new file mode 100644
index 0000000000..2a7981d0c5
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/app/main-jit.ts
@@ -0,0 +1,6 @@
+// #docregion
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app.module';
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/cb-aot-compiler/ts/app/main.ts b/public/docs/_examples/cb-aot-compiler/ts/app/main.ts
new file mode 100644
index 0000000000..f5a9e94209
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/app/main.ts
@@ -0,0 +1,6 @@
+// #docregion
+import { platformBrowser } from '@angular/platform-browser';
+
+import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory';
+
+platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
diff --git a/public/docs/_examples/cb-aot-compiler/ts/example-config.json b/public/docs/_examples/cb-aot-compiler/ts/example-config.json
new file mode 100644
index 0000000000..1ef73390ce
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/example-config.json
@@ -0,0 +1,4 @@
+{
+ "build": "build:aot",
+ "run": "http-server:e2e"
+}
\ No newline at end of file
diff --git a/public/docs/_examples/cb-aot-compiler/ts/index.html b/public/docs/_examples/cb-aot-compiler/ts/index.html
new file mode 100644
index 0000000000..5d3d6b68c4
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+ Ahead of time compilation
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading...
+
+
+
+
+
diff --git a/public/docs/_examples/cb-aot-compiler/ts/rollup.js b/public/docs/_examples/cb-aot-compiler/ts/rollup.js
new file mode 100644
index 0000000000..5b90e5b0ea
--- /dev/null
+++ b/public/docs/_examples/cb-aot-compiler/ts/rollup.js
@@ -0,0 +1,25 @@
+// #docregion
+import rollup from 'rollup'
+import nodeResolve from 'rollup-plugin-node-resolve'
+import commonjs from 'rollup-plugin-commonjs';
+import uglify from 'rollup-plugin-uglify'
+
+// #docregion config
+export default {
+ entry: 'app/main.js',
+ dest: 'dist/build.js', // output a single application bundle
+ sourceMap: false,
+ format: 'iife',
+ plugins: [
+ nodeResolve({jsnext: true, module: true}),
+ // #docregion commonjs
+ commonjs({
+ include: 'node_modules/rxjs/**',
+ }),
+ // #enddocregion commonjs
+ // #docregion uglify
+ uglify()
+ // #enddocregion uglify
+ ]
+}
+// #enddocregion config
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/tsconfig.1.json b/public/docs/_examples/cb-aot-compiler/ts/tsconfig-aot.json
similarity index 57%
rename from public/docs/_examples/testing/ts/tsconfig.1.json
rename to public/docs/_examples/cb-aot-compiler/ts/tsconfig-aot.json
index 062cf1bcb4..50cd4b53be 100644
--- a/public/docs/_examples/testing/ts/tsconfig.1.json
+++ b/public/docs/_examples/cb-aot-compiler/ts/tsconfig-aot.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "es5",
- "module": "system",
+ "module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
@@ -9,5 +9,16 @@
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
- }
+ },
+
+ "files": [
+ "app/app.module.ts",
+ "app/main.ts",
+ "./typings/index.d.ts"
+ ],
+
+ "angularCompilerOptions": {
+ "genDir": "aot",
+ "skipMetadataEmit" : true
+ }
}
diff --git a/public/docs/_examples/cb-component-communication/ts/app/app.module.ts b/public/docs/_examples/cb-component-communication/ts/app/app.module.ts
index 2314524aa7..a008fc5486 100644
--- a/public/docs/_examples/cb-component-communication/ts/app/app.module.ts
+++ b/public/docs/_examples/cb-component-communication/ts/app/app.module.ts
@@ -1,4 +1,4 @@
-import { NgModule } from '@angular/core';
+import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@@ -30,12 +30,17 @@ let directives: any[] = [
VoteTakerComponent
];
+let schemas: any[] = [];
+
// Include Countdown examples
// unless in e2e tests which they break.
if (!/e2e/.test(location.search)) {
console.log('adding countdown timer examples');
directives.push(CountdownLocalVarParentComponent);
directives.push(CountdownViewChildParentComponent);
+} else {
+ // In e2e test use CUSTOM_ELEMENTS_SCHEMA to supress unknown element errors
+ schemas.push(CUSTOM_ELEMENTS_SCHEMA);
}
@NgModule({
@@ -43,6 +48,7 @@ if (!/e2e/.test(location.search)) {
BrowserModule
],
declarations: directives,
- bootstrap: [ AppComponent ]
+ bootstrap: [ AppComponent ],
+ schemas: schemas
})
export class AppModule { }
diff --git a/public/docs/_examples/cb-component-communication/ts/app/main.ts b/public/docs/_examples/cb-component-communication/ts/app/main.ts
index 4f325ca43d..6af7a5b2ae 100644
--- a/public/docs/_examples/cb-component-communication/ts/app/main.ts
+++ b/public/docs/_examples/cb-component-communication/ts/app/main.ts
@@ -1,5 +1,5 @@
-import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
-browserDynamicPlatform().bootstrapModule(AppModule);
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts
index 7ad076d1a1..8b469886ee 100644
--- a/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts
+++ b/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts
@@ -1,15 +1,12 @@
// #docregion
import { Component } from '@angular/core';
-import { SomeAbsoluteComponent, SomeRelativeComponent } from './some.component';
-
@Component({
selector: 'my-app',
template:
`Absolute & Component-Relative Paths
- `,
- directives: [SomeAbsoluteComponent, SomeRelativeComponent]
+ `
})
export class AppComponent {}
diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/app.module.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/app.module.ts
index ab79a37ba7..a13f4b144f 100644
--- a/public/docs/_examples/cb-component-relative-paths/ts/app/app.module.ts
+++ b/public/docs/_examples/cb-component-relative-paths/ts/app/app.module.ts
@@ -2,13 +2,16 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
+import { SomeAbsoluteComponent, SomeRelativeComponent } from './some.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
- AppComponent
+ AppComponent,
+ SomeAbsoluteComponent,
+ SomeRelativeComponent
],
bootstrap: [ AppComponent ]
})
diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/app.module.ts b/public/docs/_examples/cb-dependency-injection/ts/app/app.module.ts
index 326ea4e945..7b9487e815 100644
--- a/public/docs/_examples/cb-dependency-injection/ts/app/app.module.ts
+++ b/public/docs/_examples/cb-dependency-injection/ts/app/app.module.ts
@@ -1,15 +1,16 @@
// #docregion
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { XHRBackend } from '@angular/http';
-// import { appRouterProviders } from './app.routes';
+import { HttpModule } from '@angular/http';
+
+/* import { routing } from './app.routing';*/
import { LocationStrategy,
HashLocationStrategy } from '@angular/common';
import { NgModule } from '@angular/core';
import { HeroData } from './hero-data';
-import { InMemoryBackendService,
- SEED_DATA } from 'angular2-in-memory-web-api';
+import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
+
import { AppComponent } from './app.component';
import { HeroBioComponent } from './hero-bio.component';
@@ -31,44 +32,43 @@ import { ParentFinderComponent,
BethComponent,
BobComponent } from './parent-finder.component';
-const DIRECTIVES = [
+const declarations = [
+ AppComponent,
HeroBiosComponent, HeroBiosAndContactsComponent, HeroBioComponent,
HeroesBaseComponent, SortedHeroesComponent,
HeroOfTheMonthComponent, HeroContactComponent,
HighlightDirective,
ParentFinderComponent,
- AppComponent
];
-const B_DIRECTIVES = [ BarryComponent, BethComponent, BobComponent ];
+const a_components = [AliceComponent, AlexComponent ];
-// #docregion C_DIRECTIVES
-const C_DIRECTIVES = [
+const b_components = [ BarryComponent, BethComponent, BobComponent ];
+
+const c_components = [
CarolComponent, ChrisComponent, CraigComponent,
CathyComponent
];
-// #enddocregion C_DIRECTIVES
-// #docregion bootstrap
@NgModule({
- imports: [ BrowserModule, FormsModule ],
- declarations: [ ...DIRECTIVES,
- ...B_DIRECTIVES,
- ...C_DIRECTIVES,
- AliceComponent,
- AlexComponent ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpModule,
+ InMemoryWebApiModule.forRoot(HeroData)
+ // routing TODO: add routes
+ ],
+ declarations: [
+ declarations,
+ a_components,
+ b_components,
+ c_components,
+ ],
bootstrap: [ AppComponent ],
+ // #docregion providers
providers: [
- // appRouterProviders, TODO: add routes
- { provide: LocationStrategy, useClass: HashLocationStrategy },
-
- { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
- { provide: SEED_DATA, useClass: HeroData } // in-mem server data
+ { provide: LocationStrategy, useClass: HashLocationStrategy }
]
+ // #enddocregion providers
})
-export class AppModule {
- constructor() {
- }
-}
-// #enddocregion bootstraps
-
+export class AppModule { }
diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/app.routes.ts b/public/docs/_examples/cb-dependency-injection/ts/app/app.routes.ts
deleted file mode 100644
index c8eb6ee683..0000000000
--- a/public/docs/_examples/cb-dependency-injection/ts/app/app.routes.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { provideRouter, RouterConfig } from '@angular/router';
-
-const routes: RouterConfig = [];
-
-export const appRouterProviders = [
- provideRouter(routes)
-];
diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/app.routing.ts b/public/docs/_examples/cb-dependency-injection/ts/app/app.routing.ts
new file mode 100644
index 0000000000..2d3556371d
--- /dev/null
+++ b/public/docs/_examples/cb-dependency-injection/ts/app/app.routing.ts
@@ -0,0 +1,10 @@
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [];
+
+export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
+
+export const appRoutingProviders: any[] = [
+
+];
diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/parent-finder.component.ts b/public/docs/_examples/cb-dependency-injection/ts/app/parent-finder.component.ts
index d5f87d51bd..c6f208f79b 100644
--- a/public/docs/_examples/cb-dependency-injection/ts/app/parent-finder.component.ts
+++ b/public/docs/_examples/cb-dependency-injection/ts/app/parent-finder.component.ts
@@ -2,7 +2,7 @@
/* tslint:disable:*/
// #docplaster
// #docregion
-import { Component, forwardRef, Optional, provide, SkipSelf } from '@angular/core';
+import { Component, forwardRef, Optional, SkipSelf } from '@angular/core';
// A component base class (see AlexComponent)
export abstract class Base { name = 'Count Basie'; }
diff --git a/public/docs/_examples/cb-form-validation/e2e-spec.ts b/public/docs/_examples/cb-form-validation/e2e-spec.ts
new file mode 100644
index 0000000000..bbd4a7ff03
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/e2e-spec.ts
@@ -0,0 +1,180 @@
+///
+'use strict'; // necessary for node!
+
+// THESE TESTS ARE INCOMPLETE
+describeIf(browser.appIsTs || browser.appIsJs, 'Form Validation Tests', function () {
+
+ beforeAll(function () {
+ browser.get('');
+ });
+
+ describe('Hero Form 1', () => {
+ beforeAll(() => {
+ getPage('hero-form-template1');
+ });
+
+ tests();
+ });
+
+ describe('Hero Form 2', () => {
+ beforeAll(() => {
+ getPage('hero-form-template2');
+ });
+
+ tests();
+ bobTests();
+ });
+
+ describe('Hero Form 3 (Reactive)', () => {
+ beforeAll(() => {
+ getPage('hero-form-reactive3');
+ makeNameTooLong();
+ });
+
+ tests();
+ bobTests();
+ });
+});
+
+//////////
+
+const testName = 'Test Name';
+
+let page: {
+ section: protractor.ElementFinder,
+ form: protractor.ElementFinder,
+ title: protractor.ElementFinder,
+ nameInput: protractor.ElementFinder,
+ alterEgoInput: protractor.ElementFinder,
+ powerSelect: protractor.ElementFinder,
+ errorMessages: protractor.ElementArrayFinder,
+ heroFormButtons: protractor.ElementArrayFinder,
+ heroSubmitted: protractor.ElementFinder
+};
+
+function getPage(sectionTag: string) {
+ let section = element(by.css(sectionTag));
+ let buttons = section.all(by.css('button'));
+
+ page = {
+ section: section,
+ form: section.element(by.css('form')),
+ title: section.element(by.css('h1')),
+ nameInput: section.element(by.css('#name')),
+ alterEgoInput: section.element(by.css('#alterEgo')),
+ powerSelect: section.element(by.css('#power')),
+ errorMessages: section.all(by.css('div.alert')),
+ heroFormButtons: buttons,
+ heroSubmitted: section.element(by.css('hero-submitted > div'))
+ };
+}
+
+function tests() {
+ it('should display correct title', function () {
+ expect(page.title.getText()).toContain('Hero Form');
+ });
+
+ it('should not display submitted message before submit', function () {
+ expect(page.heroSubmitted.isElementPresent(by.css('h2'))).toBe(false);
+ });
+
+ it('should have form buttons', function () {
+ expect(page.heroFormButtons.count()).toEqual(2);
+ });
+
+ it('should have error at start', function () {
+ expectFormIsInvalid();
+ });
+
+ // it('showForm', function () {
+ // page.form.getInnerHtml().then(html => console.log(html));
+ // });
+
+ it('should have disabled submit button', function () {
+ expect(page.heroFormButtons.get(0).isEnabled()).toBe(false);
+ });
+
+ it('resetting name to valid name should clear errors', function () {
+ const ele = page.nameInput;
+ expect(ele.isPresent()).toBe(true, 'nameInput should exist');
+ ele.clear();
+ ele.sendKeys(testName);
+ expectFormIsValid();
+ });
+
+ it('should produce "required" error after clearing name', function () {
+ page.nameInput.clear();
+ // page.alterEgoInput.click(); // to blur ... didn't work
+ page.nameInput.sendKeys('x', protractor.Key.BACK_SPACE); // ugh!
+ expect(page.form.getAttribute('class')).toMatch('ng-invalid');
+ expect(page.errorMessages.get(0).getText()).toContain('required');
+ });
+
+ it('should produce "at least 4 characters" error when name="x"', function () {
+ page.nameInput.clear();
+ page.nameInput.sendKeys('x'); // too short
+ expectFormIsInvalid();
+ expect(page.errorMessages.get(0).getText()).toContain('at least 4 characters');
+ });
+
+ it('resetting name to valid name again should clear errors', function () {
+ page.nameInput.sendKeys(testName);
+ expectFormIsValid();
+ });
+
+ it('should have enabled submit button', function () {
+ const submitBtn = page.heroFormButtons.get(0);
+ expect(submitBtn.isEnabled()).toBe(true);
+ });
+
+ it('should hide form after submit', function () {
+ page.heroFormButtons.get(0).click();
+ expect(page.title.isDisplayed()).toBe(false);
+ });
+
+ it('submitted form should be displayed', function () {
+ expect(page.heroSubmitted.isElementPresent(by.css('h2'))).toBe(true);
+ });
+
+ it('submitted form should have new hero name', function () {
+ expect(page.heroSubmitted.getText()).toContain(testName);
+ });
+
+ it('clicking edit button should reveal form again', function () {
+ const editBtn = page.heroSubmitted.element(by.css('button'));
+ editBtn.click();
+ expect(page.heroSubmitted.isElementPresent(by.css('h2')))
+ .toBe(false, 'submitted hidden again');
+ expect(page.title.isDisplayed()).toBe(true, 'can see form title');
+ });
+}
+
+function expectFormIsValid() {
+ expect(page.form.getAttribute('class')).toMatch('ng-valid');
+}
+
+function expectFormIsInvalid() {
+ expect(page.form.getAttribute('class')).toMatch('ng-invalid');
+}
+
+function bobTests() {
+ const emsg = 'Someone named "Bob" cannot be a hero.';
+
+ it('should produce "no bob" error after setting name to "Bobby"', function () {
+ page.nameInput.clear();
+ page.nameInput.sendKeys('Bobby');
+ expectFormIsInvalid();
+ expect(page.errorMessages.get(0).getText()).toBe(emsg);
+ });
+
+ it('should be ok again with valid name', function () {
+ page.nameInput.clear();
+ page.nameInput.sendKeys(testName);
+ expectFormIsValid();
+ });
+}
+
+function makeNameTooLong() {
+ // make the first name invalid
+ page.nameInput.sendKeys('ThisHeroNameHasWayWayTooManyLetters');
+}
diff --git a/public/docs/_examples/cb-form-validation/ts/app/app.component.ts b/public/docs/_examples/cb-form-validation/ts/app/app.component.ts
new file mode 100644
index 0000000000..2da4dc4d0a
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/app.component.ts
@@ -0,0 +1,12 @@
+// #docregion
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+
+
+ `
+})
+export class AppComponent { }
diff --git a/public/docs/_examples/cb-form-validation/ts/app/app.module.ts b/public/docs/_examples/cb-form-validation/ts/app/app.module.ts
new file mode 100644
index 0000000000..72b4e3a770
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/app.module.ts
@@ -0,0 +1,18 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+
+import { AppComponent } from './app.component';
+import { HeroFormTemplateModule } from './template/hero-form-template.module';
+import { HeroFormReactiveModule } from './reactive/hero-form-reactive.module';
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ HeroFormTemplateModule,
+ HeroFormReactiveModule
+ ],
+ declarations: [ AppComponent ],
+ bootstrap: [ AppComponent ]
+})
+export class AppModule { }
diff --git a/public/docs/_examples/cb-form-validation/ts/app/main.ts b/public/docs/_examples/cb-form-validation/ts/app/main.ts
new file mode 100644
index 0000000000..961a226688
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/main.ts
@@ -0,0 +1,6 @@
+// #docregion
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app.module';
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.component.html b/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.component.html
new file mode 100644
index 0000000000..149537bd3e
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.component.html
@@ -0,0 +1,47 @@
+
+
+
+
Hero Form 3 (Reactive)
+
+
+
+
+
+
diff --git a/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.component.ts b/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.component.ts
new file mode 100644
index 0000000000..7e7dfa0739
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.component.ts
@@ -0,0 +1,117 @@
+/* tslint:disable: member-ordering forin */
+// #docplaster
+// #docregion
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+
+import { Hero } from '../shared/hero';
+import { forbiddenNameValidator } from '../shared/forbidden-name.directive';
+
+@Component({
+ moduleId: module.id,
+ selector: 'hero-form-reactive3',
+ templateUrl: 'hero-form-reactive.component.html'
+})
+export class HeroFormReactiveComponent implements OnInit {
+
+ powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
+
+ hero = new Hero(18, 'Dr. WhatIsHisName', this.powers[0], 'Dr. What');
+
+ submitted = false;
+
+ // #docregion on-submit
+ onSubmit() {
+ this.submitted = true;
+ this.hero = this.heroForm.value;
+ }
+ // #enddocregion on-submit
+// #enddocregion
+
+ // Reset the form with a new hero AND restore 'pristine' class state
+ // by toggling 'active' flag which causes the form
+ // to be removed/re-added in a tick via NgIf
+ // TODO: Workaround until NgForm has a reset method (#6822)
+ active = true;
+// #docregion
+ // #docregion add-hero
+ addHero() {
+ this.hero = new Hero(42, '', '');
+ this.buildForm();
+ // #enddocregion add-hero
+// #enddocregion class
+
+ this.active = false;
+ setTimeout(() => this.active = true, 0);
+// #docregion
+ // #docregion add-hero
+ }
+ // #enddocregion add-hero
+
+ // #docregion form-builder
+ heroForm: FormGroup;
+ constructor(private fb: FormBuilder) { }
+
+ ngOnInit(): void {
+ this.buildForm();
+ }
+
+ buildForm(): void {
+ this.heroForm = this.fb.group({
+ // #docregion name-validators
+ 'name': [this.hero.name, [
+ Validators.required,
+ Validators.minLength(4),
+ Validators.maxLength(24),
+ forbiddenNameValidator(/bob/i)
+ ]
+ ],
+ // #enddocregion name-validators
+ 'alterEgo': [this.hero.alterEgo],
+ 'power': [this.hero.power, Validators.required]
+ });
+
+ this.heroForm.valueChanges
+ .subscribe(data => this.onValueChanged(data));
+
+ this.onValueChanged(); // (re)set validation messages now
+ }
+
+ // #enddocregion form-builder
+
+ onValueChanged(data?: any) {
+ if (!this.heroForm) { return; }
+ const form = this.heroForm;
+
+ for (const field in this.formErrors) {
+ // clear previous error message (if any)
+ this.formErrors[field] = '';
+ const control = form.get(field);
+
+ if (control && control.dirty && !control.valid) {
+ const messages = this.validationMessages[field];
+ for (const key in control.errors) {
+ this.formErrors[field] += messages[key] + ' ';
+ }
+ }
+ }
+ }
+
+ formErrors = {
+ 'name': '',
+ 'power': ''
+ };
+
+ validationMessages = {
+ 'name': {
+ 'required': 'Name is required.',
+ 'minlength': 'Name must be at least 4 characters long.',
+ 'maxlength': 'Name cannot be more than 24 characters long.',
+ 'forbiddenName': 'Someone named "Bob" cannot be a hero.'
+ },
+ 'power': {
+ 'required': 'Power is required.'
+ }
+ };
+}
+// #enddocregion
diff --git a/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.module.ts b/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.module.ts
new file mode 100644
index 0000000000..6ff9265e92
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/reactive/hero-form-reactive.module.ts
@@ -0,0 +1,13 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { ReactiveFormsModule } from '@angular/forms';
+
+import { SharedModule } from '../shared/shared.module';
+import { HeroFormReactiveComponent } from './hero-form-reactive.component';
+
+@NgModule({
+ imports: [ SharedModule, ReactiveFormsModule ],
+ declarations: [ HeroFormReactiveComponent ],
+ exports: [ HeroFormReactiveComponent ]
+})
+export class HeroFormReactiveModule { }
diff --git a/public/docs/_examples/cb-form-validation/ts/app/shared/forbidden-name.directive.ts b/public/docs/_examples/cb-form-validation/ts/app/shared/forbidden-name.directive.ts
new file mode 100644
index 0000000000..a8f6c03d33
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/shared/forbidden-name.directive.ts
@@ -0,0 +1,43 @@
+// #docregion
+import { Directive, Input, OnChanges, SimpleChanges } from '@angular/core';
+import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } from '@angular/forms';
+
+// #docregion custom-validator
+/** A hero's name can't match the given regular expression */
+export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
+ return (control: AbstractControl): {[key: string]: any} => {
+ const name = control.value;
+ const no = nameRe.test(name);
+ return no ? {'forbiddenName': {name}} : null;
+ };
+}
+// #enddocregion custom-validator
+
+// #docregion directive
+@Directive({
+ selector: '[forbiddenName]',
+ // #docregion directive-providers
+ providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
+ // #enddocregion directive-providers
+})
+export class ForbiddenValidatorDirective implements Validator, OnChanges {
+ @Input() forbiddenName: string;
+ private valFn = Validators.nullValidator;
+
+ ngOnChanges(changes: SimpleChanges): void {
+ const change = changes['forbiddenName'];
+ if (change) {
+ const val: string | RegExp = change.currentValue;
+ const re = val instanceof RegExp ? val : new RegExp(val, 'i');
+ this.valFn = forbiddenNameValidator(re);
+ } else {
+ this.valFn = Validators.nullValidator;
+ }
+ }
+
+ validate(control: AbstractControl): {[key: string]: any} {
+ return this.valFn(control);
+ }
+}
+// #docregion directive
+
diff --git a/public/docs/_examples/forms-deprecated/ts/app/hero.ts b/public/docs/_examples/cb-form-validation/ts/app/shared/hero.ts
similarity index 98%
rename from public/docs/_examples/forms-deprecated/ts/app/hero.ts
rename to public/docs/_examples/cb-form-validation/ts/app/shared/hero.ts
index c128626452..fe2b55e51a 100644
--- a/public/docs/_examples/forms-deprecated/ts/app/hero.ts
+++ b/public/docs/_examples/cb-form-validation/ts/app/shared/hero.ts
@@ -1,11 +1,9 @@
// #docregion
export class Hero {
-
constructor(
public id: number,
public name: string,
public power: string,
public alterEgo?: string
) { }
-
}
diff --git a/public/docs/_examples/cb-form-validation/ts/app/shared/shared.module.ts b/public/docs/_examples/cb-form-validation/ts/app/shared/shared.module.ts
new file mode 100644
index 0000000000..2b0ada59bd
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/shared/shared.module.ts
@@ -0,0 +1,14 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { ForbiddenValidatorDirective } from './forbidden-name.directive';
+import { SubmittedComponent } from './submitted.component';
+
+@NgModule({
+ imports: [ CommonModule],
+ declarations: [ ForbiddenValidatorDirective, SubmittedComponent ],
+ exports: [ ForbiddenValidatorDirective, SubmittedComponent,
+ CommonModule ]
+})
+export class SharedModule { }
diff --git a/public/docs/_examples/cb-form-validation/ts/app/shared/submitted.component.ts b/public/docs/_examples/cb-form-validation/ts/app/shared/submitted.component.ts
new file mode 100644
index 0000000000..18cea6563f
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/shared/submitted.component.ts
@@ -0,0 +1,32 @@
+// #docregion
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { Hero } from './hero';
+
+@Component({
+ selector: 'hero-submitted',
+ template: `
+
+
You submitted the following:
+
+
Name
+
{{ hero.name }}
+
+
+
Alter Ego
+
{{ hero.alterEgo }}
+
+
+
Power
+
{{ hero.power }}
+
+
+
Edit
+
`
+})
+export class SubmittedComponent {
+ @Input() hero: Hero;
+ @Input() submitted = false;
+ @Output() submittedChange = new EventEmitter();
+ onClick() { this.submittedChange.emit(false); }
+}
diff --git a/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template.module.ts b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template.module.ts
new file mode 100644
index 0000000000..042c019d5e
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template.module.ts
@@ -0,0 +1,14 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+
+import { SharedModule } from '../shared/shared.module';
+import { HeroFormTemplate1Component } from './hero-form-template1.component';
+import { HeroFormTemplate2Component } from './hero-form-template2.component';
+
+@NgModule({
+ imports: [ SharedModule, FormsModule ],
+ declarations: [ HeroFormTemplate1Component, HeroFormTemplate2Component ],
+ exports: [ HeroFormTemplate1Component, HeroFormTemplate2Component ]
+})
+export class HeroFormTemplateModule { }
diff --git a/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template1.component.html b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template1.component.html
new file mode 100644
index 0000000000..22b374b622
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template1.component.html
@@ -0,0 +1,61 @@
+
+
+
+
Hero Form 1 (Template)
+
+
+
+
+
+
diff --git a/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template1.component.ts b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template1.component.ts
new file mode 100644
index 0000000000..845fcc9abc
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template1.component.ts
@@ -0,0 +1,48 @@
+/* tslint:disable: member-ordering */
+// #docplaster
+// #docregion
+import { Component } from '@angular/core';
+
+
+import { Hero } from '../shared/hero';
+
+@Component({
+ moduleId: module.id,
+ selector: 'hero-form-template1',
+ templateUrl: 'hero-form-template1.component.html'
+})
+// #docregion class
+export class HeroFormTemplate1Component {
+
+ powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
+
+ hero = new Hero(18, 'Dr. WhatIsHisWayTooLongName', this.powers[0], 'Dr. What');
+
+ submitted = false;
+
+ onSubmit() {
+ this.submitted = true;
+ }
+// #enddocregion class
+// #enddocregion
+ // Reset the form with a new hero AND restore 'pristine' class state
+ // by toggling 'active' flag which causes the form
+ // to be removed/re-added in a tick via NgIf
+ // TODO: Workaround until NgForm has a reset method (#6822)
+ active = true;
+// #docregion
+// #docregion class
+
+ addHero() {
+ this.hero = new Hero(42, '', '');
+// #enddocregion class
+// #enddocregion
+
+ this.active = false;
+ setTimeout(() => this.active = true, 0);
+// #docregion
+// #docregion class
+ }
+}
+// #enddocregion class
+// #enddocregion
diff --git a/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template2.component.html b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template2.component.html
new file mode 100644
index 0000000000..8bb7066541
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template2.component.html
@@ -0,0 +1,52 @@
+
+
+
+
Hero Form 2 (Template & Messages)
+
+
+
+
+
+
diff --git a/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template2.component.ts b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template2.component.ts
new file mode 100644
index 0000000000..e2781ec617
--- /dev/null
+++ b/public/docs/_examples/cb-form-validation/ts/app/template/hero-form-template2.component.ts
@@ -0,0 +1,100 @@
+/* tslint:disable: member-ordering forin */
+// #docplaster
+// #docregion
+import { Component, AfterViewChecked, ViewChild } from '@angular/core';
+import { NgForm } from '@angular/forms';
+
+import { Hero } from '../shared/hero';
+
+@Component({
+ moduleId: module.id,
+ selector: 'hero-form-template2',
+ templateUrl: 'hero-form-template2.component.html'
+})
+export class HeroFormTemplate2Component implements AfterViewChecked {
+
+ powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
+
+ hero = new Hero(18, 'Dr. WhatIsHisWayTooLongName', this.powers[0], 'Dr. What');
+
+ submitted = false;
+
+ onSubmit() {
+ this.submitted = true;
+ }
+// #enddocregion
+
+ // Reset the form with a new hero AND restore 'pristine' class state
+ // by toggling 'active' flag which causes the form
+ // to be removed/re-added in a tick via NgIf
+ // TODO: Workaround until NgForm has a reset method (#6822)
+ active = true;
+// #docregion
+
+ addHero() {
+ this.hero = new Hero(42, '', '');
+// #enddocregion
+
+ this.active = false;
+ setTimeout(() => this.active = true, 0);
+// #docregion
+ }
+
+ // #docregion view-child
+ heroForm: NgForm;
+ @ViewChild('heroForm') currentForm: NgForm;
+
+ ngAfterViewChecked() {
+ this.formChanged();
+ }
+
+ formChanged() {
+ if (this.currentForm === this.heroForm) { return; }
+ this.heroForm = this.currentForm;
+ if (this.heroForm) {
+ this.heroForm.valueChanges
+ .subscribe(data => this.onValueChanged(data));
+ }
+ }
+ // #enddocregion view-child
+
+ // #docregion handler
+ onValueChanged(data?: any) {
+ if (!this.heroForm) { return; }
+ const form = this.heroForm.form;
+
+ for (const field in this.formErrors) {
+ // clear previous error message (if any)
+ this.formErrors[field] = '';
+ const control = form.get(field);
+
+ if (control && control.dirty && !control.valid) {
+ const messages = this.validationMessages[field];
+ for (const key in control.errors) {
+ this.formErrors[field] += messages[key] + ' ';
+ }
+ }
+ }
+ }
+
+ formErrors = {
+ 'name': '',
+ 'power': ''
+ };
+ // #enddocregion handler
+
+ // #docregion messages
+ validationMessages = {
+ 'name': {
+ 'required': 'Name is required.',
+ 'minlength': 'Name must be at least 4 characters long.',
+ 'maxlength': 'Name cannot be more than 24 characters long.',
+ 'forbiddenName': 'Someone named "Bob" cannot be a hero.'
+ },
+ 'power': {
+ 'required': 'Power is required.'
+ }
+ };
+ // #enddocregion messages
+}
+// #enddocregion
diff --git a/public/docs/_examples/forms-deprecated/js/example-config.json b/public/docs/_examples/cb-form-validation/ts/example-config.json
similarity index 100%
rename from public/docs/_examples/forms-deprecated/js/example-config.json
rename to public/docs/_examples/cb-form-validation/ts/example-config.json
diff --git a/public/docs/_examples/forms-deprecated/ts/forms.css b/public/docs/_examples/cb-form-validation/ts/forms.css
similarity index 56%
rename from public/docs/_examples/forms-deprecated/ts/forms.css
rename to public/docs/_examples/cb-form-validation/ts/forms.css
index d7e11405b1..67ad13037b 100644
--- a/public/docs/_examples/forms-deprecated/ts/forms.css
+++ b/public/docs/_examples/cb-form-validation/ts/forms.css
@@ -1,9 +1,7 @@
-/* #docregion */
-.ng-valid[required] {
+.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
-.ng-invalid {
+.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
-/* #enddocregion */
\ No newline at end of file
diff --git a/public/docs/_examples/forms-deprecated/ts/index.html b/public/docs/_examples/cb-form-validation/ts/index.html
similarity index 80%
rename from public/docs/_examples/forms-deprecated/ts/index.html
rename to public/docs/_examples/cb-form-validation/ts/index.html
index 4df2d32d46..6aea5beaa4 100644
--- a/public/docs/_examples/forms-deprecated/ts/index.html
+++ b/public/docs/_examples/cb-form-validation/ts/index.html
@@ -1,18 +1,13 @@
-
-
- Hero Form
+ Hero Form with Validation
+
-
-
-
-
@@ -30,5 +25,5 @@
Loading...
-
+
diff --git a/public/docs/_examples/forms-deprecated/ts/plnkr.json b/public/docs/_examples/cb-form-validation/ts/plnkr.json
similarity index 58%
rename from public/docs/_examples/forms-deprecated/ts/plnkr.json
rename to public/docs/_examples/cb-form-validation/ts/plnkr.json
index c813933f8e..aa676ad767 100644
--- a/public/docs/_examples/forms-deprecated/ts/plnkr.json
+++ b/public/docs/_examples/cb-form-validation/ts/plnkr.json
@@ -1,5 +1,5 @@
{
- "description": "Forms-Deprecated",
+ "description": "Validation",
"files":[
"!**/*.d.ts",
"!**/*.js"
diff --git a/public/docs/_examples/cb-set-document-title/ts/app/main.ts b/public/docs/_examples/cb-set-document-title/ts/app/main.ts
index ba9421d573..961a226688 100644
--- a/public/docs/_examples/cb-set-document-title/ts/app/main.ts
+++ b/public/docs/_examples/cb-set-document-title/ts/app/main.ts
@@ -1,6 +1,6 @@
// #docregion
-import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
-browserDynamicPlatform().bootstrapModule(AppModule);
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/cb-set-document-title/ts/plnkr.json b/public/docs/_examples/cb-set-document-title/ts/plnkr.json
index 0131610c20..1863d49471 100644
--- a/public/docs/_examples/cb-set-document-title/ts/plnkr.json
+++ b/public/docs/_examples/cb-set-document-title/ts/plnkr.json
@@ -1,5 +1,5 @@
{
- "description": "Set The Document Title In Angular 2",
+ "description": "Set The Document Title In Angular",
"files": [
"!**/*.d.ts",
"!**/*.js",
diff --git a/public/docs/_examples/cb-ts-to-js/e2e-spec.ts b/public/docs/_examples/cb-ts-to-js/e2e-spec.ts
index d356544496..1fc5641bd3 100644
--- a/public/docs/_examples/cb-ts-to-js/e2e-spec.ts
+++ b/public/docs/_examples/cb-ts-to-js/e2e-spec.ts
@@ -25,7 +25,7 @@ describe('TypeScript to Javascript tests', function () {
it('should support optional, attribute, and query injections', function () {
let app = element(by.css('hero-di-inject-additional'));
let h1 = app.element(by.css('h1'));
- let okMsg = app.element(by.css('.ok-msg'));
+ let okMsg = app.element(by.css('p'));
expect(h1.getText()).toBe('Tour of Heroes');
app.element(by.buttonText('OK')).click();
diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject-additional.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject-additional.component.js
index 153e83c06f..fa9684e7a1 100644
--- a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject-additional.component.js
+++ b/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject-additional.component.js
@@ -6,7 +6,7 @@
template:
'{{titlePrefix}} {{title}} ' +
'OK ' +
- ' '
+ '{{ msg }}
'
}).Class({
constructor: [
[
@@ -14,20 +14,14 @@
new ng.core.Inject('titlePrefix')
],
new ng.core.Attribute('title'),
- [
- new ng.core.Query('okMsg'),
- ng.core.ElementRef
- ],
- function(titlePrefix, title, msg) {
+ function(titlePrefix, title) {
this.titlePrefix = titlePrefix;
this.title = title;
- this.msg = msg;
+ this.msg = '';
}
],
ok: function() {
- var msgEl =
- this.msg.first.nativeElement;
- msgEl.textContent = 'OK!';
+ this.msg = 'OK!';
}
});
// #enddocregion
@@ -35,7 +29,6 @@
var AppComponent = ng.core.Component({
selector: 'hero-di-inject-additional',
template: '' +
- ' ' +
' '
}).Class({
constructor: function() { }
diff --git a/public/docs/_examples/cb-ts-to-js/js/app/main.js b/public/docs/_examples/cb-ts-to-js/js/app/main.js
index a1ec27c6ad..9091452599 100644
--- a/public/docs/_examples/cb-ts-to-js/js/app/main.js
+++ b/public/docs/_examples/cb-ts-to-js/js/app/main.js
@@ -4,8 +4,8 @@
// #enddocregion appimport
// #docregion ng2import
- var bootstrap =
- ng.platformBrowserDynamic.bootstrap;
+ var platformBrowserDynamic =
+ ng.platformBrowserDynamic.platformBrowserDynamic;
var LocationStrategy =
ng.common.LocationStrategy;
var HashLocationStrategy =
@@ -17,20 +17,17 @@
// #enddocregion appimport
document.addEventListener('DOMContentLoaded', function() {
- var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic();
-
- platformBrowserDynamic.bootstrapModule(app.HeroesModule);
- platformBrowserDynamic.bootstrapModule(app.HeroesDslModule);
- platformBrowserDynamic.bootstrapModule(app.HeroesLifecycleModule);
- platformBrowserDynamic.bootstrapModule(app.HeroesDIModule);
- platformBrowserDynamic.bootstrapModule(app.HeroDIInlineModule);
- platformBrowserDynamic.bootstrapModule(app.HeroesDIInjectModule);
- platformBrowserDynamic.bootstrapModule(app.HeroesDIInjectModule2);
- platformBrowserDynamic.bootstrapModule(app.HeroesDIInjectAdditionalModule);
- platformBrowserDynamic.bootstrapModule(app.HeroesIOModule);
- platformBrowserDynamic.bootstrapModule(app.HeroesHostBindingsModule);
-
- platformBrowserDynamic.bootstrapModule(app.HeroesQueriesModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesDslModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesLifecycleModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesDIModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroDIInlineModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesDIInjectModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesDIInjectModule2);
+ platformBrowserDynamic().bootstrapModule(app.HeroesDIInjectAdditionalModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesIOModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesHostBindingsModule);
+ platformBrowserDynamic().bootstrapModule(app.HeroesQueriesModule);
});
// #docregion appimport
diff --git a/public/docs/_examples/cb-ts-to-js/js/index.html b/public/docs/_examples/cb-ts-to-js/js/index.html
index 89e80451a6..448c295609 100644
--- a/public/docs/_examples/cb-ts-to-js/js/index.html
+++ b/public/docs/_examples/cb-ts-to-js/js/index.html
@@ -10,7 +10,7 @@
-
+
diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts
index bca1e88cb6..146c6cbd83 100644
--- a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts
+++ b/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts
@@ -1,11 +1,8 @@
import {
Attribute,
Component,
- ElementRef,
Inject,
Optional,
- Query,
- QueryList,
NgModule
} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@@ -16,24 +13,21 @@ import { BrowserModule } from '@angular/platform-browser';
template: `
{{titlePrefix}} {{title}}
OK
-
+ {{ msg }}
`
})
class TitleComponent {
+ private msg: string = '';
constructor(
@Inject('titlePrefix')
@Optional()
private titlePrefix: string,
@Attribute('title')
- private title: string,
- @Query('okMsg')
- private msg: QueryList) {
+ private title: string) {
}
ok() {
- let msgEl =
- this.msg.first.nativeElement;
- msgEl.textContent = 'OK!';
+ this.msg = 'OK!';
}
}
// #enddocregion
@@ -41,7 +35,6 @@ class TitleComponent {
@Component({
selector: 'hero-di-inject-additional',
template: `
-
`
})
class AppComponent { }
diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/main.ts b/public/docs/_examples/cb-ts-to-js/ts/app/main.ts
index c4549d7034..92f5af5e1a 100644
--- a/public/docs/_examples/cb-ts-to-js/ts/app/main.ts
+++ b/public/docs/_examples/cb-ts-to-js/ts/app/main.ts
@@ -1,7 +1,6 @@
/* tslint:disable no-unused-variable */
// #docregion ng2import
-import { bootstrap }
- from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import {
LocationStrategy,
HashLocationStrategy
@@ -12,8 +11,6 @@ import {
import { HeroComponent } from './hero.component';
// #enddocregion appimport
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
-
import { HeroesModule } from './hero.component';
import { HeroesLifecycleModule } from './hero-lifecycle.component';
import { HeroesDIModule } from './hero-di.component';
diff --git a/public/docs/_examples/cli-quickstart/e2e-spec.ts.disabled b/public/docs/_examples/cli-quickstart/e2e-spec.ts.disabled
index f214b75d93..ef30b01ec1 100644
--- a/public/docs/_examples/cli-quickstart/e2e-spec.ts.disabled
+++ b/public/docs/_examples/cli-quickstart/e2e-spec.ts.disabled
@@ -7,6 +7,6 @@ describe('cli-quickstart App', () => {
it('should display message saying app works', () => {
let pageTitle = element(by.css('cli-quickstart-app h1')).getText();
- expect(pageTitle).toEqual('My First Angular 2 App');
+ expect(pageTitle).toEqual('My First Angular App');
});
});
diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.ts b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.ts
index 5510df7476..8c6b3a43cc 100644
--- a/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.ts
+++ b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.ts
@@ -12,6 +12,6 @@ import { Component } from '@angular/core';
// #enddocregion metadata
// #docregion title, class
export class CliQuickstartAppComponent {
- title = 'My First Angular 2 App';
+ title = 'My First Angular App';
}
// #enddocregion title, class
diff --git a/public/docs/_examples/component-styles/dart/pubspec.yaml b/public/docs/_examples/component-styles/dart/pubspec.yaml
index 731e9e5d8e..7521cf8365 100755
--- a/public/docs/_examples/component-styles/dart/pubspec.yaml
+++ b/public/docs/_examples/component-styles/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/dependency-injection/dart/pubspec.yaml b/public/docs/_examples/dependency-injection/dart/pubspec.yaml
index b3b5a1cb42..b5958b1e07 100644
--- a/public/docs/_examples/dependency-injection/dart/pubspec.yaml
+++ b/public/docs/_examples/dependency-injection/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/dependency-injection/ts/app/app.module.ts b/public/docs/_examples/dependency-injection/ts/app/app.module.ts
index 439c9ff276..5ef7678573 100644
--- a/public/docs/_examples/dependency-injection/ts/app/app.module.ts
+++ b/public/docs/_examples/dependency-injection/ts/app/app.module.ts
@@ -7,9 +7,21 @@ import { HeroesComponent } from './heroes/heroes.component';
import { HeroListComponent } from './heroes/hero-list.component';
import { InjectorComponent } from './injector.component';
import { TestComponent } from './test.component';
-import { ProvidersComponent } from './providers.component';
import { APP_CONFIG, HERO_DI_CONFIG } from './app.config';
import { UserService } from './user.service';
+import {
+ ProvidersComponent,
+ Provider1Component,
+ Provider3Component,
+ Provider4Component,
+ Provider5Component,
+ Provider6aComponent,
+ Provider6bComponent,
+ Provider7Component,
+ Provider8Component,
+ Provider9Component,
+ Provider10Component,
+} from './providers.component';
// #docregion ngmodule
@NgModule({
@@ -22,7 +34,18 @@ import { UserService } from './user.service';
HeroesComponent,
HeroListComponent,
InjectorComponent,
- TestComponent
+ TestComponent,
+ ProvidersComponent,
+ Provider1Component,
+ Provider3Component,
+ Provider4Component,
+ Provider5Component,
+ Provider6aComponent,
+ Provider6bComponent,
+ Provider7Component,
+ Provider8Component,
+ Provider9Component,
+ Provider10Component,
],
// #docregion ngmodule-providers
providers: [
diff --git a/public/docs/_examples/dependency-injection/ts/app/main.ts b/public/docs/_examples/dependency-injection/ts/app/main.ts
index 4acb58eab5..0b0458c3b8 100644
--- a/public/docs/_examples/dependency-injection/ts/app/main.ts
+++ b/public/docs/_examples/dependency-injection/ts/app/main.ts
@@ -1,6 +1,6 @@
-import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
// #docregion bootstrap
-browserDynamicPlatform().bootstrapModule(AppModule);
+platformBrowserDynamic().bootstrapModule(AppModule);
// #enddocregion bootstrap
diff --git a/public/docs/_examples/dependency-injection/ts/app/providers.component.ts b/public/docs/_examples/dependency-injection/ts/app/providers.component.ts
index 04089be01d..f8c7ee81fd 100644
--- a/public/docs/_examples/dependency-injection/ts/app/providers.component.ts
+++ b/public/docs/_examples/dependency-injection/ts/app/providers.component.ts
@@ -261,18 +261,6 @@ export class Provider10Component implements OnInit {
- `,
- directives: [
- Provider1Component,
- Provider3Component,
- Provider4Component,
- Provider5Component,
- Provider6aComponent,
- Provider6bComponent,
- Provider7Component,
- Provider8Component,
- Provider9Component,
- Provider10Component,
- ],
+ `
})
export class ProvidersComponent { }
diff --git a/public/docs/_examples/displaying-data/dart/pubspec.yaml b/public/docs/_examples/displaying-data/dart/pubspec.yaml
index 8c57ff7300..2c5961c70e 100644
--- a/public/docs/_examples/displaying-data/dart/pubspec.yaml
+++ b/public/docs/_examples/displaying-data/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/displaying-data/ts/app/main.1.ts b/public/docs/_examples/displaying-data/ts/app/main.1.ts
deleted file mode 100644
index b033da1575..0000000000
--- a/public/docs/_examples/displaying-data/ts/app/main.1.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-/* tslint:disable */
-import { bootstrap } from '@angular/platform-browser-dynamic';
-
-import { AppCtorComponent } from './app-ctor.component';
-import { AppComponent as v1 } from './app.component.1';
-import { AppComponent as v2 } from './app.component.2';
-import { AppComponent as v3 } from './app.component.3';
-
-import { AppComponent as final } from './app.component';
-
-// pick one
-// bootstrap(v1);
-// bootstrap(v2);
-// bootstrap(v3);
-bootstrap(final);
-
-// for doc testing
-bootstrap(AppCtorComponent);
diff --git a/public/docs/_examples/forms-deprecated/e2e-spec.ts.disabled b/public/docs/_examples/forms-deprecated/e2e-spec.ts.disabled
deleted file mode 100644
index ab5c8321be..0000000000
--- a/public/docs/_examples/forms-deprecated/e2e-spec.ts.disabled
+++ /dev/null
@@ -1,64 +0,0 @@
-///
-'use strict';
-describeIf(browser.appIsTs || browser.appIsJs, 'Forms (Deprecated) Tests', function () {
-
- beforeEach(function () {
- browser.get('');
- });
-
- it('should display correct title', function () {
- expect(element.all(by.css('h1')).get(0).getText()).toEqual('Hero Form');
- });
-
-
- it('should not display message before submit', function () {
- let ele = element(by.css('h2'));
- expect(ele.isDisplayed()).toBe(false);
- });
-
- it('should hide form after submit', function () {
- let ele = element.all(by.css('h1')).get(0);
- expect(ele.isDisplayed()).toBe(true);
- let b = element.all(by.css('button[type=submit]')).get(0);
- b.click().then(function() {
- expect(ele.isDisplayed()).toBe(false);
- });
- });
-
- it('should display message after submit', function () {
- let b = element.all(by.css('button[type=submit]')).get(0);
- b.click().then(function() {
- expect(element(by.css('h2')).getText()).toContain('You submitted the following');
- });
- });
-
- it('should hide form after submit', function () {
- let alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0);
- expect(alterEgoEle.isDisplayed()).toBe(true);
- let submitButtonEle = element.all(by.css('button[type=submit]')).get(0);
- submitButtonEle.click().then(function() {
- expect(alterEgoEle.isDisplayed()).toBe(false);
- });
- });
-
- it('should reflect submitted data after submit', function () {
- let test = 'testing 1 2 3';
- let newValue: string;
- let alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0);
- alterEgoEle.getAttribute('value').then(function(value) {
- // alterEgoEle.sendKeys(test);
- sendKeys(alterEgoEle, test);
- newValue = value + test;
- expect(alterEgoEle.getAttribute('value')).toEqual(newValue);
- }).then(function() {
- let b = element.all(by.css('button[type=submit]')).get(0);
- return b.click();
- }).then(function() {
- let alterEgoTextEle = element(by.cssContainingText('div', 'Alter Ego'));
- expect(alterEgoTextEle.isPresent()).toBe(true, 'cannot locate "Alter Ego" label');
- let divEle = element(by.cssContainingText('div', newValue));
- expect(divEle.isPresent()).toBe(true, 'cannot locate div with this text: ' + newValue);
- });
- });
-});
-
diff --git a/public/docs/_examples/forms-deprecated/js/app/app.component.js b/public/docs/_examples/forms-deprecated/js/app/app.component.js
deleted file mode 100644
index bb6b789938..0000000000
--- a/public/docs/_examples/forms-deprecated/js/app/app.component.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// #docregion
-(function(app) {
- app.AppComponent = ng.core
- .Component({
- selector: 'my-app',
- template: ' ',
- directives: [app.HeroFormComponent]
- })
- .Class({
- constructor: function() {}
- });
-})(window.app || (window.app = {}));
diff --git a/public/docs/_examples/forms-deprecated/js/app/hero-form.component.html b/public/docs/_examples/forms-deprecated/js/app/hero-form.component.html
deleted file mode 100644
index fdf8e08396..0000000000
--- a/public/docs/_examples/forms-deprecated/js/app/hero-form.component.html
+++ /dev/null
@@ -1,195 +0,0 @@
-
-
-
-
-
-
-
-
-
You submitted the following:
-
-
Name
-
{{ model.name }}
-
-
-
Alter Ego
-
{{ model.alterEgo }}
-
-
-
Power
-
{{ model.power }}
-
-
-
Edit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TODO: remove this: {{model.name}}
-
-
-
-
- TODO: remove this: {{model.name}}
-
-
-
-
-
-
- Name via form.controls = {{showFormControls(heroForm)}}
-
-
-
diff --git a/public/docs/_examples/forms-deprecated/js/app/hero-form.component.js b/public/docs/_examples/forms-deprecated/js/app/hero-form.component.js
deleted file mode 100644
index 8988231189..0000000000
--- a/public/docs/_examples/forms-deprecated/js/app/hero-form.component.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// #docplaster
-// #docregion
-// #docregion first, final
-(function(app) {
- app.HeroFormComponent = ng.core
- .Component({
- selector: 'hero-form',
- templateUrl: 'app/hero-form.component.html'
- })
- .Class({
- // #docregion submitted
- constructor: function() {
- // #enddocregion submitted
- this.powers = ['Really Smart', 'Super Flexible',
- 'Super Hot', 'Weather Changer'
- ];
-
- this.model = new app.Hero(18, 'Dr IQ', this.powers[0],
- 'Chuck Overstreet');
-
- // #docregion submitted
- this.submitted = false;
- },
- onSubmit: function() {
- this.submitted = true;
- },
- // #enddocregion submitted
-
- // #enddocregion final
- // TODO: Remove this when we're done
- diagnostic: function() {
- return JSON.stringify(this.model);
- },
- // #enddocregion first
-
-
- //////// DO NOT SHOW IN DOCS ////////
-
- // Reveal in html:
- // AlterEgo via form.controls = {{showFormControls(hf)}}
- showFormControls: function(form) {
- return form.controls['alterEgo'] &&
- // #docregion form-controls
- form.controls['name'].value; // Dr. IQ
- // #enddocregion form-controls
- },
- /////////////////////////////
-
- // #docregion first, final
- });
- // #enddocregion first, final
-})(window.app || (window.app = {}));
diff --git a/public/docs/_examples/forms-deprecated/js/app/hero.js b/public/docs/_examples/forms-deprecated/js/app/hero.js
deleted file mode 100644
index 9c2449c922..0000000000
--- a/public/docs/_examples/forms-deprecated/js/app/hero.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// #docregion
-(function(app) {
- app.Hero = Hero;
-
- function Hero(id, name, power, alterEgo) {
- this.id = id;
- this.name = name;
- this.power = power;
- this.alterEgo = alterEgo;
- }
-})(window.app || (window.app = {}));
diff --git a/public/docs/_examples/forms-deprecated/js/app/main.js b/public/docs/_examples/forms-deprecated/js/app/main.js
deleted file mode 100644
index 5930bdd061..0000000000
--- a/public/docs/_examples/forms-deprecated/js/app/main.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// #docregion
-(function(app) {
- document.addEventListener('DOMContentLoaded', function() {
- ng.platformBrowserDynamic.bootstrap(app.AppComponent);
- });
-})(window.app || (window.app = {}));
diff --git a/public/docs/_examples/forms-deprecated/js/forms.css b/public/docs/_examples/forms-deprecated/js/forms.css
deleted file mode 100644
index d7e11405b1..0000000000
--- a/public/docs/_examples/forms-deprecated/js/forms.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/* #docregion */
-.ng-valid[required] {
- border-left: 5px solid #42A948; /* green */
-}
-
-.ng-invalid {
- border-left: 5px solid #a94442; /* red */
-}
-/* #enddocregion */
\ No newline at end of file
diff --git a/public/docs/_examples/forms-deprecated/js/index.html b/public/docs/_examples/forms-deprecated/js/index.html
deleted file mode 100644
index e15f41e4fe..0000000000
--- a/public/docs/_examples/forms-deprecated/js/index.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
- Hero Form
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Loading...
-
-
-
diff --git a/public/docs/_examples/forms-deprecated/js/plnkr.json b/public/docs/_examples/forms-deprecated/js/plnkr.json
deleted file mode 100644
index 0105283bd3..0000000000
--- a/public/docs/_examples/forms-deprecated/js/plnkr.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "description": "Forms",
- "files":["app/**/*.js", "**/*.html", "**/*.css"]
-}
diff --git a/public/docs/_examples/forms-deprecated/ts/app/app.component.ts b/public/docs/_examples/forms-deprecated/ts/app/app.component.ts
deleted file mode 100644
index 2dcbc8037a..0000000000
--- a/public/docs/_examples/forms-deprecated/ts/app/app.component.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// #docregion
-import { Component } from '@angular/core';
-import { HeroFormComponent } from './hero-form.component';
-
-@Component({
- selector: 'my-app',
- template: ' ',
- directives: [HeroFormComponent]
-})
-export class AppComponent { }
diff --git a/public/docs/_examples/forms-deprecated/ts/app/hero-form.component.html b/public/docs/_examples/forms-deprecated/ts/app/hero-form.component.html
deleted file mode 100644
index 6fcfc2a7cb..0000000000
--- a/public/docs/_examples/forms-deprecated/ts/app/hero-form.component.html
+++ /dev/null
@@ -1,208 +0,0 @@
-
-
-
-
-
-
-
-
-
You submitted the following:
-
-
Name
-
{{ model.name }}
-
-
-
Alter Ego
-
{{ model.alterEgo }}
-
-
-
Power
-
{{ model.power }}
-
-
-
Edit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TODO: remove this: {{model.name}}
-
-
-
-
- TODO: remove this: {{model.name}}
-
-
-
-
-
-
diff --git a/public/docs/_examples/forms-deprecated/ts/app/hero-form.component.ts b/public/docs/_examples/forms-deprecated/ts/app/hero-form.component.ts
deleted file mode 100644
index 7ea7c44738..0000000000
--- a/public/docs/_examples/forms-deprecated/ts/app/hero-form.component.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-// #docplaster
-// #docregion
-// #docregion first, final
-import { Component } from '@angular/core';
-import { NgForm } from '@angular/common';
-
-import { Hero } from './hero';
-
-@Component({
- selector: 'hero-form',
- templateUrl: 'app/hero-form.component.html'
-})
-export class HeroFormComponent {
-
- powers = ['Really Smart', 'Super Flexible',
- 'Super Hot', 'Weather Changer'];
-
- model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet');
-
- // #docregion submitted
- submitted = false;
-
- onSubmit() { this.submitted = true; }
- // #enddocregion submitted
-
- // #enddocregion final
- // TODO: Remove this when we're done
- get diagnostic() { return JSON.stringify(this.model); }
- // #enddocregion first
-
- // #docregion final
- // Reset the form with a new hero AND restore 'pristine' class state
- // by toggling 'active' flag which causes the form
- // to be removed/re-added in a tick via NgIf
- // TODO: Workaround until NgForm has a reset method (#6822)
- // #docregion new-hero
- active = true;
-
- // #docregion new-hero-v1
- newHero() {
- this.model = new Hero(42, '', '');
- // #enddocregion new-hero-v1
- this.active = false;
- setTimeout(() => this.active = true, 0);
- // #docregion new-hero-v1
- }
- // #enddocregion new-hero-v1
- // #enddocregion new-hero
- // #enddocregion final
- //////// NOT SHOWN IN DOCS ////////
-
- // Reveal in html:
- // Name via form.controls = {{showFormControls(heroForm)}}
- showFormControls(form: NgForm) {
-
- return form && form.controls['name'] &&
- // #docregion form-controls
- form.controls['name'].value; // Dr. IQ
- // #enddocregion form-controls
- }
-
- /////////////////////////////
-
- // #docregion first, final
-}
-// #enddocregion first, final
diff --git a/public/docs/_examples/forms-deprecated/ts/app/main.ts b/public/docs/_examples/forms-deprecated/ts/app/main.ts
deleted file mode 100644
index 5338161d66..0000000000
--- a/public/docs/_examples/forms-deprecated/ts/app/main.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// #docregion
-import { bootstrap } from '@angular/platform-browser-dynamic';
-
-import { AppComponent } from './app.component';
-
-bootstrap(AppComponent);
diff --git a/public/docs/_examples/forms/dart/pubspec.yaml b/public/docs/_examples/forms/dart/pubspec.yaml
index 89b203abf0..43a19366d7 100644
--- a/public/docs/_examples/forms/dart/pubspec.yaml
+++ b/public/docs/_examples/forms/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/forms/js/app/hero-form.component.js b/public/docs/_examples/forms/js/app/hero-form.component.js
index 428ff82d35..505993a1fd 100644
--- a/public/docs/_examples/forms/js/app/hero-form.component.js
+++ b/public/docs/_examples/forms/js/app/hero-form.component.js
@@ -48,5 +48,5 @@
// #docregion first, final
});
- // #enddocregion first, final
})(window.app || (window.app = {}));
+// #enddocregion first, final
diff --git a/public/docs/_examples/forms/js/index.html b/public/docs/_examples/forms/js/index.html
index fe525d5549..e67b53ac26 100644
--- a/public/docs/_examples/forms/js/index.html
+++ b/public/docs/_examples/forms/js/index.html
@@ -20,7 +20,7 @@
-
+
diff --git a/public/docs/_examples/forms/ts/forms.css b/public/docs/_examples/forms/ts/forms.css
index d7e11405b1..13ffbe1203 100644
--- a/public/docs/_examples/forms/ts/forms.css
+++ b/public/docs/_examples/forms/ts/forms.css
@@ -1,9 +1,9 @@
/* #docregion */
-.ng-valid[required] {
+.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
-.ng-invalid {
+.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
-/* #enddocregion */
\ No newline at end of file
+/* #enddocregion */
diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml b/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml
index d81a211702..d18bc10490 100644
--- a/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml
+++ b/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/homepage-hello-world/ts/index.1.html b/public/docs/_examples/homepage-hello-world/ts/index.1.html
index ce0bdfbaf9..5637880406 100644
--- a/public/docs/_examples/homepage-hello-world/ts/index.1.html
+++ b/public/docs/_examples/homepage-hello-world/ts/index.1.html
@@ -2,19 +2,19 @@
- Angular 2 Hello World
+ Angular Hello World
-
+
-
-
-
-
+
+
+
+
diff --git a/public/docs/_examples/homepage-hello-world/ts/index.html b/public/docs/_examples/homepage-hello-world/ts/index.html
index 794935d3bb..283343ace7 100644
--- a/public/docs/_examples/homepage-hello-world/ts/index.html
+++ b/public/docs/_examples/homepage-hello-world/ts/index.html
@@ -2,7 +2,7 @@
- Angular 2 Hello World
+ Angular Hello World
diff --git a/public/docs/_examples/homepage-tabs/ts/app/app.module.ts b/public/docs/_examples/homepage-tabs/ts/app/app.module.ts
new file mode 100644
index 0000000000..bd2193755c
--- /dev/null
+++ b/public/docs/_examples/homepage-tabs/ts/app/app.module.ts
@@ -0,0 +1,17 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+
+import { DiDemoComponent } from './di_demo';
+import { UiTabsComponent, UiPaneDirective } from './ui_tabs';
+
+@NgModule({
+ imports: [ BrowserModule ],
+ declarations: [
+ DiDemoComponent,
+ UiTabsComponent,
+ UiPaneDirective
+ ],
+ bootstrap: [ DiDemoComponent ]
+})
+export class AppModule { }
diff --git a/public/docs/_examples/homepage-tabs/ts/app/di_demo.ts b/public/docs/_examples/homepage-tabs/ts/app/di_demo.ts
index cbf2e6db57..be72ae5c79 100644
--- a/public/docs/_examples/homepage-tabs/ts/app/di_demo.ts
+++ b/public/docs/_examples/homepage-tabs/ts/app/di_demo.ts
@@ -1,8 +1,6 @@
// #docregion
import { Component } from '@angular/core';
-import { UiTabsComponent, UiPaneDirective } from './ui_tabs';
-
class Detail {
title: string;
text: string;
@@ -26,8 +24,7 @@ class Detail {
Add Detail
- `,
- directives: [UiTabsComponent, UiPaneDirective]
+ `
})
export class DiDemoComponent {
details: Detail[] = [];
diff --git a/public/docs/_examples/homepage-tabs/ts/app/main.ts b/public/docs/_examples/homepage-tabs/ts/app/main.ts
index c77f15f7bb..961a226688 100644
--- a/public/docs/_examples/homepage-tabs/ts/app/main.ts
+++ b/public/docs/_examples/homepage-tabs/ts/app/main.ts
@@ -1,6 +1,6 @@
// #docregion
-import { bootstrap } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
-import { DiDemoComponent } from './di_demo';
+import { AppModule } from './app.module';
-bootstrap(DiDemoComponent);
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/homepage-tabs/ts/index.1.html b/public/docs/_examples/homepage-tabs/ts/index.1.html
index c790439682..6ff25956dc 100644
--- a/public/docs/_examples/homepage-tabs/ts/index.1.html
+++ b/public/docs/_examples/homepage-tabs/ts/index.1.html
@@ -2,7 +2,7 @@
- Angular 2 Tabs
+ Angular Tabs
@@ -10,12 +10,12 @@
-
+
-
-
-
-
+
+
+
+
diff --git a/public/docs/_examples/homepage-tabs/ts/index.html b/public/docs/_examples/homepage-tabs/ts/index.html
index 1fe2ebc8ba..66ce8f3ecc 100644
--- a/public/docs/_examples/homepage-tabs/ts/index.html
+++ b/public/docs/_examples/homepage-tabs/ts/index.html
@@ -2,7 +2,7 @@
- Angular 2 Tabs
+ Angular Tabs
diff --git a/public/docs/_examples/homepage-todo/ts/app/app.module.ts b/public/docs/_examples/homepage-todo/ts/app/app.module.ts
index 344a98f417..a77bb640ab 100644
--- a/public/docs/_examples/homepage-todo/ts/app/app.module.ts
+++ b/public/docs/_examples/homepage-todo/ts/app/app.module.ts
@@ -4,13 +4,19 @@ import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { TodoAppComponent } from './todo_app';
+import { TodoListComponent } from './todo_list';
+import { TodoFormComponent } from './todo_form';
@NgModule({
imports: [
BrowserModule,
FormsModule
],
- declarations: [ TodoAppComponent ],
+ declarations: [
+ TodoAppComponent,
+ TodoListComponent,
+ TodoFormComponent
+ ],
bootstrap: [ TodoAppComponent ]
})
export class AppModule { }
diff --git a/public/docs/_examples/homepage-todo/ts/app/todo_app.ts b/public/docs/_examples/homepage-todo/ts/app/todo_app.ts
index 1c1c7bbb6c..e56bad95b6 100644
--- a/public/docs/_examples/homepage-todo/ts/app/todo_app.ts
+++ b/public/docs/_examples/homepage-todo/ts/app/todo_app.ts
@@ -2,8 +2,6 @@
import { Component } from '@angular/core';
import { Todo } from './todo';
-import { TodoListComponent } from './todo_list';
-import { TodoFormComponent } from './todo_form';
@Component({
selector: 'todo-app',
@@ -14,8 +12,7 @@ import { TodoFormComponent } from './todo_form';
`,
- styles: ['a { cursor: pointer; cursor: hand; }'],
- directives: [TodoListComponent, TodoFormComponent]
+ styles: ['a { cursor: pointer; cursor: hand; }']
})
export class TodoAppComponent {
todos: Todo[] = [
diff --git a/public/docs/_examples/homepage-todo/ts/index.1.html b/public/docs/_examples/homepage-todo/ts/index.1.html
index d926bbe323..26800d3e05 100644
--- a/public/docs/_examples/homepage-todo/ts/index.1.html
+++ b/public/docs/_examples/homepage-todo/ts/index.1.html
@@ -2,7 +2,7 @@
- Angular 2 Todos
+ Angular Todos
@@ -10,12 +10,12 @@
-
+
-
-
-
-
+
+
+
+
diff --git a/public/docs/_examples/homepage-todo/ts/index.html b/public/docs/_examples/homepage-todo/ts/index.html
index 2bddce017c..8839065224 100644
--- a/public/docs/_examples/homepage-todo/ts/index.html
+++ b/public/docs/_examples/homepage-todo/ts/index.html
@@ -2,7 +2,7 @@
- Angular 2 Todos
+ Angular Todos
diff --git a/public/docs/_examples/karma-test-shim.js b/public/docs/_examples/karma-test-shim.js
deleted file mode 100644
index ec50e1ff66..0000000000
--- a/public/docs/_examples/karma-test-shim.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// /*global jasmine, __karma__, window*/
-Error.stackTraceLimit = Infinity;
-jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
-
-__karma__.loaded = function () {
-};
-
-function isJsFile(path) {
- return path.slice(-3) == '.js';
-}
-
-function isSpecFile(path) {
- return /\.spec\.js$/.test(path);
-}
-
-function isBuiltFile(path) {
- var builtPath = '/base/app/';
- return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
-}
-
-var allSpecFiles = Object.keys(window.__karma__.files)
- .filter(isSpecFile)
- .filter(isBuiltFile);
-
-System.config({
- baseURL: '/base',
- packageWithIndex: true // sadly, we can't use umd packages (yet?)
-});
-
-System.import('systemjs.config.js')
- .then(function () {
- return Promise.all([
- System.import('@angular/core/testing'),
- System.import('@angular/platform-browser-dynamic/testing')
- ])
- })
- .then(function (providers) {
- var testing = providers[0];
- var testingBrowser = providers[1];
-
- testing.setBaseTestProviders(
- testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
- testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
-
- })
- .then(function() {
- // Finally, load all spec files.
- // This will run the tests directly.
- return Promise.all(
- allSpecFiles.map(function (moduleName) {
- return System.import(moduleName);
- }));
- })
- .then(__karma__.start, __karma__.error);
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart
index c405c874ac..9c2413c559 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart
@@ -7,7 +7,7 @@ import 'logger_service.dart';
//////////////////
// #docregion child-view
@Component(
- selector: 'my-child',
+ selector: 'my-child-view',
template: ' ')
class ChildViewComponent {
String hero = 'Magneta';
@@ -20,7 +20,7 @@ class ChildViewComponent {
// #docregion template
template: '''
-- child view begins --
-
+
-- child view ends --
''',
// #enddocregion template
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_component.dart
index 5483b9be8f..3208a18777 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_component.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_component.dart
@@ -1,6 +1,4 @@
// #docregion
-import 'dart:convert';
-
import 'package:angular2/core.dart';
class Hero {
@@ -23,7 +21,7 @@ class Hero {
'.hero {background: LightYellow; padding: 8px; margin-top: 8px}',
'p {background: Yellow; padding: 8px; margin-top: 8px}'
])
-class DoCheckComponent implements DoCheck, OnChanges {
+class DoCheckComponent implements DoCheck {
@Input()
Hero hero;
@Input()
@@ -72,16 +70,6 @@ class DoCheckComponent implements DoCheck, OnChanges {
}
// #enddocregion ng-do-check
- // Copied from OnChangesComponent
- ngOnChanges(Map changes) {
- changes.forEach((String propName, SimpleChange change) {
- String cur = JSON.encode(change.currentValue);
- String prev =
- change.isFirstChange() ? "{}" : JSON.encode(change.previousValue);
- changeLog.add('$propName: currentValue = $cur, previousValue = $prev');
- });
- }
-
void reset() {
changeDetected = true;
changeLog.clear();
@@ -92,7 +80,7 @@ class DoCheckComponent implements DoCheck, OnChanges {
@Component(
selector: 'do-check-parent',
- templateUrl: 'on_changes_parent_component.html',
+ templateUrl: 'do_check_parent_component.html',
styles: const ['.parent {background: Lavender}'],
directives: const [DoCheckComponent])
class DoCheckParentComponent {
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_parent_component.html b/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_parent_component.html
new file mode 100644
index 0000000000..ef3c30be28
--- /dev/null
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_parent_component.html
@@ -0,0 +1,13 @@
+
+
{{title}}
+
+
+
Reset Log
+
+
+
+
+
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_parent_component.html b/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_parent_component.html
index 7889ce8e91..a0fd404931 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_parent_component.html
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_parent_component.html
@@ -7,8 +7,7 @@
Reset Log
-
+
-
-
+
diff --git a/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml b/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml
index 0710ddbb86..e1bda01d28 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml
+++ b/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/lifecycle-hooks/dart/web/main.dart b/public/docs/_examples/lifecycle-hooks/dart/web/main.dart
index 5013275e6a..f9143d4116 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/web/main.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/web/main.dart
@@ -1,8 +1,6 @@
-// #docregion
import 'package:angular2/platform/browser.dart';
-
import 'package:lifecycle_hooks/app_component.dart';
-main() {
+void main() {
bootstrap(AppComponent);
}
diff --git a/public/docs/_examples/lifecycle-hooks/e2e-spec.ts b/public/docs/_examples/lifecycle-hooks/e2e-spec.ts
index f86218e9a8..156ea3c3a9 100644
--- a/public/docs/_examples/lifecycle-hooks/e2e-spec.ts
+++ b/public/docs/_examples/lifecycle-hooks/e2e-spec.ts
@@ -66,8 +66,8 @@ describe('Lifecycle hooks', function () {
expect(titleEle.getText()).toContain('Windstorm can sing');
changeLogEles.count().then(function(count) {
- // Empirically 5 messages to start
- expect(count).toBeGreaterThan(4, 'should start with some messages');
+ // 3 messages to start
+ expect(count).toEqual(3, 'should start with 3 messages');
logCount = count;
// heroNameInputEle.sendKeys('-foo-').then(function () {
return sendKeys(heroNameInputEle, '-foo-');
@@ -82,8 +82,7 @@ describe('Lifecycle hooks', function () {
return sendKeys(powerInputEle, '-bar-');
}).then(function () {
expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-');
- // 7 == 2 previously + length of '-bar-'
- expect(changeLogEles.count()).toEqual(logCount + 11, 'should add 11 more messages');
+ expect(changeLogEles.count()).toEqual(logCount + 6, 'should add 6 more messages');
});
});
diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/do-check.component.ts b/public/docs/_examples/lifecycle-hooks/ts/app/do-check.component.ts
index 1ffdd23ba7..6dfcf8dd43 100644
--- a/public/docs/_examples/lifecycle-hooks/ts/app/do-check.component.ts
+++ b/public/docs/_examples/lifecycle-hooks/ts/app/do-check.component.ts
@@ -1,6 +1,6 @@
/* tslint:disable:forin */
// #docregion
-import { Component, DoCheck, Input, OnChanges, SimpleChange, ViewChild } from '@angular/core';
+import { Component, DoCheck, Input, ViewChild } from '@angular/core';
class Hero {
constructor(public name: string) {}
@@ -21,7 +21,7 @@ class Hero {
'p {background: Yellow; padding: 8px; margin-top: 8px}'
]
})
-export class DoCheckComponent implements DoCheck, OnChanges {
+export class DoCheckComponent implements DoCheck {
@Input() hero: Hero;
@Input() power: string;
@@ -66,16 +66,6 @@ export class DoCheckComponent implements DoCheck, OnChanges {
}
// #enddocregion ng-do-check
- // Copied from OnChangesComponent
- ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
- for (let propName in changes) {
- let chng = changes[propName];
- let cur = JSON.stringify(chng.currentValue);
- let prev = JSON.stringify(chng.previousValue);
- this.changeLog.push(`OnChanges: ${propName}: currentValue = ${cur}, previousValue = ${prev}`);
- }
- }
-
reset() {
this.changeDetected = true;
this.changeLog.length = 0;
diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/main.ts b/public/docs/_examples/lifecycle-hooks/ts/app/main.ts
index 4acf5de663..2470c9595e 100644
--- a/public/docs/_examples/lifecycle-hooks/ts/app/main.ts
+++ b/public/docs/_examples/lifecycle-hooks/ts/app/main.ts
@@ -1,4 +1,3 @@
-// #docregion
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/on-changes-parent.component.html b/public/docs/_examples/lifecycle-hooks/ts/app/on-changes-parent.component.html
index 5c76a6056c..a0fd404931 100644
--- a/public/docs/_examples/lifecycle-hooks/ts/app/on-changes-parent.component.html
+++ b/public/docs/_examples/lifecycle-hooks/ts/app/on-changes-parent.component.html
@@ -7,7 +7,7 @@
Reset Log
-
+
-
+
diff --git a/public/docs/_examples/lifecycle-hooks/ts/index.html b/public/docs/_examples/lifecycle-hooks/ts/index.html
index 6fa866c6e6..07cf7d4a03 100644
--- a/public/docs/_examples/lifecycle-hooks/ts/index.html
+++ b/public/docs/_examples/lifecycle-hooks/ts/index.html
@@ -2,7 +2,7 @@
- Angular 2 Lifecycle Hooks
+ Angular Lifecycle Hooks
diff --git a/public/docs/_examples/ngmodule/e2e-spec.ts b/public/docs/_examples/ngmodule/e2e-spec.ts
index 9279b26fd0..de8f4fa7e0 100644
--- a/public/docs/_examples/ngmodule/e2e-spec.ts
+++ b/public/docs/_examples/ngmodule/e2e-spec.ts
@@ -6,6 +6,7 @@ describe('NgModule', function () {
const gold = 'rgba(255, 215, 0, 1)';
const powderblue = 'rgba(176, 224, 230, 1)';
const lightgray = 'rgba(211, 211, 211, 1)';
+ const white = 'rgba(0, 0, 0, 0)';
function getCommonsSectionStruct() {
const buttons = element.all(by.css('nav a'));
@@ -55,7 +56,7 @@ describe('NgModule', function () {
}
// tests
- function appTitleTests(color: string) {
+ function appTitleTests(color: string, name?: string) {
return function() {
it('should have a gray header', function() {
const commons = getCommonsSectionStruct();
@@ -64,16 +65,16 @@ describe('NgModule', function () {
it('should welcome us', function () {
const commons = getCommonsSectionStruct();
- expect(commons.subtitle.getText()).toBe('Welcome, Sam Spade');
+ expect(commons.subtitle.getText()).toBe('Welcome, ' + (name || 'Sherlock Holmes'));
});
};
}
- function contactTests(color: string) {
+ function contactTests(color: string, name?: string) {
return function() {
it('shows the contact\'s owner', function() {
const contacts = getContactSectionStruct();
- expect(contacts.header.getText()).toBe('Contact of Sam Spade');
+ expect(contacts.header.getText()).toBe('Contact of ' + (name || 'Sherlock Holmes'));
});
it('can cycle between contacts', function () {
@@ -114,9 +115,9 @@ describe('NgModule', function () {
browser.get('');
});
- describe('app-title', appTitleTests(lightgray));
+ describe('app-title', appTitleTests(white, 'Miss Marple'));
- describe('contact', contactTests(lightgray));
+ describe('contact', contactTests(lightgray, 'Miss Marple'));
describe('crisis center', function () {
beforeEach(function () {
@@ -149,7 +150,7 @@ describe('NgModule', function () {
it('shows a list of heroes', function() {
const heroes = getHeroesSectionStruct();
- expect(heroes.header.getText()).toBe('Heroes of Sam Spade');
+ expect(heroes.header.getText()).toBe('Heroes of Miss Marple');
expect(heroes.title.getText()).toBe('Hero List');
expect(heroes.items.count()).toBe(6);
expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice');
diff --git a/public/docs/_examples/ngmodule/ts/app/app.module.3.ts b/public/docs/_examples/ngmodule/ts/app/app.module.3.ts
index 8aa968a31c..8920c00b61 100644
--- a/public/docs/_examples/ngmodule/ts/app/app.module.3.ts
+++ b/public/docs/_examples/ngmodule/ts/app/app.module.3.ts
@@ -11,8 +11,6 @@ import { UserService } from './user.service';
/* Feature Modules */
import { ContactModule } from './contact/contact.module.3';
-
-
import { routing } from './app.routing.3';
@NgModule({
@@ -23,9 +21,8 @@ import { routing } from './app.routing.3';
routing
],
// #enddocregion imports
-
- declarations: [ AppComponent, HighlightDirective, TitleComponent ],
providers: [ UserService ],
+ declarations: [ AppComponent, HighlightDirective, TitleComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
diff --git a/public/docs/_examples/ngmodule/ts/app/app.module.ts b/public/docs/_examples/ngmodule/ts/app/app.module.ts
index 7f7ede96e1..cccb49c981 100644
--- a/public/docs/_examples/ngmodule/ts/app/app.module.ts
+++ b/public/docs/_examples/ngmodule/ts/app/app.module.ts
@@ -1,29 +1,40 @@
// #docplaster
// #docregion
+// #docregion v4
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
/* App Root */
import { AppComponent } from './app.component';
-
-
-
/* Feature Modules */
import { ContactModule } from './contact/contact.module';
-import { SharedModule } from './shared/shared.module';
-
+import { CoreModule } from './core/core.module';
import { routing } from './app.routing';
@NgModule({
+ // #docregion import-for-root
imports: [
BrowserModule,
ContactModule,
- routing,
- SharedModule.forRoot()
+// #enddocregion v4
+// #enddocregion
+// #enddocregion import-for-root
+/*
+// #docregion v4
+ CoreModule,
+// #enddocregion v4
+*/
+// #docregion import-for-root
+// #docregion
+ CoreModule.forRoot({userName: 'Miss Marple'}),
+// #docregion v4
+ routing
],
+ // #enddocregion import-for-root
declarations: [ AppComponent ],
-
bootstrap: [ AppComponent ]
})
export class AppModule { }
+// #enddocregion v4
+// #enddocregion
diff --git a/public/docs/_examples/ngmodule/ts/app/app.routing.3.ts b/public/docs/_examples/ngmodule/ts/app/app.routing.3.ts
index 96eebf5dac..9c9129023c 100644
--- a/public/docs/_examples/ngmodule/ts/app/app.routing.3.ts
+++ b/public/docs/_examples/ngmodule/ts/app/app.routing.3.ts
@@ -1,10 +1,10 @@
-import { Routes,
- RouterModule } from '@angular/router';
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
- { path: 'crisis', loadChildren: 'app/crisis/crisis.module' },
- { path: 'heroes', loadChildren: 'app/hero/hero.module.3' }
+ { path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
+ { path: 'heroes', loadChildren: 'app/hero/hero.module.3#HeroModule' }
];
-export const routing = RouterModule.forRoot(routes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
diff --git a/public/docs/_examples/ngmodule/ts/app/app.routing.ts b/public/docs/_examples/ngmodule/ts/app/app.routing.ts
index 09fa0225d8..f34498c4e1 100644
--- a/public/docs/_examples/ngmodule/ts/app/app.routing.ts
+++ b/public/docs/_examples/ngmodule/ts/app/app.routing.ts
@@ -1,15 +1,15 @@
// #docregion
-import { Routes,
- RouterModule } from '@angular/router';
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
// #docregion lazy-routes
- { path: 'crisis', loadChildren: 'app/crisis/crisis.module' },
- { path: 'heroes', loadChildren: 'app/hero/hero.module' }
+ { path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
+ { path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' }
// #enddocregion lazy-routes
];
// #docregion forRoot
-export const routing = RouterModule.forRoot(routes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
// #enddocregion forRoot
diff --git a/public/docs/_examples/ngmodule/ts/app/contact/contact.component.3.ts b/public/docs/_examples/ngmodule/ts/app/contact/contact.component.3.ts
index 019e477e63..392904086a 100644
--- a/public/docs/_examples/ngmodule/ts/app/contact/contact.component.3.ts
+++ b/public/docs/_examples/ngmodule/ts/app/contact/contact.component.3.ts
@@ -5,9 +5,10 @@ import { Contact, ContactService } from './contact.service';
import { UserService } from '../user.service';
@Component({
+ moduleId: module.id,
selector: 'app-contact',
- templateUrl: 'app/contact/contact.component.html',
- styleUrls: ['app/contact/contact.component.css']
+ templateUrl: 'contact.component.html',
+ styleUrls: ['contact.component.css']
})
export class ContactComponent implements OnInit {
contact: Contact;
@@ -35,7 +36,7 @@ export class ContactComponent implements OnInit {
}
onSubmit() {
- // TODO: do something like save it
+ // POST-DEMO TODO: do something like save it
this.displayMessage('Saved ' + this.contact.name);
}
diff --git a/public/docs/_examples/ngmodule/ts/app/contact/contact.component.ts b/public/docs/_examples/ngmodule/ts/app/contact/contact.component.ts
index 9bf9bc0ee9..bb6f2e3b42 100644
--- a/public/docs/_examples/ngmodule/ts/app/contact/contact.component.ts
+++ b/public/docs/_examples/ngmodule/ts/app/contact/contact.component.ts
@@ -1,14 +1,15 @@
-// Exact copy except import UserService from shared
+// Exact copy except import UserService from core
// #docregion
import { Component, OnInit } from '@angular/core';
import { Contact, ContactService } from './contact.service';
-import { UserService } from '../shared/user.service';
+import { UserService } from '../core/user.service';
@Component({
+ moduleId: module.id,
selector: 'app-contact',
- templateUrl: 'app/contact/contact.component.html',
- styleUrls: ['app/contact/contact.component.css']
+ templateUrl: 'contact.component.html',
+ styleUrls: ['contact.component.css']
})
export class ContactComponent implements OnInit {
contact: Contact;
@@ -36,7 +37,7 @@ export class ContactComponent implements OnInit {
}
onSubmit() {
- // TODO: do something like save it
+ // POST-DEMO TODO: do something like save it
this.displayMessage('Saved ' + this.contact.name);
}
diff --git a/public/docs/_examples/ngmodule/ts/app/contact/contact.module.3.ts b/public/docs/_examples/ngmodule/ts/app/contact/contact.module.3.ts
index d28d67d085..6f835635d0 100644
--- a/public/docs/_examples/ngmodule/ts/app/contact/contact.module.3.ts
+++ b/public/docs/_examples/ngmodule/ts/app/contact/contact.module.3.ts
@@ -15,7 +15,6 @@ import { routing } from './contact.routing.3';
@NgModule({
imports: [ CommonModule, FormsModule, routing ],
declarations: [ ContactComponent, HighlightDirective, AwesomePipe ],
-
providers: [ ContactService ]
})
export class ContactModule { }
diff --git a/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.3.ts b/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.3.ts
index f90fc36789..63d740d82e 100644
--- a/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.3.ts
+++ b/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.3.ts
@@ -1,7 +1,8 @@
-import { RouterModule } from '@angular/router';
+import { ModuleWithProviders } from '@angular/core';
+import { RouterModule } from '@angular/router';
-import { ContactComponent } from './contact.component.3';
+import { ContactComponent } from './contact.component.3';
-export const routing = RouterModule.forChild([
+export const routing: ModuleWithProviders = RouterModule.forChild([
{ path: 'contact', component: ContactComponent}
]);
diff --git a/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.ts b/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.ts
index fe9af67fbf..6b6534dfbc 100644
--- a/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.ts
+++ b/public/docs/_examples/ngmodule/ts/app/contact/contact.routing.ts
@@ -1,9 +1,10 @@
-import { RouterModule } from '@angular/router';
+import { ModuleWithProviders } from '@angular/core';
+import { RouterModule } from '@angular/router';
-import { ContactComponent } from './contact.component';
+import { ContactComponent } from './contact.component';
// #docregion routing
-export const routing = RouterModule.forChild([
+export const routing: ModuleWithProviders = RouterModule.forChild([
{ path: 'contact', component: ContactComponent}
]);
// #enddocregion
diff --git a/public/docs/_examples/ngmodule/ts/app/core/core.module.ts b/public/docs/_examples/ngmodule/ts/app/core/core.module.ts
new file mode 100644
index 0000000000..27cb9a2193
--- /dev/null
+++ b/public/docs/_examples/ngmodule/ts/app/core/core.module.ts
@@ -0,0 +1,48 @@
+/* tslint:disable:member-ordering no-unused-variable */
+// #docplaster
+// #docregion
+// #docregion v4
+import {
+ ModuleWithProviders, NgModule,
+ Optional, SkipSelf } from '@angular/core';
+
+import { CommonModule } from '@angular/common';
+
+import { TitleComponent } from './title.component';
+import { UserService } from './user.service';
+// #enddocregion
+import { UserServiceConfig } from './user.service';
+
+// #docregion v4
+@NgModule({
+ imports: [ CommonModule ],
+ declarations: [ TitleComponent ],
+ exports: [ TitleComponent ],
+ providers: [ UserService ]
+})
+export class CoreModule {
+// #enddocregion v4
+
+ // #docregion ctor
+ constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
+ if (parentModule) {
+ throw new Error(
+ 'CoreModule is already loaded. Import it in the AppModule only');
+ }
+ }
+ // #enddocregion ctor
+
+ // #docregion for-root
+ static forRoot(config: UserServiceConfig): ModuleWithProviders {
+ return {
+ ngModule: CoreModule,
+ providers: [
+ {provide: UserServiceConfig, useValue: config }
+ ]
+ };
+ }
+ // #enddocregion for-root
+// #docregion v4
+}
+// #enddocregion v4
+// #enddocregion
diff --git a/public/docs/_examples/ngmodule/ts/app/shared/title.component.html b/public/docs/_examples/ngmodule/ts/app/core/title.component.html
similarity index 63%
rename from public/docs/_examples/ngmodule/ts/app/shared/title.component.html
rename to public/docs/_examples/ngmodule/ts/app/core/title.component.html
index 6108c38415..8ebd08ae43 100644
--- a/public/docs/_examples/ngmodule/ts/app/shared/title.component.html
+++ b/public/docs/_examples/ngmodule/ts/app/core/title.component.html
@@ -1,4 +1,4 @@
-
+
{{title}} {{subtitle}}
Welcome, {{user}}
diff --git a/public/docs/_examples/ngmodule/ts/app/shared/title.component.ts b/public/docs/_examples/ngmodule/ts/app/core/title.component.ts
similarity index 74%
rename from public/docs/_examples/ngmodule/ts/app/shared/title.component.ts
rename to public/docs/_examples/ngmodule/ts/app/core/title.component.ts
index c3f35b5d32..be2df3acf1 100644
--- a/public/docs/_examples/ngmodule/ts/app/shared/title.component.ts
+++ b/public/docs/_examples/ngmodule/ts/app/core/title.component.ts
@@ -1,10 +1,11 @@
// Exact copy of app/title.component.ts except import UserService from shared
import { Component, Input } from '@angular/core';
-import { UserService } from './user.service';
+import { UserService } from '../core/user.service';
@Component({
+ moduleId: module.id,
selector: 'app-title',
- templateUrl: 'app/shared/title.component.html',
+ templateUrl: 'title.component.html',
})
export class TitleComponent {
@Input() subtitle = '';
diff --git a/public/docs/_examples/ngmodule/ts/app/core/user.service.ts b/public/docs/_examples/ngmodule/ts/app/core/user.service.ts
new file mode 100644
index 0000000000..8fe839075e
--- /dev/null
+++ b/public/docs/_examples/ngmodule/ts/app/core/user.service.ts
@@ -0,0 +1,32 @@
+// Crazy copy of the app/user.service
+// Proves that UserService is an app-wide singleton and only instantiated once
+// IFF shared.module follows the `forRoot` pattern
+//
+// If it didn't, a new instance of UserService would be created
+// after each lazy load and the userName would double up.
+
+import { Injectable, Optional } from '@angular/core';
+
+let nextId = 1;
+
+export class UserServiceConfig {
+ userName = 'Philip Marlowe';
+}
+
+@Injectable()
+export class UserService {
+ id = nextId++;
+ private _userName = 'Sherlock Holmes';
+
+ // #docregion ctor
+ constructor(@Optional() config: UserServiceConfig) {
+ if (config) { this._userName = config.userName; }
+ }
+ // #enddocregion ctor
+
+ get userName() {
+ // Demo: add a suffix if this service has been created more than once
+ const suffix = this.id > 1 ? ` times ${this.id}` : '';
+ return this._userName + suffix;
+ }
+}
diff --git a/public/docs/_examples/ngmodule/ts/app/crisis/crisis-detail.component.ts b/public/docs/_examples/ngmodule/ts/app/crisis/crisis-detail.component.ts
index da9efb3b2b..9749029d62 100644
--- a/public/docs/_examples/ngmodule/ts/app/crisis/crisis-detail.component.ts
+++ b/public/docs/_examples/ngmodule/ts/app/crisis/crisis-detail.component.ts
@@ -1,5 +1,5 @@
-import { Component, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
@Component({
template: `
diff --git a/public/docs/_examples/ngmodule/ts/app/crisis/crisis.module.ts b/public/docs/_examples/ngmodule/ts/app/crisis/crisis.module.ts
index 6a759cf87e..40491985dc 100644
--- a/public/docs/_examples/ngmodule/ts/app/crisis/crisis.module.ts
+++ b/public/docs/_examples/ngmodule/ts/app/crisis/crisis.module.ts
@@ -11,6 +11,4 @@ import { routing } from './crisis.routing';
declarations: [ CrisisDetailComponent, CrisisListComponent ],
providers: [ CrisisService ]
})
-// #docregion export-default
-export default class CrisisModule {}
-// #enddocregion export-default
+export class CrisisModule {}
diff --git a/public/docs/_examples/ngmodule/ts/app/crisis/crisis.routing.ts b/public/docs/_examples/ngmodule/ts/app/crisis/crisis.routing.ts
index a0e8b850b7..4d8d711d65 100644
--- a/public/docs/_examples/ngmodule/ts/app/crisis/crisis.routing.ts
+++ b/public/docs/_examples/ngmodule/ts/app/crisis/crisis.routing.ts
@@ -1,5 +1,6 @@
+import { ModuleWithProviders } from '@angular/core';
import { Routes,
- RouterModule } from '@angular/router';
+ RouterModule } from '@angular/router';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail.component';
@@ -10,4 +11,4 @@ const routes: Routes = [
{ path: ':id', component: CrisisDetailComponent }
];
-export const routing = RouterModule.forChild(routes);
+export const routing: ModuleWithProviders = RouterModule.forChild(routes);
diff --git a/public/docs/_examples/ngmodule/ts/app/hero/hero.component.ts b/public/docs/_examples/ngmodule/ts/app/hero/hero.component.ts
index 3329e25cc0..86338fb0ae 100644
--- a/public/docs/_examples/ngmodule/ts/app/hero/hero.component.ts
+++ b/public/docs/_examples/ngmodule/ts/app/hero/hero.component.ts
@@ -1,8 +1,8 @@
-// Exact copy except import UserService from shared
+// Exact copy except import UserService from core
import { Component } from '@angular/core';
import { HeroService } from './hero.service';
-import { UserService } from '../shared/user.service';
+import { UserService } from '../core/user.service';
@Component({
template: `
diff --git a/public/docs/_examples/ngmodule/ts/app/hero/hero.module.3.ts b/public/docs/_examples/ngmodule/ts/app/hero/hero.module.3.ts
index def1432fc4..319af623bb 100644
--- a/public/docs/_examples/ngmodule/ts/app/hero/hero.module.3.ts
+++ b/public/docs/_examples/ngmodule/ts/app/hero/hero.module.3.ts
@@ -1,12 +1,12 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { FormsModule } from '@angular/forms';
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
-import { HeroComponent } from './hero.component.3';
-import { HeroDetailComponent } from './hero-detail.component';
-import { HeroListComponent } from './hero-list.component';
-import { HighlightDirective } from './highlight.directive';
-import { routing } from './hero.routing.3';
+import { HeroComponent } from './hero.component.3';
+import { HeroDetailComponent } from './hero-detail.component';
+import { HeroListComponent } from './hero-list.component';
+import { HighlightDirective } from './highlight.directive';
+import { routing } from './hero.routing.3';
// #docregion class
@NgModule({
@@ -16,5 +16,5 @@ import { routing } from './hero.routing.3';
HighlightDirective
]
})
-export default class HeroModule { }
+export class HeroModule { }
// #enddocregion class
diff --git a/public/docs/_examples/ngmodule/ts/app/hero/hero.module.ts b/public/docs/_examples/ngmodule/ts/app/hero/hero.module.ts
index d49455fa0b..57159ed533 100644
--- a/public/docs/_examples/ngmodule/ts/app/hero/hero.module.ts
+++ b/public/docs/_examples/ngmodule/ts/app/hero/hero.module.ts
@@ -1,23 +1,16 @@
-import { NgModule } from '@angular/core';
+import { NgModule } from '@angular/core';
-import { SharedModule } from '../shared/shared.module';
+import { SharedModule } from '../shared/shared.module';
-import { HeroComponent } from './hero.component';
-import { HeroDetailComponent } from './hero-detail.component';
-import { HeroListComponent } from './hero-list.component';
-import { routing } from './hero.routing';
-
-/*
- * TODO: Remove THE HeroService class and provider after
- * https://github.com/angular/angular/pull/10579 lands
- */
-import { HeroService } from './hero.service';
+import { HeroComponent } from './hero.component';
+import { HeroDetailComponent } from './hero-detail.component';
+import { HeroListComponent } from './hero-list.component';
+import { routing } from './hero.routing';
@NgModule({
imports: [ SharedModule, routing ],
- providers: [ HeroService ],
declarations: [
HeroComponent, HeroDetailComponent, HeroListComponent,
]
})
-export default class HeroModule { }
+export class HeroModule { }
diff --git a/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.3.ts b/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.3.ts
index 181e48faf5..132d21b29e 100644
--- a/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.3.ts
+++ b/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.3.ts
@@ -1,9 +1,10 @@
+import { ModuleWithProviders } from '@angular/core';
import { Routes,
- RouterModule } from '@angular/router';
+ RouterModule } from '@angular/router';
-import { HeroComponent } from './hero.component.3';
-import { HeroListComponent } from './hero-list.component';
-import { HeroDetailComponent } from './hero-detail.component';
+import { HeroComponent } from './hero.component.3';
+import { HeroListComponent } from './hero-list.component';
+import { HeroDetailComponent } from './hero-detail.component';
const routes: Routes = [
{ path: '',
@@ -15,4 +16,4 @@ const routes: Routes = [
}
];
-export const routing = RouterModule.forChild(routes);
+export const routing: ModuleWithProviders = RouterModule.forChild(routes);
diff --git a/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.ts b/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.ts
index 951ffd7d12..f1b4285ecd 100644
--- a/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.ts
+++ b/public/docs/_examples/ngmodule/ts/app/hero/hero.routing.ts
@@ -1,9 +1,10 @@
+import { ModuleWithProviders } from '@angular/core';
import { Routes,
- RouterModule } from '@angular/router';
+ RouterModule } from '@angular/router';
-import { HeroComponent } from './hero.component';
-import { HeroListComponent } from './hero-list.component';
-import { HeroDetailComponent } from './hero-detail.component';
+import { HeroComponent } from './hero.component';
+import { HeroListComponent } from './hero-list.component';
+import { HeroDetailComponent } from './hero-detail.component';
const routes: Routes = [
{ path: '',
@@ -15,4 +16,4 @@ const routes: Routes = [
}
];
-export const routing = RouterModule.forChild(routes);
+export const routing: ModuleWithProviders = RouterModule.forChild(routes);
diff --git a/public/docs/_examples/ngmodule/ts/app/shared/shared.module.ts b/public/docs/_examples/ngmodule/ts/app/shared/shared.module.ts
index 5991278d44..2da7d7b2a5 100644
--- a/public/docs/_examples/ngmodule/ts/app/shared/shared.module.ts
+++ b/public/docs/_examples/ngmodule/ts/app/shared/shared.module.ts
@@ -1,40 +1,18 @@
// #docregion
-import { NgModule,
- ModuleWithProviders } from '@angular/core';
+import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AwesomePipe } from './awesome.pipe';
import { HighlightDirective } from './highlight.directive';
-import { TitleComponent } from './title.component';
-import { UserService } from './user.service';
-// #docregion shared-module
+// #docregion module
@NgModule({
imports: [ CommonModule ],
- declarations: [ AwesomePipe, HighlightDirective, TitleComponent ],
- exports: [ AwesomePipe, HighlightDirective, TitleComponent,
+ declarations: [ AwesomePipe, HighlightDirective ],
+ exports: [ AwesomePipe, HighlightDirective,
CommonModule, FormsModule ]
})
-export class SharedModule {
-
-// #docregion for-root
- static forRoot(): ModuleWithProviders {
- return {
- ngModule: SharedModule,
- providers: [ UserService ]
- };
- }
-// #enddocregion for-root
-}
-
-// #enddocregion shared-module
+export class SharedModule { }
+// #enddocregion module
// #enddocregion
-
-// #docregion shared-root-module
-@NgModule({
- exports: [ SharedModule ],
- providers: [ UserService ]
-})
-export class SharedRootModule { }
-// #enddocregion shared-root-module
diff --git a/public/docs/_examples/ngmodule/ts/app/shared/user.service.ts b/public/docs/_examples/ngmodule/ts/app/shared/user.service.ts
deleted file mode 100644
index d32b20b043..0000000000
--- a/public/docs/_examples/ngmodule/ts/app/shared/user.service.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// Crazy copy of the app/user.service
-// Proves that UserService is an app-wide singleton and only instantiated once
-// IFF shared.module follows the `forRoot` pattern
-//
-// If it didn't, a new instance of UserService would be created
-// after each lazy load and the userName would double up.
-
-import { Injectable } from '@angular/core';
-
-@Injectable()
-export class UserService {
-
- static userName = '';
-
- constructor() {
- UserService.userName += UserService.userName || 'Sam Spade';
- }
-
- get userName() { return UserService.userName; }
-}
diff --git a/public/docs/_examples/ngmodule/ts/app/title.component.ts b/public/docs/_examples/ngmodule/ts/app/title.component.ts
index 0edfd4b468..cd5a19aad0 100644
--- a/public/docs/_examples/ngmodule/ts/app/title.component.ts
+++ b/public/docs/_examples/ngmodule/ts/app/title.component.ts
@@ -7,8 +7,9 @@ import { UserService } from './user.service';
// #docregion v1
@Component({
+ moduleId: module.id,
selector: 'app-title',
- templateUrl: 'app/title.component.html',
+ templateUrl: 'title.component.html',
})
export class TitleComponent {
@Input() subtitle = '';
diff --git a/public/docs/_examples/ngmodule/ts/app/user.service.ts b/public/docs/_examples/ngmodule/ts/app/user.service.ts
index cf31db5da5..7d996b26fa 100644
--- a/public/docs/_examples/ngmodule/ts/app/user.service.ts
+++ b/public/docs/_examples/ngmodule/ts/app/user.service.ts
@@ -4,5 +4,5 @@ import { Injectable } from '@angular/core';
@Injectable()
/** Dummy version of an authenticated user service */
export class UserService {
- userName = 'Sam Spade';
+ userName = 'Sherlock Holmes';
}
diff --git a/public/docs/_examples/ngmodule/ts/contact.1b.plnkr.json b/public/docs/_examples/ngmodule/ts/contact.1b.plnkr.json
index 77804a3be1..090a440059 100644
--- a/public/docs/_examples/ngmodule/ts/contact.1b.plnkr.json
+++ b/public/docs/_examples/ngmodule/ts/contact.1b.plnkr.json
@@ -9,11 +9,12 @@
"app/title.component.ts",
"app/user.service.ts",
- "app/contact/*.css",
- "app/contact/*.html",
- "app/contact/*.ts",
- "!app/contact/contact.component.ts",
- "!app/contact/contact.module.ts",
+ "app/contact/awesome.pipe.ts",
+ "app/contact/contact.component.css",
+ "app/contact/contact.component.html",
+ "app/contact/contact.component.3.ts",
+ "app/contact/contact.service.ts",
+ "app/contact/highlight.directive.ts",
"styles.css",
"index.1b.html"
diff --git a/public/docs/_examples/ngmodule/ts/contact.2.plnkr.json b/public/docs/_examples/ngmodule/ts/contact.2.plnkr.json
index b7da9b879f..4ee4638a63 100644
--- a/public/docs/_examples/ngmodule/ts/contact.2.plnkr.json
+++ b/public/docs/_examples/ngmodule/ts/contact.2.plnkr.json
@@ -9,12 +9,14 @@
"app/title.component.ts",
"app/user.service.ts",
- "app/contact/*.css",
- "app/contact/*.html",
- "app/contact/*.ts",
- "!app/contact/contact.component.ts",
- "!app/contact/contact.module.ts",
- "!app/contact/contact.module.3.ts",
+ "app/contact/contact.component.css",
+ "app/contact/contact.component.html",
+ "app/contact/contact.service.ts",
+
+ "app/contact/awesome.pipe.ts",
+ "app/contact/contact.component.3.ts",
+ "app/contact/contact.module.2.ts",
+ "app/contact/highlight.directive.ts",
"styles.css",
"index.2.html"
diff --git a/public/docs/_examples/ngmodule/ts/plnkr.json b/public/docs/_examples/ngmodule/ts/plnkr.json
index 54b3da8310..fbc92ce13b 100644
--- a/public/docs/_examples/ngmodule/ts/plnkr.json
+++ b/public/docs/_examples/ngmodule/ts/plnkr.json
@@ -8,19 +8,25 @@
"app/contact/contact.component.css",
"app/contact/contact.component.html",
+ "app/contact/contact.service.ts",
+
"app/contact/contact.component.ts",
"app/contact/contact.module.ts",
"app/contact/contact.routing.ts",
- "app/contact/contact.service.ts",
"app/crisis/*.ts",
- "app/hero/*.ts",
+ "app/hero/hero-detail.component.ts",
+ "app/hero/hero-list.component.ts",
+ "app/hero/hero.service.ts",
- "!app/hero/hero.component.3.ts",
- "!app/hero/hero.module.3.ts",
- "!app/hero/hero.routing.3.ts",
- "!app/hero/highlight.directive.ts",
+ "app/hero/hero.component.ts",
+ "app/hero/hero.module.ts",
+ "app/hero/hero.routing.ts",
+
+ "app/core/*.css",
+ "app/core/*.html",
+ "app/core/*.ts",
"app/shared/*.css",
"app/shared/*.html",
diff --git a/public/docs/_examples/ngmodule/ts/pre-shared.3.plnkr.json b/public/docs/_examples/ngmodule/ts/pre-shared.3.plnkr.json
index dcdfb6e77f..6a7b39e2a2 100644
--- a/public/docs/_examples/ngmodule/ts/pre-shared.3.plnkr.json
+++ b/public/docs/_examples/ngmodule/ts/pre-shared.3.plnkr.json
@@ -11,21 +11,26 @@
"app/title.component.ts",
"app/user.service.ts",
- "app/contact/*.css",
- "app/contact/*.html",
- "app/contact/*.ts",
+ "app/contact/contact.component.css",
+ "app/contact/contact.component.html",
+ "app/contact/contact.service.ts",
- "!app/contact/contact.component.ts",
- "!app/contact/contact.module.ts",
- "!app/contact/contact.routing.ts",
+ "app/contact/awesome.pipe.ts",
+ "app/contact/contact.component.3.ts",
+ "app/contact/contact.module.3.ts",
+ "app/contact/contact.routing.3.ts",
+ "app/contact/highlight.directive.ts",
"app/crisis/*.ts",
- "app/hero/*.ts",
+ "app/hero/hero-detail.component.ts",
+ "app/hero/hero-list.component.ts",
+ "app/hero/hero.service.ts",
- "!app/hero/hero.component.ts",
- "!app/hero/hero.module.ts",
- "!app/hero/hero.routing.ts",
+ "app/hero/hero.component.3.ts",
+ "app/hero/hero.module.3.ts",
+ "app/hero/hero.routing.3.ts",
+ "app/hero/highlight.directive.ts",
"styles.css",
"index.3.html"
diff --git a/public/docs/_examples/package.json b/public/docs/_examples/package.json
index 7015bd0767..7baee8a5a9 100644
--- a/public/docs/_examples/package.json
+++ b/public/docs/_examples/package.json
@@ -19,35 +19,41 @@
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
"test:webpack": "karma start karma.webpack.conf.js",
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
- "build:cli": "ng build"
+ "build:cli": "ng build",
+ "build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.5",
- "@angular/compiler": "2.0.0-rc.5",
- "@angular/core": "2.0.0-rc.5",
- "@angular/forms": "0.3.0",
- "@angular/http": "2.0.0-rc.5",
- "@angular/platform-browser": "2.0.0-rc.5",
- "@angular/platform-browser-dynamic": "2.0.0-rc.5",
- "@angular/router": "3.0.0-rc.1",
- "@angular/router-deprecated": "2.0.0-rc.2",
- "@angular/upgrade": "2.0.0-rc.5",
- "angular2-in-memory-web-api": "0.0.15",
+ "@angular/common": "2.0.0",
+ "@angular/compiler": "2.0.0",
+ "@angular/compiler-cli": "0.6.2",
+ "@angular/core": "2.0.0",
+ "@angular/forms": "2.0.0",
+ "@angular/http": "2.0.0",
+ "@angular/platform-browser": "2.0.0",
+ "@angular/platform-browser-dynamic": "2.0.0",
+ "@angular/platform-server": "2.0.0",
+ "@angular/router": "3.0.0",
+ "@angular/upgrade": "2.0.0",
+ "angular2-in-memory-web-api": "0.0.20",
"bootstrap": "^3.3.6",
- "core-js": "^2.4.0",
+ "core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
- "rxjs": "5.0.0-beta.6",
+ "rollup": "^0.34.13",
+ "rollup-plugin-node-resolve": "^2.0.0",
+ "rollup-plugin-uglify": "^1.0.1",
+ "rxjs": "5.0.0-beta.12",
"systemjs": "0.19.27",
- "zone.js": "^0.6.12"
+ "zone.js": "^0.6.23"
},
"devDependencies": {
"angular-cli": "^1.0.0-beta.5",
"angular2-template-loader": "^0.4.0",
+ "awesome-typescript-loader": "^2.2.4",
"canonical-path": "0.0.2",
- "concurrently": "^2.1.0",
+ "concurrently": "^2.2.0",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
@@ -55,27 +61,29 @@
"html-webpack-plugin": "^2.16.1",
"http-server": "^0.9.0",
"jasmine-core": "^2.4.1",
- "karma": "^0.13.22",
- "karma-chrome-launcher": "^1.0.1",
- "karma-cli": "^1.0.0",
- "karma-htmlfile-reporter": "^0.3.1",
+ "karma": "^1.2.0",
+ "karma-chrome-launcher": "^2.0.0",
+ "karma-cli": "^1.0.1",
+ "karma-htmlfile-reporter": "^0.3.4",
"karma-jasmine": "^1.0.2",
- "karma-phantomjs-launcher": "^1.0.0",
+ "karma-jasmine-html-reporter": "^0.2.2",
+ "karma-phantomjs-launcher": "^1.0.2",
"karma-sourcemap-loader": "^0.3.7",
- "karma-webpack": "^1.7.0",
- "lite-server": "^2.2.0",
+ "karma-webpack": "^1.8.0",
+ "lite-server": "^2.2.2",
"lodash": "^4.13.1",
"null-loader": "^0.1.1",
"phantomjs-prebuilt": "^2.1.7",
"protractor": "^3.3.0",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
+ "rollup-plugin-commonjs": "^4.1.0",
"style-loader": "^0.13.1",
"ts-loader": "^0.8.2",
- "ts-node": "^0.7.3",
- "tslint": "^3.13.0",
- "typescript": "^1.8.10",
- "typings": "^1.0.4",
+ "ts-node": "^1.3.0",
+ "tslint": "^3.15.1",
+ "typescript": "^2.0.2",
+ "typings": "^1.3.2",
"webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1",
"webpack-merge": "^0.14.0"
diff --git a/public/docs/_examples/pipes/dart/pubspec.yaml b/public/docs/_examples/pipes/dart/pubspec.yaml
index 4afa2870c0..e48db77d96 100644
--- a/public/docs/_examples/pipes/dart/pubspec.yaml
+++ b/public/docs/_examples/pipes/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/pipes/e2e-spec.ts b/public/docs/_examples/pipes/e2e-spec.ts
index 01c9e5fd13..5f9c4607dc 100644
--- a/public/docs/_examples/pipes/e2e-spec.ts
+++ b/public/docs/_examples/pipes/e2e-spec.ts
@@ -64,7 +64,7 @@ describe('Pipes', function () {
});
- it('should support flying heroes (pure) ', function () {
+ xit('should support flying heroes (pure) ', function () {
let nameEle = element(by.css('flying-heroes input[type="text"]'));
let canFlyCheckEle = element(by.css('flying-heroes #can-fly'));
let mutateCheckEle = element(by.css('flying-heroes #mutate'));
@@ -95,7 +95,7 @@ describe('Pipes', function () {
});
- it('should support flying heroes (impure) ', function () {
+ xit('should support flying heroes (impure) ', function () {
let nameEle = element(by.css('flying-heroes-impure input[type="text"]'));
let canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly'));
let mutateCheckEle = element(by.css('flying-heroes-impure #mutate'));
diff --git a/public/docs/_examples/plunker.README.md b/public/docs/_examples/plunker.README.md
index 5bcc99414d..fa2e46f47a 100644
--- a/public/docs/_examples/plunker.README.md
+++ b/public/docs/_examples/plunker.README.md
@@ -1,2 +1,2 @@
-### Angular 2 Documentation Example
+### Angular Documentation Example
diff --git a/public/docs/_examples/quickstart/dart/pubspec.yaml b/public/docs/_examples/quickstart/dart/pubspec.yaml
index 0c08200992..b8ad984d4c 100644
--- a/public/docs/_examples/quickstart/dart/pubspec.yaml
+++ b/public/docs/_examples/quickstart/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/quickstart/dart/web/styles_1.css b/public/docs/_examples/quickstart/dart/web/styles_1.css
deleted file mode 100644
index 27e60d67c0..0000000000
--- a/public/docs/_examples/quickstart/dart/web/styles_1.css
+++ /dev/null
@@ -1,14 +0,0 @@
-/* #docregion */
-h1 {
- color: #369;
- font-family: Arial, Helvetica, sans-serif;
- font-size: 250%;
-}
-body {
- margin: 2em;
-}
-
-/*
-* See https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css
-* for the full set of master styles used by the documentation samples
-*/
diff --git a/public/docs/_examples/quickstart/e2e-spec.ts b/public/docs/_examples/quickstart/e2e-spec.ts
index 4a6d169756..5a1c683cfd 100644
--- a/public/docs/_examples/quickstart/e2e-spec.ts
+++ b/public/docs/_examples/quickstart/e2e-spec.ts
@@ -2,7 +2,7 @@
'use strict';
describe('QuickStart E2E Tests', function () {
- let expectedMsg = 'My First Angular 2 App';
+ let expectedMsg = 'My First Angular App';
beforeEach(function () {
browser.get('');
diff --git a/public/docs/_examples/quickstart/js/app/app.component.js b/public/docs/_examples/quickstart/js/app/app.component.js
index f86b3bde46..69d3e9127e 100644
--- a/public/docs/_examples/quickstart/js/app/app.component.js
+++ b/public/docs/_examples/quickstart/js/app/app.component.js
@@ -10,7 +10,7 @@
ng.core.Component({
// #enddocregion ng-namespace-funcs
selector: 'my-app',
- template: '
My First Angular 2 App '
+ template: 'My First Angular App '
// #docregion ng-namespace-funcs
})
// #enddocregion component
diff --git a/public/docs/_examples/quickstart/js/index.html b/public/docs/_examples/quickstart/js/index.html
index b127bdce13..03fcbb37c4 100644
--- a/public/docs/_examples/quickstart/js/index.html
+++ b/public/docs/_examples/quickstart/js/index.html
@@ -2,7 +2,7 @@
- Angular 2 QuickStart JS
+ Angular QuickStart JS
@@ -16,7 +16,7 @@
-
+
diff --git a/public/docs/_examples/quickstart/js/package.1.json b/public/docs/_examples/quickstart/js/package.1.json
index 5b3ecbc847..cca103a52f 100644
--- a/public/docs/_examples/quickstart/js/package.1.json
+++ b/public/docs/_examples/quickstart/js/package.1.json
@@ -7,23 +7,22 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.5",
- "@angular/compiler": "2.0.0-rc.5",
- "@angular/core": "2.0.0-rc.5",
- "@angular/forms": "0.3.0",
- "@angular/http": "2.0.0-rc.5",
- "@angular/platform-browser": "2.0.0-rc.5",
- "@angular/platform-browser-dynamic": "2.0.0-rc.5",
- "@angular/router": "3.0.0-rc.1",
- "@angular/router-deprecated": "2.0.0-rc.2",
- "@angular/upgrade": "2.0.0-rc.5",
+ "@angular/common": "2.0.0",
+ "@angular/compiler": "2.0.0",
+ "@angular/core": "2.0.0",
+ "@angular/forms": "2.0.0",
+ "@angular/http": "2.0.0",
+ "@angular/platform-browser": "2.0.0",
+ "@angular/platform-browser-dynamic": "2.0.0",
+ "@angular/router": "3.0.0",
+ "@angular/upgrade": "2.0.0",
- "core-js": "^2.4.0",
- "reflect-metadata": "0.1.3",
- "rxjs": "5.0.0-beta.6",
- "zone.js": "0.6.12",
+ "core-js": "^2.4.1",
+ "reflect-metadata": "^0.1.3",
+ "rxjs": "5.0.0-beta.12",
+ "zone.js": "^0.6.23",
- "angular2-in-memory-web-api": "0.0.15",
+ "angular2-in-memory-web-api": "0.0.20",
"bootstrap": "^3.3.6"
},
"devDependencies": {
diff --git a/public/docs/_examples/quickstart/ts/app/app.component.ts b/public/docs/_examples/quickstart/ts/app/app.component.ts
index ea76b32116..e6c635440b 100644
--- a/public/docs/_examples/quickstart/ts/app/app.component.ts
+++ b/public/docs/_examples/quickstart/ts/app/app.component.ts
@@ -6,7 +6,7 @@ import { Component } from '@angular/core';
// #docregion metadata
@Component({
selector: 'my-app',
- template: 'My First Angular 2 App '
+ template: 'My First Angular App '
})
// #enddocregion metadata
// #docregion class
diff --git a/public/docs/_examples/quickstart/ts/app/app.module.1.ts b/public/docs/_examples/quickstart/ts/app/app.module.1.ts
new file mode 100644
index 0000000000..cd9673617d
--- /dev/null
+++ b/public/docs/_examples/quickstart/ts/app/app.module.1.ts
@@ -0,0 +1,8 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+
+@NgModule({
+ imports: [ BrowserModule ]
+})
+export class AppModule { }
diff --git a/public/docs/_examples/quickstart/ts/app/app.module.ts b/public/docs/_examples/quickstart/ts/app/app.module.ts
index b4fc185c24..a8b40a7650 100644
--- a/public/docs/_examples/quickstart/ts/app/app.module.ts
+++ b/public/docs/_examples/quickstart/ts/app/app.module.ts
@@ -2,11 +2,12 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
-import { AppComponent } from './app.component';
+import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
+
export class AppModule { }
diff --git a/public/docs/_examples/quickstart/ts/app/main.ts b/public/docs/_examples/quickstart/ts/app/main.ts
index 4ad787ebfd..e36de73708 100644
--- a/public/docs/_examples/quickstart/ts/app/main.ts
+++ b/public/docs/_examples/quickstart/ts/app/main.ts
@@ -5,4 +5,5 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
// #enddocregion import
-platformBrowserDynamic().bootstrapModule(AppModule);
+const platform = platformBrowserDynamic();
+platform.bootstrapModule(AppModule);
diff --git a/public/docs/_examples/quickstart/ts/index.html b/public/docs/_examples/quickstart/ts/index.html
index a0a64d1122..4ee082433c 100644
--- a/public/docs/_examples/quickstart/ts/index.html
+++ b/public/docs/_examples/quickstart/ts/index.html
@@ -2,17 +2,17 @@
- Angular 2 QuickStart
+ Angular QuickStart
-
+
-
+
diff --git a/public/docs/_examples/quickstart/ts/package.1.json b/public/docs/_examples/quickstart/ts/package.1.json
index 4f0bc098fd..35efebb2c2 100644
--- a/public/docs/_examples/quickstart/ts/package.1.json
+++ b/public/docs/_examples/quickstart/ts/package.1.json
@@ -1,5 +1,5 @@
{
- "name": "angular2-quickstart",
+ "name": "angular-quickstart",
"version": "1.0.0",
"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
@@ -11,30 +11,29 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.5",
- "@angular/compiler": "2.0.0-rc.5",
- "@angular/core": "2.0.0-rc.5",
- "@angular/forms": "0.3.0",
- "@angular/http": "2.0.0-rc.5",
- "@angular/platform-browser": "2.0.0-rc.5",
- "@angular/platform-browser-dynamic": "2.0.0-rc.5",
- "@angular/router": "3.0.0-rc.1",
- "@angular/router-deprecated": "2.0.0-rc.2",
- "@angular/upgrade": "2.0.0-rc.5",
+ "@angular/common": "2.0.0",
+ "@angular/compiler": "2.0.0",
+ "@angular/core": "2.0.0",
+ "@angular/forms": "2.0.0",
+ "@angular/http": "2.0.0",
+ "@angular/platform-browser": "2.0.0",
+ "@angular/platform-browser-dynamic": "2.0.0",
+ "@angular/router": "3.0.0",
+ "@angular/upgrade": "2.0.0",
- "systemjs": "0.19.27",
- "core-js": "^2.4.0",
+ "core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
- "rxjs": "5.0.0-beta.6",
- "zone.js": "^0.6.12",
+ "rxjs": "5.0.0-beta.12",
+ "systemjs": "0.19.27",
+ "zone.js": "^0.6.23",
- "angular2-in-memory-web-api": "0.0.15",
+ "angular2-in-memory-web-api": "0.0.20",
"bootstrap": "^3.3.6"
},
"devDependencies": {
- "concurrently": "^2.0.0",
- "lite-server": "^2.2.0",
- "typescript": "^1.8.10",
- "typings":"^1.0.4"
+ "concurrently": "^2.2.0",
+ "lite-server": "^2.2.2",
+ "typescript": "^2.0.2",
+ "typings":"^1.3.2"
}
}
diff --git a/public/docs/_examples/quickstart/ts/styles.1.css b/public/docs/_examples/quickstart/ts/styles.1.css
deleted file mode 100644
index fbc30e2c9e..0000000000
--- a/public/docs/_examples/quickstart/ts/styles.1.css
+++ /dev/null
@@ -1,14 +0,0 @@
-/* #docregion */
-h1 {
- color: #369;
- font-family: Arial, Helvetica, sans-serif;
- font-size: 250%;
-}
-body {
- margin: 2em;
-}
-
- /*
- * See https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css
- * for the full set of master styles used by the documentation samples
- */
diff --git a/public/docs/_examples/quickstart/ts/systemjs.config.1.js b/public/docs/_examples/quickstart/ts/systemjs.config.1.js
index 901b8f01d0..852c46168d 100644
--- a/public/docs/_examples/quickstart/ts/systemjs.config.1.js
+++ b/public/docs/_examples/quickstart/ts/systemjs.config.1.js
@@ -1,60 +1,46 @@
// #docregion
/**
- * System configuration for Angular 2 samples
+ * System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
-(function(global) {
+(function (global) {
+ System.config({
+ paths: {
+ // paths serve as alias
+ 'npm:': 'node_modules/'
+ },
+ // map tells the System loader where to look for things
+ map: {
+ // our app is within the app folder
+ app: 'app',
- // map tells the System loader where to look for things
- var map = {
- 'app': 'app', // 'dist',
-
- '@angular': 'node_modules/@angular',
- 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
- 'rxjs': 'node_modules/rxjs'
- };
-
- // packages tells the System loader how to load when no filename and/or no extension
- var packages = {
- 'app': { main: 'main.js', defaultExtension: 'js' },
- 'rxjs': { defaultExtension: 'js' },
- 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
- };
-
- var ngPackageNames = [
- 'common',
- 'compiler',
- 'core',
- 'forms',
- 'http',
- 'platform-browser',
- 'platform-browser-dynamic',
- 'router',
- 'router-deprecated',
- 'upgrade',
- ];
-
- // Individual files (~300 requests):
- function packIndex(pkgName) {
- packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
- }
-
- // Bundled (~40 requests):
- function packUmd(pkgName) {
- packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
- }
-
- // Most environments should use UMD; some (Karma) need the individual index files
- var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
-
- // Add package entries for angular packages
- ngPackageNames.forEach(setPackageConfig);
-
- var config = {
- map: map,
- packages: packages
- };
-
- System.config(config);
+ // angular bundles
+ '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
+ '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
+ '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
+ '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
+ '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
+ '@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',
+ // other libraries
+ 'rxjs': 'npm:rxjs',
+ 'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
+ },
+ // packages tells the System loader how to load when no filename and/or no extension
+ packages: {
+ app: {
+ main: './main.js',
+ defaultExtension: 'js'
+ },
+ rxjs: {
+ defaultExtension: 'js'
+ },
+ 'angular2-in-memory-web-api': {
+ main: './index.js',
+ defaultExtension: 'js'
+ }
+ }
+ });
})(this);
diff --git a/public/docs/_examples/quickstart/ts/typings.1.json b/public/docs/_examples/quickstart/ts/typings.1.json
index 3d826df25a..7da31ca0af 100644
--- a/public/docs/_examples/quickstart/ts/typings.1.json
+++ b/public/docs/_examples/quickstart/ts/typings.1.json
@@ -1,7 +1,7 @@
{
"globalDependencies": {
- "core-js": "registry:dt/core-js#0.0.0+20160602141332",
+ "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+20160807145350"
+ "node": "registry:dt/node#6.0.0+20160909174046"
}
}
diff --git a/public/docs/_examples/router-deprecated/e2e-spec.ts.disabled b/public/docs/_examples/router-deprecated/e2e-spec.ts.disabled
deleted file mode 100644
index 3892285845..0000000000
--- a/public/docs/_examples/router-deprecated/e2e-spec.ts.disabled
+++ /dev/null
@@ -1,127 +0,0 @@
-///
-'use strict';
-describe('Router', function () {
-
- beforeAll(function () {
- browser.get('');
- });
-
- function getPageStruct() {
- let hrefEles = element.all(by.css('my-app a'));
-
- return {
- hrefs: hrefEles,
- routerParent: element(by.css('my-app > undefined')),
- routerTitle: element(by.css('my-app > undefined > h2')),
-
- crisisHref: hrefEles.get(0),
- crisisList: element.all(by.css('my-app > undefined > undefined li')),
- crisisDetail: element(by.css('my-app > undefined > undefined > div')),
- crisisDetailTitle: element(by.css('my-app > undefined > undefined > div > h3')),
-
- heroesHref: hrefEles.get(1),
- heroesList: element.all(by.css('my-app > undefined li')),
- heroDetail: element(by.css('my-app > undefined > div')),
- heroDetailTitle: element(by.css('my-app > undefined > div > h3')),
-
- };
- }
-
- it('should be able to see the start screen', function () {
- let page = getPageStruct();
- expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
- expect(page.crisisHref.getText()).toEqual('Crisis Center');
- expect(page.heroesHref.getText()).toEqual('Heroes');
- });
-
- it('should be able to see crises center items', function () {
- let page = getPageStruct();
- expect(page.crisisList.count()).toBe(4, 'should be 4 crisis center entries at start');
- });
-
- it('should be able to see hero items', function () {
- let page = getPageStruct();
- page.heroesHref.click().then(function() {
- expect(page.routerTitle.getText()).toContain('HEROES');
- expect(page.heroesList.count()).toBe(6, 'should be 6 heroes');
- });
- });
-
- it('should be able to toggle the views', function () {
- let page = getPageStruct();
- page.crisisHref.click().then(function() {
- expect(page.crisisList.count()).toBe(4, 'should be 4 crisis center entries');
- return page.heroesHref.click();
- }).then(function() {
- expect(page.heroesList.count()).toBe(6, 'should be 6 heroes');
- });
- });
-
- it('should be able to edit and save details from the crisis center view', function () {
- crisisCenterEdit(2, true);
- });
-
- it('should be able to edit and cancel details from the crisis center view', function () {
- crisisCenterEdit(3, false);
- });
-
- it('should be able to edit and save details from the heroes view', function () {
- let page = getPageStruct();
- let heroEle: protractor.ElementFinder;
- let heroText: string;
- page.heroesHref.click().then(function() {
- heroEle = page.heroesList.get(4);
- return heroEle.getText();
- }).then(function(text) {
- expect(text.length).toBeGreaterThan(0, 'should have some text');
- // remove leading id from text
- heroText = text.substr(text.indexOf(' ')).trim();
- return heroEle.click();
- }).then(function() {
- expect(page.heroesList.count()).toBe(0, 'should no longer see crisis center entries');
- expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
- expect(page.heroDetailTitle.getText()).toContain(heroText);
- let inputEle = page.heroDetail.element(by.css('input'));
- return sendKeys(inputEle, '-foo');
- }).then(function() {
- expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo');
- let buttonEle = page.heroDetail.element(by.css('button'));
- return buttonEle.click();
- }).then(function() {
- expect(heroEle.getText()).toContain(heroText + '-foo');
- });
- });
-
- function crisisCenterEdit(index: number, shouldSave: boolean) {
- let page = getPageStruct();
- let crisisEle: protractor.ElementFinder;
- let crisisText: string;
- page.crisisHref.click()
- .then(function () {
- crisisEle = page.crisisList.get(index);
- return crisisEle.getText();
- }).then(function (text) {
- expect(text.length).toBeGreaterThan(0, 'should have some text');
- // remove leading id from text
- crisisText = text.substr(text.indexOf(' ')).trim();
- return crisisEle.click();
- }).then(function () {
- expect(page.crisisList.count()).toBe(0, 'should no longer see crisis center entries');
- expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
- expect(page.crisisDetailTitle.getText()).toContain(crisisText);
- let inputEle = page.crisisDetail.element(by.css('input'));
- return sendKeys(inputEle, '-foo');
- }).then(function () {
- expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo');
- let buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel'));
- return buttonEle.click();
- }).then(function () {
- if (shouldSave) {
- expect(crisisEle.getText()).toContain(crisisText + '-foo');
- } else {
- expect(crisisEle.getText()).not.toContain(crisisText + '-foo');
- }
- });
- }
-
-});
diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.1.ts
deleted file mode 100644
index 0e20623fd3..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/app.component.1.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/* First version */
-// #docplaster
-
-// #docregion
-import { Component } from '@angular/core';
-// #docregion import-router
-import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated';
-// #enddocregion import-router
-
-import { CrisisListComponent } from './crisis-list.component';
-import { HeroListComponent } from './hero-list.component';
-
-@Component({
- selector: 'my-app',
-// #docregion template
- template: `
- Component Router (Deprecated)
-
- Crisis Center
- Heroes
-
-
- `,
-// #enddocregion template
- directives: [ROUTER_DIRECTIVES]
-})
-// #enddocregion
-/*
-// #docregion route-config
-@Component({ ... })
-// #enddocregion route-config
-*/
-// #docregion
-// #docregion route-config
-@RouteConfig([
-// #docregion route-defs
- {path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent},
- {path: '/heroes', name: 'Heroes', component: HeroListComponent}
-// #enddocregion route-defs
-])
-export class AppComponent { }
-// #enddocregion route-config
-// #enddocregion
diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.2.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.2.ts
deleted file mode 100644
index e4685ff418..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/app.component.2.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Second Heroes version */
-// #docplaster
-
-// #docregion
-import { Component } from '@angular/core';
-import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated';
-
-import { CrisisListComponent } from './crisis-list.component';
-// #enddocregion
-/*
-// Apparent Milestone 2 imports
-// #docregion
-// #docregion hero-import
-import { HeroListComponent } from './heroes/hero-list.component';
-import { HeroDetailComponent } from './heroes/hero-detail.component';
-import { HeroService } from './heroes/hero.service';
-// #enddocregion hero-import
-// #enddocregion
-*/
-// Actual Milestone 2 imports
-import { HeroListComponent } from './heroes/hero-list.component.1';
-import { HeroDetailComponent } from './heroes/hero-detail.component.1';
-import { HeroService } from './heroes/hero.service';
-// #docregion
-
-@Component({
- selector: 'my-app',
- template: `
- Component Router (Deprecated)
-
- Crisis Center
- Heroes
-
-
- `,
- providers: [HeroService],
- directives: [ROUTER_DIRECTIVES]
-})
-// #enddocregion
-/*
-// #docregion route-config
-@Component({ ... })
-// #enddocregion route-config
-*/
-// #docregion
-// #docregion route-config
-@RouteConfig([
-// #docregion route-defs
- {path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent},
- {path: '/heroes', name: 'Heroes', component: HeroListComponent},
- // #docregion hero-detail-route
- {path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent}
- // #enddocregion hero-detail-route
-// #enddocregion route-defs
-])
-export class AppComponent { }
-// #enddocregion route-config
-// #enddocregion
diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.3.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.3.ts
deleted file mode 100644
index 68635e8aad..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/app.component.3.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// #docplaster
-import { Component } from '@angular/core';
-import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated';
-
-import { CrisisCenterComponent } from './crisis-center/crisis-center.component.1';
-import { DialogService } from './dialog.service';
-import { HeroService } from './heroes/hero.service';
-
-@Component({
- selector: 'my-app',
-// #enddocregion
- /* Typical link
- // #docregion h-anchor
- Heroes
- // #enddocregion h-anchor
- */
- /* Incomplete Crisis Center link when CC lacks a default
- // #docregion cc-anchor-fail
- // The link now fails with a "non-terminal link" error
- // #docregion cc-anchor-w-default
- Crisis Center
- // #enddocregion cc-anchor-w-default
- // #enddocregion cc-anchor-fail
- */
- /* Crisis Center link when CC lacks a default
- // #docregion cc-anchor-no-default
- Crisis Center
- // #enddocregion cc-anchor-no-default
- */
- /* Crisis Center Detail link
- // #docregion Dragon-anchor
- Dragon Crisis
- // #enddocregion Dragon-anchor
- */
-// #docregion template
- template: `
- Component Router (Deprecated)
-
- Crisis Center
- Dragon Crisis
- Shark Crisis
-
-
- `,
-// #enddocregion template
- providers: [DialogService, HeroService],
- directives: [ROUTER_DIRECTIVES]
-})
-@RouteConfig([
- {path: '/crisis-center/...', name: 'CrisisCenter', component: CrisisCenterComponent},
-])
-export class AppComponent { }
diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.ts
deleted file mode 100644
index a6f784cda9..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/app.component.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-// #docplaster
-// #docregion
-import { Component } from '@angular/core';
-import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated';
-
-import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
-import { HeroListComponent } from './heroes/hero-list.component';
-import { HeroDetailComponent } from './heroes/hero-detail.component';
-
-import { DialogService } from './dialog.service';
-import { HeroService } from './heroes/hero.service';
-
-@Component({
- selector: 'my-app',
-// #docregion template
- template: `
- Component Router (Deprecated)
-
- Crisis Center
- Heroes
-
-
- `,
-// #enddocregion template
- providers: [DialogService, HeroService],
- directives: [ROUTER_DIRECTIVES]
-})
-// #docregion route-config
-@RouteConfig([
-
- // #docregion route-config-cc
- { // Crisis Center child route
- path: '/crisis-center/...',
- name: 'CrisisCenter',
- component: CrisisCenterComponent,
- useAsDefault: true
- },
- // #enddocregion route-config-cc
-
- {path: '/heroes', name: 'Heroes', component: HeroListComponent},
- {path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent},
-])
-// #enddocregion route-config
-export class AppComponent { }
diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.1.ts
deleted file mode 100644
index 6925fb8008..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.1.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Component } from '@angular/core';
-import { RouteConfig, RouterOutlet } from '@angular/router-deprecated';
-
-import { CrisisListComponent } from './crisis-list.component.1';
-import { CrisisDetailComponent } from './crisis-detail.component.1';
-import { CrisisService } from './crisis.service';
-
-// #docregion minus-imports
-@Component({
- template: `
- CRISIS CENTER
-
- `,
- directives: [RouterOutlet],
-// #docregion providers
- providers: [CrisisService]
-// #enddocregion providers
-})
-// #docregion route-config
-@RouteConfig([
- // #docregion default-route
- {path: '/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true},
- // #enddocregion default-route
- {path: '/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
-])
-// #enddocregion route-config
-export class CrisisCenterComponent { }
-// #enddocregion minus-imports
diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.ts
deleted file mode 100644
index 3c735ae6ae..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// #docregion
-import { Component } from '@angular/core';
-import { RouteConfig, RouterOutlet } from '@angular/router-deprecated';
-
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisService } from './crisis.service';
-
-@Component({
- template: `
- CRISIS CENTER
-
- `,
- directives: [RouterOutlet],
- providers: [CrisisService]
-})
-@RouteConfig([
- {path: '/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true},
- {path: '/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
-])
-export class CrisisCenterComponent { }
-// #enddocregion
diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-detail.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-detail.component.1.ts
deleted file mode 100644
index 0c683853c9..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-detail.component.1.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-// #docplaster
-
-// #docregion
-import { Component, OnInit } from '@angular/core';
-import { RouteParams, Router } from '@angular/router-deprecated';
-// #docregion routerCanDeactivate
-import { CanDeactivate, ComponentInstruction } from '@angular/router-deprecated';
-
-import { DialogService } from '../dialog.service';
-
-// #enddocregion routerCanDeactivate
-import { Crisis, CrisisService } from './crisis.service';
-
-@Component({
- // #docregion template
- template: `
-
-
"{{editName}}"
-
- Id: {{crisis.id}}
-
- Name:
-
-
-
- Save
- Cancel
-
-
- `,
- // #enddocregion template
- styles: ['input {width: 20em}']
-})
-// #docregion routerCanDeactivate, cancel-save
-export class CrisisDetailComponent implements OnInit, CanDeactivate {
-
- crisis: Crisis;
- editName: string;
-
-// #enddocregion routerCanDeactivate, cancel-save
- constructor(
- private service: CrisisService,
- private router: Router,
- private routeParams: RouteParams,
- private dialog: DialogService
- ) { }
-
- // #docregion ngOnInit
- ngOnInit() {
- let id = +this.routeParams.get('id');
- this.service.getCrisis(id).then(crisis => {
- if (crisis) {
- this.editName = crisis.name;
- this.crisis = crisis;
- } else { // id not found
- this.gotoCrises();
- }
- });
- }
- // #enddocregion ngOnInit
-
- // #docregion routerCanDeactivate
- routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction): any {
- // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged.
- if (!this.crisis || this.crisis.name === this.editName) {
- return true;
- }
- // Otherwise ask the user with the dialog service and return its
- // promise which resolves to true or false when the user decides
- return this.dialog.confirm('Discard changes?');
- }
- // #enddocregion routerCanDeactivate
-
- // #docregion cancel-save
- cancel() {
- this.editName = this.crisis.name;
- this.gotoCrises();
- }
-
- save() {
- this.crisis.name = this.editName;
- this.gotoCrises();
- }
- // #enddocregion cancel-save
-
- // #docregion gotoCrises
- gotoCrises() {
- // Like Crisis Center
- "{{editName}}"
-
- Id: {{crisis.id}}
-
- Name:
-
-
-
- Save
- Cancel
-
-
- `,
- styles: ['input {width: 20em}']
-})
-
-export class CrisisDetailComponent implements OnInit, CanDeactivate {
-
- crisis: Crisis;
- editName: string;
-
- constructor(
- private service: CrisisService,
- private router: Router,
- private routeParams: RouteParams,
- private _dialog: DialogService
- ) { }
-
- ngOnInit() {
- let id = +this.routeParams.get('id');
- this.service.getCrisis(id).then(crisis => {
- if (crisis) {
- this.editName = crisis.name;
- this.crisis = crisis;
- } else { // id not found
- this.gotoCrises();
- }
- });
- }
-
- routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction): any {
- // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged.
- if (!this.crisis || this.crisis.name === this.editName) {
- return true;
- }
- // Otherwise ask the user with the dialog service and return its
- // promise which resolves to true or false when the user decides
- return this._dialog.confirm('Discard changes?');
- }
-
- cancel() {
- this.editName = this.crisis.name;
- this.gotoCrises();
- }
-
- save() {
- this.crisis.name = this.editName;
- this.gotoCrises();
- }
-
- // #docregion gotoCrises
- gotoCrises() {
- let crisisId = this.crisis ? this.crisis.id : null;
- // Pass along the hero id if available
- // so that the CrisisListComponent can select that hero.
- // Add a totally useless `foo` parameter for kicks.
- // #docregion gotoCrises-navigate
- this.router.navigate(['CrisisList', {id: crisisId, foo: 'foo'} ]);
- // #enddocregion gotoCrises-navigate
- }
- // #enddocregion gotoCrises
-}
diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.1.ts
deleted file mode 100644
index 45121da69e..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.1.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-// #docplaster
-
-// #docregion
-import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router-deprecated';
-
-import { Crisis, CrisisService } from './crisis.service';
-
-@Component({
- // #docregion template
- template: `
-
-
- {{crisis.id}} {{crisis.name}}
-
-
- `,
- // #enddocregion template
-})
-export class CrisisListComponent implements OnInit {
- crises: Crisis[];
-
- constructor(
- private service: CrisisService,
- private router: Router) {}
-
- ngOnInit() {
- this.service.getCrises().then(crises => this.crises = crises);
- }
-
- // #docregion select
- onSelect(crisis: Crisis) {
- this.router.navigate(['CrisisDetail', { id: crisis.id }] );
- }
- // #enddocregion select
-}
diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.ts
deleted file mode 100644
index a5770d256f..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-// #docplaster
-
-// #docregion
-import { Component, OnInit } from '@angular/core';
-import { RouteParams, Router } from '@angular/router-deprecated';
-
-import { Crisis, CrisisService } from './crisis.service';
-
-@Component({
- template: `
-
-
- {{crisis.id}} {{crisis.name}}
-
-
- `,
-})
-export class CrisisListComponent implements OnInit {
- crises: Crisis[];
-
- private selectedId: number;
-
- constructor(
- private service: CrisisService,
- private router: Router,
- routeParams: RouteParams) {
- this.selectedId = +routeParams.get('id');
- }
-
- isSelected(crisis: Crisis) { return crisis.id === this.selectedId; }
-
- ngOnInit() {
- this.service.getCrises().then(crises => this.crises = crises);
- }
-
- onSelect(crisis: Crisis) {
- this.router.navigate( ['CrisisDetail', { id: crisis.id }] );
- }
-}
diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis.service.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis.service.ts
deleted file mode 100644
index a847a15217..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis.service.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-// #docplaster
-// #docregion
-import { Injectable } from '@angular/core';
-
-export class Crisis {
- constructor(public id: number, public name: string) { }
-}
-
-let crises = [
- new Crisis(1, 'Dragon Burning Cities'),
- new Crisis(2, 'Sky Rains Great White Sharks'),
- new Crisis(3, 'Giant Asteroid Heading For Earth'),
- new Crisis(4, 'Procrastinators Meeting Delayed Again'),
-];
-
-let crisesPromise = Promise.resolve(crises);
-
-@Injectable()
-export class CrisisService {
- getCrises() { return crisesPromise; }
-
- getCrisis(id: number | string) {
- return crisesPromise
- .then(crises => crises.find(c => c.id === +id));
- }
-
-// #enddocregion
-
- static nextCrisisId = 100;
-
- addCrisis(name: string) {
- name = name.trim();
- if (name) {
- let crisis = new Crisis(CrisisService.nextCrisisId++, name);
- crisesPromise.then(crises => crises.push(crisis));
- }
- }
-// #docregion
-}
-// #enddocregion
diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-list.component.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-list.component.ts
deleted file mode 100644
index 6caa3653b5..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/crisis-list.component.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// Initial empty version
-// #docregion
-import { Component } from '@angular/core';
-
-@Component({
- template: `
- CRISIS CENTER
- Get your crisis here
`
-})
-export class CrisisListComponent { }
diff --git a/public/docs/_examples/router-deprecated/ts/app/dialog.service.ts b/public/docs/_examples/router-deprecated/ts/app/dialog.service.ts
deleted file mode 100644
index 71a342cbe8..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/dialog.service.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// #docregion
-import { Injectable } from '@angular/core';
-/**
- * Async modal dialog service
- * DialogService makes this app easier to test by faking this service.
- * TODO: better modal implementation that doesn't use window.confirm
- */
-@Injectable()
-export class DialogService {
- /**
- * Ask user to confirm an action. `message` explains the action and choices.
- * Returns promise resolving to `true`=confirm or `false`=cancel
- */
- confirm(message?: string) {
- return new Promise((resolve, reject) =>
- resolve(window.confirm(message || 'Is it OK?')));
- };
-}
diff --git a/public/docs/_examples/router-deprecated/ts/app/hero-list.component.ts b/public/docs/_examples/router-deprecated/ts/app/hero-list.component.ts
deleted file mode 100644
index 5dbbe17d8e..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/hero-list.component.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/// Initial empty version
-// #docregion
-import { Component } from '@angular/core';
-
-@Component({
- template: `
- HEROES
- Get your heroes here
`
-})
-export class HeroListComponent { }
diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.1.ts
deleted file mode 100644
index ebfa0bf21d..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.1.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-// #docregion
-import { Component, OnInit } from '@angular/core';
-import { RouteParams, Router } from '@angular/router-deprecated';
-
-import { Hero, HeroService } from './hero.service';
-
-@Component({
- template: `
- HEROES
-
-
"{{hero.name}}"
-
- Id: {{hero.id}}
-
- Name:
-
-
-
- Back
-
-
- `,
-})
-export class HeroDetailComponent implements OnInit {
- hero: Hero;
-
- // #docregion ctor
- constructor(
- private router: Router,
- private routeParams: RouteParams,
- private service: HeroService) {}
- // #enddocregion ctor
-
- // #docregion ngOnInit
- ngOnInit() {
- let id = this.routeParams.get('id');
- this.service.getHero(id).then(hero => this.hero = hero);
- }
- // #enddocregion ngOnInit
-
- // #docregion gotoHeroes
- gotoHeroes() {
- // Like Heroes
- this.router.navigate(['Heroes']);
- }
- // #enddocregion gotoHeroes
-}
diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.ts
deleted file mode 100644
index 10e73fd27b..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// #docregion
-import { Component, OnInit } from '@angular/core';
-import { RouteParams, Router } from '@angular/router-deprecated';
-
-import { Hero, HeroService } from './hero.service';
-
-@Component({
- template: `
- HEROES
-
-
"{{hero.name}}"
-
- Id: {{hero.id}}
-
- Name:
-
-
-
- Back
-
-
- `,
-})
-export class HeroDetailComponent implements OnInit {
- hero: Hero;
-
- // #docregion ctor
- constructor(
- private router: Router,
- private routeParams: RouteParams,
- private service: HeroService) {}
- // #enddocregion ctor
-
- // #docregion ngOnInit
- ngOnInit() {
- let id = this.routeParams.get('id');
- this.service.getHero(id).then(hero => this.hero = hero);
- }
- // #enddocregion ngOnInit
-
- // #docregion gotoHeroes
- gotoHeroes() {
- let heroId = this.hero ? this.hero.id : null;
- // Pass along the hero id if available
- // so that the HeroList component can select that hero.
- // Add a totally useless `foo` parameter for kicks.
- // #docregion gotoHeroes-navigate
- this.router.navigate(['Heroes', {id: heroId, foo: 'foo'} ]);
- // #enddocregion gotoHeroes-navigate
- }
- // #enddocregion gotoHeroes
-}
diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.1.ts
deleted file mode 100644
index cb1d20327c..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.1.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-// #docplaster
-
-// #docregion
-// TODO SOMEDAY: Feature Componetized like HeroCenter
-import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router-deprecated';
-
-import { Hero, HeroService } from './hero.service';
-
-@Component({
- // #docregion template
- template: `
- HEROES
-
-
- {{hero.id}} {{hero.name}}
-
-
- `
- // #enddocregion template
-})
-export class HeroListComponent implements OnInit {
- heroes: Hero[];
-
- // #docregion ctor
- constructor(
- private router: Router,
- private service: HeroService) { }
- // #enddocregion ctor
-
- ngOnInit() {
- this.service.getHeroes().then(heroes => this.heroes = heroes);
- }
-
- // #docregion select
- onSelect(hero: Hero) {
- // #docregion nav-to-detail
- this.router.navigate( ['HeroDetail', { id: hero.id }] );
- // #enddocregion nav-to-detail
- }
- // #enddocregion select
-}
-// #enddocregion
-
-/* A link parameters array
-// #docregion link-parameters-array
-['HeroDetail', { id: hero.id }] // {id: 15}
-// #enddocregion link-parameters-array
-*/
diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.ts
deleted file mode 100644
index 1ca787592f..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-// #docplaster
-
-// TODO SOMEDAY: Feature Componetized like CrisisCenter
-// #docregion
-import { Component, OnInit } from '@angular/core';
-// #docregion import-route-params
-import { RouteParams, Router } from '@angular/router-deprecated';
-// #enddocregion import-route-params
-
-import { Hero, HeroService } from './hero.service';
-
-@Component({
- // #docregion template
- template: `
- HEROES
-
-
- {{hero.id}} {{hero.name}}
-
-
- `
- // #enddocregion template
-})
-export class HeroListComponent implements OnInit {
- heroes: Hero[];
-
- // #docregion ctor
- private selectedId: number;
-
- constructor(
- private service: HeroService,
- private router: Router,
- routeParams: RouteParams) {
- this.selectedId = +routeParams.get('id');
- }
- // #enddocregion ctor
-
- // #docregion isSelected
- isSelected(hero: Hero) { return hero.id === this.selectedId; }
- // #enddocregion isSelected
-
- // #docregion select
- onSelect(hero: Hero) {
- this.router.navigate( ['HeroDetail', { id: hero.id }] );
- }
- // #enddocregion select
-
- ngOnInit() {
-
-
- this.service.getHeroes().then(heroes => this.heroes = heroes);
- }
-}
-// #enddocregion
diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero.service.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero.service.ts
deleted file mode 100644
index c819bd2632..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero.service.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-// #docregion
-import { Injectable } from '@angular/core';
-
-export class Hero {
- constructor(public id: number, public name: string) { }
-}
-
-let HEROES = [
- new Hero(11, 'Mr. Nice'),
- new Hero(12, 'Narco'),
- new Hero(13, 'Bombasto'),
- new Hero(14, 'Celeritas'),
- new Hero(15, 'Magneta'),
- new Hero(16, 'RubberMan')
-];
-
-let heroesPromise = Promise.resolve(HEROES);
-
-@Injectable()
-export class HeroService {
- getHeroes() { return heroesPromise; }
-
- getHero(id: number | string) {
- return heroesPromise
- .then(heroes => heroes.find(h => h.id === +id));
- }
-}
diff --git a/public/docs/_examples/router-deprecated/ts/app/main.1.ts b/public/docs/_examples/router-deprecated/ts/app/main.1.ts
deleted file mode 100644
index ce110455d4..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/main.1.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/* First version */
-// #docplaster
-
-// #docregion all
-import { bootstrap } from '@angular/platform-browser-dynamic';
-import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
-
-import { AppComponent } from './app.component';
-
-// #enddocregion all
-
-/* Can't use AppComponent ... but display as if we can
-// #docregion all
-bootstrap(AppComponent, [
-// #enddocregion all
-*/
-
-// Actually use the v.1 component
-import { AppComponent as ac } from './app.component.1';
-bootstrap(ac, [
-// #docregion all
- ROUTER_PROVIDERS
-]);
-// #enddocregion all
diff --git a/public/docs/_examples/router-deprecated/ts/app/main.2.ts b/public/docs/_examples/router-deprecated/ts/app/main.2.ts
deleted file mode 100644
index 74862cdd0a..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/main.2.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Second version */
-// For Milestone #2
-// Also includes digression on HashPathStrategy (not used in the final app)
-// #docplaster
-
-// #docregion
-import { bootstrap } from '@angular/platform-browser-dynamic';
-import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
-
-// Add these symbols to override the `LocationStrategy`
-import { LocationStrategy,
- HashLocationStrategy } from '@angular/common';
-
-import { AppComponent } from './app.component';
-// #enddocregion
-/* Can't use AppComponent ... but display as if we can
-// #docregion
-
-bootstrap(AppComponent, [
-// #enddocregion
-*/
-
-// Actually use the v.2 component
-import { AppComponent as ac } from './app.component.2';
-
-bootstrap(ac, [
-// #docregion
- ROUTER_PROVIDERS,
- { provide: LocationStrategy, useClass: HashLocationStrategy } // .../#/crisis-center/
-]);
-// #enddocregion
diff --git a/public/docs/_examples/router-deprecated/ts/app/main.3.ts b/public/docs/_examples/router-deprecated/ts/app/main.3.ts
deleted file mode 100644
index 9e9eb04721..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/main.3.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// #docregion
-import { bootstrap } from '@angular/platform-browser-dynamic';
-import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
-
-import { AppComponent } from './app.component.3';
-
-bootstrap(AppComponent, [ROUTER_PROVIDERS]);
diff --git a/public/docs/_examples/router-deprecated/ts/app/main.ts b/public/docs/_examples/router-deprecated/ts/app/main.ts
deleted file mode 100644
index 08bbbef6e8..0000000000
--- a/public/docs/_examples/router-deprecated/ts/app/main.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// #docregion
-import { bootstrap } from '@angular/platform-browser-dynamic';
-import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
-
-import { AppComponent } from './app.component';
-
-bootstrap(AppComponent, [ROUTER_PROVIDERS]);
diff --git a/public/docs/_examples/router-deprecated/ts/example-config.json b/public/docs/_examples/router-deprecated/ts/example-config.json
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/public/docs/_examples/router-deprecated/ts/index.1.html b/public/docs/_examples/router-deprecated/ts/index.1.html
deleted file mode 100644
index 53a6d4832f..0000000000
--- a/public/docs/_examples/router-deprecated/ts/index.1.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
- Router (Deprecated) Sample v.1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Milestone 1
- loading...
-
-
-
-
diff --git a/public/docs/_examples/router-deprecated/ts/index.2.html b/public/docs/_examples/router-deprecated/ts/index.2.html
deleted file mode 100644
index d71bd929cb..0000000000
--- a/public/docs/_examples/router-deprecated/ts/index.2.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
- Router (Deprecated) Sample v.2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Milestone 2
- loading...
-
-
-
-
diff --git a/public/docs/_examples/router-deprecated/ts/index.3.html b/public/docs/_examples/router-deprecated/ts/index.3.html
deleted file mode 100644
index abbb771beb..0000000000
--- a/public/docs/_examples/router-deprecated/ts/index.3.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
- Router (Deprecated) Sample v.3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Milestone 3
- loading...
-
-
-
-
diff --git a/public/docs/_examples/router-deprecated/ts/plnkr.json b/public/docs/_examples/router-deprecated/ts/plnkr.json
deleted file mode 100644
index 91eff6fdb9..0000000000
--- a/public/docs/_examples/router-deprecated/ts/plnkr.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "description": "Router (Deprecated Beta)",
- "files":[
- "!**/*.d.ts",
- "!**/*.js",
- "!**/*.[1,2,3].*",
- "!app/crisis-list.component.ts",
- "!app/hero-list.component.ts",
- "!app/crisis-center/add-crisis.component.ts"
- ],
- "tags": ["router", "deprecated"]
-}
diff --git a/public/docs/_examples/router/e2e-spec.ts b/public/docs/_examples/router/e2e-spec.ts
index bf672c3f01..a82ebd08a5 100644
--- a/public/docs/_examples/router/e2e-spec.ts
+++ b/public/docs/_examples/router/e2e-spec.ts
@@ -16,8 +16,8 @@ describe('Router', function () {
crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('my-app > ng-component > ng-component li')),
- crisisDetail: element(by.css('my-app > ng-component > ng-component > div')),
- crisisDetailTitle: element(by.css('my-app > ng-component > ng-component > div > h3')),
+ crisisDetail: element(by.css('my-app > ng-component > ng-component > ng-component > div')),
+ crisisDetailTitle: element(by.css('my-app > ng-component > ng-component > ng-component > div > h3')),
heroesHref: hrefEles.get(1),
heroesList: element.all(by.css('my-app > ng-component li')),
@@ -34,7 +34,7 @@ describe('Router', function () {
expect(page.hrefs.count()).toEqual(4, 'should be 4 dashboard choices');
expect(page.crisisHref.getText()).toEqual('Crisis Center');
expect(page.heroesHref.getText()).toEqual('Heroes');
- expect(page.adminHref.getText()).toEqual('Crisis Admin');
+ expect(page.adminHref.getText()).toEqual('Admin');
expect(page.loginHref.getText()).toEqual('Login');
});
@@ -118,7 +118,6 @@ describe('Router', function () {
crisisText = text.substr(text.indexOf(' ')).trim();
return crisisEle.click();
}).then(function () {
- expect(page.crisisList.count()).toBe(0, 'should no longer see crisis center entries');
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.crisisDetailTitle.getText()).toContain(crisisText);
let inputEle = page.crisisDetail.element(by.css('input'));
diff --git a/public/docs/_examples/router/ts/app/admin/admin-dashboard.component.1.ts b/public/docs/_examples/router/ts/app/admin/admin-dashboard.component.1.ts
new file mode 100644
index 0000000000..ffa3e3cb8f
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/admin-dashboard.component.1.ts
@@ -0,0 +1,9 @@
+// #docregion
+import { Component } from '@angular/core';
+
+@Component({
+ template: `
+ Dashboard
+ `
+})
+export class AdminDashboardComponent { }
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-admin.component.ts b/public/docs/_examples/router/ts/app/admin/admin-dashboard.component.ts
old mode 100755
new mode 100644
similarity index 86%
rename from public/docs/_examples/router/ts/app/crisis-center/crisis-admin.component.ts
rename to public/docs/_examples/router/ts/app/admin/admin-dashboard.component.ts
index 38fe14a38e..8c8e481643
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-admin.component.ts
+++ b/public/docs/_examples/router/ts/app/admin/admin-dashboard.component.ts
@@ -6,15 +6,14 @@ import 'rxjs/add/operator/map';
@Component({
template: `
- CRISIS ADMINISTRATION
- Manage your crises here
+ Dashboard
Session ID: {{ sessionId | async }}
Token: {{ token | async }}
`
})
-export class CrisisAdminComponent implements OnInit {
+export class AdminDashboardComponent implements OnInit {
sessionId: Observable;
token: Observable;
diff --git a/public/docs/_examples/router/ts/app/admin/admin.component.ts b/public/docs/_examples/router/ts/app/admin/admin.component.ts
new file mode 100755
index 0000000000..30abfa4524
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/admin.component.ts
@@ -0,0 +1,17 @@
+// #docregion
+import { Component } from '@angular/core';
+
+@Component({
+ template: `
+ ADMIN
+
+ Dashboard
+ Manage Crises
+ Manage Heroes
+
+
+ `
+})
+export class AdminComponent {
+}
diff --git a/public/docs/_examples/router/ts/app/admin/admin.module.ts b/public/docs/_examples/router/ts/app/admin/admin.module.ts
new file mode 100644
index 0000000000..dce2ce30e2
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/admin.module.ts
@@ -0,0 +1,28 @@
+// #docplaster
+// #docregion
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { AdminComponent } from './admin.component';
+import { AdminDashboardComponent } from './admin-dashboard.component';
+import { ManageCrisesComponent } from './manage-crises.component';
+import { ManageHeroesComponent } from './manage-heroes.component';
+
+import { adminRouting } from './admin.routing';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ adminRouting
+ ],
+ declarations: [
+ AdminComponent,
+ AdminDashboardComponent,
+ ManageCrisesComponent,
+ ManageHeroesComponent
+ ]
+})
+// #docregion admin-module-export
+export class AdminModule {}
+// #enddocregion admin-module-export
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/admin/admin.routing.1.ts b/public/docs/_examples/router/ts/app/admin/admin.routing.1.ts
new file mode 100644
index 0000000000..a620f3ba51
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/admin.routing.1.ts
@@ -0,0 +1,31 @@
+// #docplaster
+// #docregion
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AdminComponent } from './admin.component';
+import { AdminDashboardComponent } from './admin-dashboard.component';
+import { ManageCrisesComponent } from './manage-crises.component';
+import { ManageHeroesComponent } from './manage-heroes.component';
+
+// #docregion admin-routes
+const adminRoutes: Routes = [
+ {
+ path: 'admin',
+ component: AdminComponent,
+ children: [
+ {
+ path: '',
+ children: [
+ { path: 'crises', component: ManageCrisesComponent },
+ { path: 'heroes', component: ManageHeroesComponent },
+ { path: '', component: AdminDashboardComponent }
+ ]
+ }
+ ]
+ }
+];
+
+export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
+// #enddocregion admin-routes
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/admin/admin.routing.2.ts b/public/docs/_examples/router/ts/app/admin/admin.routing.2.ts
new file mode 100644
index 0000000000..9fa3f10e4a
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/admin.routing.2.ts
@@ -0,0 +1,37 @@
+// #docplaster
+// #docregion
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AdminComponent } from './admin.component';
+import { AdminDashboardComponent } from './admin-dashboard.component';
+import { ManageCrisesComponent } from './manage-crises.component';
+import { ManageHeroesComponent } from './manage-heroes.component';
+
+// #docregion admin-route, can-activate-child
+import { AuthGuard } from '../auth-guard.service';
+
+const adminRoutes: Routes = [
+ {
+ path: 'admin',
+ component: AdminComponent,
+ canActivate: [AuthGuard],
+ children: [
+ {
+ path: '',
+ children: [
+ { path: 'crises', component: ManageCrisesComponent },
+ { path: 'heroes', component: ManageHeroesComponent },
+ { path: '', component: AdminDashboardComponent }
+ ],
+ // #enddocregion admin-route
+ // #docregion can-activate-child
+ canActivateChild: [AuthGuard]
+ // #docregion admin-route
+ }
+ ]
+ }
+];
+
+export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/admin/admin.routing.3.ts b/public/docs/_examples/router/ts/app/admin/admin.routing.3.ts
new file mode 100644
index 0000000000..3b4051a819
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/admin.routing.3.ts
@@ -0,0 +1,35 @@
+// #docplaster
+// #docregion
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AdminComponent } from './admin.component';
+import { AdminDashboardComponent } from './admin-dashboard.component';
+import { ManageCrisesComponent } from './manage-crises.component';
+import { ManageHeroesComponent } from './manage-heroes.component';
+
+// #docregion admin-route
+import { AuthGuard } from '../auth-guard.service';
+
+// #docregion can-activate-child
+const adminRoutes: Routes = [
+ {
+ path: 'admin',
+ component: AdminComponent,
+ canActivate: [AuthGuard],
+ children: [
+ {
+ path: '',
+ canActivateChild: [AuthGuard],
+ children: [
+ { path: 'crises', component: ManageCrisesComponent },
+ { path: 'heroes', component: ManageHeroesComponent },
+ { path: '', component: AdminDashboardComponent }
+ ]
+ }
+ ]
+ }
+];
+
+export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/admin/admin.routing.ts b/public/docs/_examples/router/ts/app/admin/admin.routing.ts
new file mode 100644
index 0000000000..bc5d13554c
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/admin.routing.ts
@@ -0,0 +1,34 @@
+// #docplaster
+// #docregion
+import { ModuleWithProviders } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AdminComponent } from './admin.component';
+import { AdminDashboardComponent } from './admin-dashboard.component';
+import { ManageCrisesComponent } from './manage-crises.component';
+import { ManageHeroesComponent } from './manage-heroes.component';
+
+// #docregion admin-route
+import { AuthGuard } from '../auth-guard.service';
+
+const adminRoutes: Routes = [
+ {
+ path: '',
+ component: AdminComponent,
+ canActivate: [AuthGuard],
+ children: [
+ {
+ path: '',
+ canActivateChild: [AuthGuard],
+ children: [
+ { path: 'crises', component: ManageCrisesComponent },
+ { path: 'heroes', component: ManageHeroesComponent },
+ { path: '', component: AdminDashboardComponent }
+ ]
+ }
+ ]
+ }
+];
+
+export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-admin.component.1.ts b/public/docs/_examples/router/ts/app/admin/manage-crises.component.ts
similarity index 63%
rename from public/docs/_examples/router/ts/app/crisis-center/crisis-admin.component.1.ts
rename to public/docs/_examples/router/ts/app/admin/manage-crises.component.ts
index a8dacc8549..d3176563eb 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-admin.component.1.ts
+++ b/public/docs/_examples/router/ts/app/admin/manage-crises.component.ts
@@ -3,8 +3,7 @@ import { Component } from '@angular/core';
@Component({
template: `
- CRISIS ADMINISTRATION
Manage your crises here
`
})
-export class CrisisAdminComponent { }
+export class ManageCrisesComponent { }
diff --git a/public/docs/_examples/router/ts/app/admin/manage-heroes.component.ts b/public/docs/_examples/router/ts/app/admin/manage-heroes.component.ts
new file mode 100644
index 0000000000..7f3a39893d
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/admin/manage-heroes.component.ts
@@ -0,0 +1,9 @@
+// #docregion
+import { Component } from '@angular/core';
+
+@Component({
+ template: `
+ Manage your heroes here
+ `
+})
+export class ManageHeroesComponent { }
diff --git a/public/docs/_examples/router/ts/app/app.component.1.ts b/public/docs/_examples/router/ts/app/app.component.1.ts
index 1b0aba0044..21e9aa417d 100644
--- a/public/docs/_examples/router/ts/app/app.component.1.ts
+++ b/public/docs/_examples/router/ts/app/app.component.1.ts
@@ -6,7 +6,7 @@ import { Component } from '@angular/core';
selector: 'my-app',
// #docregion template
template: `
- Component Router
+ Angular Router
Crisis Center
Heroes
diff --git a/public/docs/_examples/router/ts/app/app.component.2.ts b/public/docs/_examples/router/ts/app/app.component.2.ts
index 7593aa1608..fa3ddf01b9 100644
--- a/public/docs/_examples/router/ts/app/app.component.2.ts
+++ b/public/docs/_examples/router/ts/app/app.component.2.ts
@@ -7,7 +7,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
- Component Router
+ Angular Router
Crisis Center
Heroes
diff --git a/public/docs/_examples/router/ts/app/app.component.3.ts b/public/docs/_examples/router/ts/app/app.component.3.ts
index 1150a01814..ad4dbe33d6 100644
--- a/public/docs/_examples/router/ts/app/app.component.3.ts
+++ b/public/docs/_examples/router/ts/app/app.component.3.ts
@@ -1,7 +1,7 @@
/* tslint:disable:no-unused-variable */
// #docplaster
import { Component } from '@angular/core';
-import { Router } from '@angular/router';
+import { Router } from '@angular/router';
@Component({
selector: 'my-app',
@@ -36,7 +36,7 @@ import { Router } from '@angular/router';
*/
// #docregion template
template: `
- Component Router
+ Angular Router
Crisis Center
Dragon Crisis
diff --git a/public/docs/_examples/router/ts/app/app.component.4.ts b/public/docs/_examples/router/ts/app/app.component.4.ts
index e609850a42..9769d4f2da 100644
--- a/public/docs/_examples/router/ts/app/app.component.4.ts
+++ b/public/docs/_examples/router/ts/app/app.component.4.ts
@@ -1,16 +1,15 @@
// #docregion
-import { Component } from '@angular/core';
+import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
- Component Router
+ Angular Router
- Crisis Center
+ Crisis Center
Heroes
- Crisis Admin
+ Admin
`
diff --git a/public/docs/_examples/router/ts/app/app.component.ts b/public/docs/_examples/router/ts/app/app.component.ts
index 2dcb0a062b..37f69472a0 100644
--- a/public/docs/_examples/router/ts/app/app.component.ts
+++ b/public/docs/_examples/router/ts/app/app.component.ts
@@ -1,17 +1,16 @@
// #docplaster
// #docregion
-import { Component } from '@angular/core';
+import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
- Component Router
+ Angular Router
- Crisis Center
+ Crisis Center
Heroes
- Crisis Admin
+ Admin
Login
diff --git a/public/docs/_examples/router/ts/app/app.module.1.ts b/public/docs/_examples/router/ts/app/app.module.1.ts
index c6d5648bbf..ea1edc36af 100644
--- a/public/docs/_examples/router/ts/app/app.module.1.ts
+++ b/public/docs/_examples/router/ts/app/app.module.1.ts
@@ -4,11 +4,10 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-
// #docregion router-basics
-import { AppComponent } from './app.component';
+import { AppComponent } from './app.component';
import { routing,
- appRoutingProviders } from './app.routing';
+ appRoutingProviders } from './app.routing';
import { HeroListComponent } from './hero-list.component';
import { CrisisListComponent } from './crisis-list.component';
diff --git a/public/docs/_examples/router/ts/app/app.module.2.ts b/public/docs/_examples/router/ts/app/app.module.2.ts
index 35913ae6a2..3e1d42896c 100644
--- a/public/docs/_examples/router/ts/app/app.module.2.ts
+++ b/public/docs/_examples/router/ts/app/app.module.2.ts
@@ -1,14 +1,14 @@
// #docplaster
// #docregion
+// #docregion hero-import
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { AppComponent } from './app.component';
+import { AppComponent } from './app.component';
import { routing,
- appRoutingProviders } from './app.routing';
+ appRoutingProviders } from './app.routing';
-// #docregion hero-import
import { HeroesModule } from './heroes/heroes.module';
import { CrisisListComponent } from './crisis-list.component';
diff --git a/public/docs/_examples/router/ts/app/app.module.3.ts b/public/docs/_examples/router/ts/app/app.module.3.ts
index d1969a860a..6ddd73ac3e 100644
--- a/public/docs/_examples/router/ts/app/app.module.3.ts
+++ b/public/docs/_examples/router/ts/app/app.module.3.ts
@@ -1,24 +1,34 @@
+// #docplaster
// #docregion
+// #docregion crisis-center-module, admin-module
import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
+import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
-import { AppComponent } from './app.component';
+import { AppComponent } from './app.component';
import { routing,
- appRoutingProviders } from './app.routing';
+ appRoutingProviders } from './app.routing';
import { HeroesModule } from './heroes/heroes.module';
+// #docregion crisis-center-module
import { CrisisCenterModule } from './crisis-center/crisis-center.module';
+// #enddocregion crisis-center-module
+// #docregion admin-module
+import { AdminModule } from './admin/admin.module';
+// #docregion crisis-center-module
-import { DialogService } from './dialog.service';
+import { DialogService } from './dialog.service';
@NgModule({
imports: [
- BrowserModule,
+ CommonModule,
FormsModule,
routing,
HeroesModule,
- CrisisCenterModule
+ CrisisCenterModule,
+// #enddocregion crisis-center-module
+ AdminModule
+// #docregion crisis-center-module
],
declarations: [
AppComponent
@@ -31,3 +41,4 @@ import { DialogService } from './dialog.service';
})
export class AppModule {
}
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/app.module.4.ts b/public/docs/_examples/router/ts/app/app.module.4.ts
index 96a8eb61d9..840ea422db 100644
--- a/public/docs/_examples/router/ts/app/app.module.4.ts
+++ b/public/docs/_examples/router/ts/app/app.module.4.ts
@@ -2,25 +2,30 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { Routes, RouterModule } from '@angular/router';
-import { AppComponent } from './app.component';
+import { AppComponent } from './app.component';
+import { routing,
+ appRoutingProviders } from './app.routing';
-const routes: Routes = [
+import { HeroesModule } from './heroes/heroes.module';
+import { CrisisCenterModule } from './crisis-center/crisis-center.module';
-];
+import { DialogService } from './dialog.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
- RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/
+ routing,
+ HeroesModule,
+ CrisisCenterModule
],
declarations: [
AppComponent
],
providers: [
-
+ appRoutingProviders,
+ DialogService
],
bootstrap: [ AppComponent ]
})
diff --git a/public/docs/_examples/router/ts/app/app.module.5.ts b/public/docs/_examples/router/ts/app/app.module.5.ts
new file mode 100644
index 0000000000..b1ba4bd231
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/app.module.5.ts
@@ -0,0 +1,28 @@
+// #docregion
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { FormsModule } from '@angular/forms';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AppComponent } from './app.component';
+
+const routes: Routes = [
+
+];
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ FormsModule,
+ RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/
+ ],
+ declarations: [
+ AppComponent
+ ],
+ providers: [
+
+ ],
+ bootstrap: [ AppComponent ]
+})
+export class AppModule {
+}
diff --git a/public/docs/_examples/router/ts/app/app.module.ts b/public/docs/_examples/router/ts/app/app.module.ts
index f273052d83..87c031e2bb 100644
--- a/public/docs/_examples/router/ts/app/app.module.ts
+++ b/public/docs/_examples/router/ts/app/app.module.ts
@@ -3,22 +3,24 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { AppComponent } from './app.component';
+import { AppComponent } from './app.component';
import { routing,
- appRoutingProviders } from './app.routing';
+ appRoutingProviders } from './app.routing';
-import { HeroesModule } from './heroes/heroes.module';
+import { HeroesModule } from './heroes/heroes.module';
+import { CrisisCenterModule } from './crisis-center/crisis-center.module';
-import { LoginComponent } from './login.component';
+import { LoginComponent } from './login.component';
-import { DialogService } from './dialog.service';
+import { DialogService } from './dialog.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
routing,
- HeroesModule
+ HeroesModule,
+ CrisisCenterModule
],
declarations: [
AppComponent,
diff --git a/public/docs/_examples/router/ts/app/app.routing.1.ts b/public/docs/_examples/router/ts/app/app.routing.1.ts
index ccdff404a4..736f49b4fb 100644
--- a/public/docs/_examples/router/ts/app/app.routing.1.ts
+++ b/public/docs/_examples/router/ts/app/app.routing.1.ts
@@ -1,6 +1,7 @@
// #docplaster
// #docregion
// #docregion route-config
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
// #enddocregion route-config
@@ -11,12 +12,16 @@ import { HeroListComponent } from './hero-list.component';
import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { HeroDetailComponent } from './heroes/hero-detail.component';
import { PageNotFoundComponent } from './not-found.component';
+import { PageNotFoundComponent as HomeComponent } from './not-found.component';
// #enddocregion base-routes
// #docregion
// #docregion route-config
const appRoutes: Routes = [
// #docregion route-defs
+ // #docregion hero-detail-route
+ { path: 'hero/:id', component: HeroDetailComponent },
+ // #enddocregion hero-detail-route
{ path: 'crisis-center', component: CrisisCenterComponent },
{
path: 'heroes',
@@ -25,10 +30,8 @@ const appRoutes: Routes = [
title: 'Heroes List'
}
},
+ { path: '', component: HomeComponent },
// #enddocregion route-defs
- // #docregion hero-detail-route
- { path: 'hero/:id', component: HeroDetailComponent },
- // #enddocregion hero-detail-route
{ path: '**', component: PageNotFoundComponent }
];
@@ -36,6 +39,6 @@ export const appRoutingProviders: any[] = [
];
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
// #enddocregion route-config
// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/app.routing.2.ts b/public/docs/_examples/router/ts/app/app.routing.2.ts
index 81c04c86da..1115c9084e 100644
--- a/public/docs/_examples/router/ts/app/app.routing.2.ts
+++ b/public/docs/_examples/router/ts/app/app.routing.2.ts
@@ -1,5 +1,6 @@
// #docplaster
// #docregion
+import { ModuleWithProviders } from '@angular/core';
// #docregion route-config
import { Routes, RouterModule } from '@angular/router';
@@ -17,5 +18,5 @@ export const appRoutingProviders: any[] = [
];
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
// #enddocregion route-config
diff --git a/public/docs/_examples/router/ts/app/app.routing.3.ts b/public/docs/_examples/router/ts/app/app.routing.3.ts
index 2eab693570..247ec7f2dd 100644
--- a/public/docs/_examples/router/ts/app/app.routing.3.ts
+++ b/public/docs/_examples/router/ts/app/app.routing.3.ts
@@ -1,15 +1,16 @@
// #docplaster
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { CrisisListComponent } from './crisis-center/crisis-list.component';
+import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
const appRoutes: Routes = [
- { path: 'crisis-center', component: CrisisListComponent }
+ { path: 'crisis-center', component: CrisisCenterComponent }
];
export const appRoutingProviders: any[] = [
];
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/router/ts/app/app.routing.4.ts b/public/docs/_examples/router/ts/app/app.routing.4.ts
index 59153e9e53..ff04dd8bfd 100644
--- a/public/docs/_examples/router/ts/app/app.routing.4.ts
+++ b/public/docs/_examples/router/ts/app/app.routing.4.ts
@@ -1,4 +1,5 @@
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const appRoutes: Routes = [
@@ -9,4 +10,4 @@ export const appRoutingProviders: any[] = [
];
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/router/ts/app/app.routing.5.ts b/public/docs/_examples/router/ts/app/app.routing.5.ts
index 8334e865a5..ce153c7b1f 100644
--- a/public/docs/_examples/router/ts/app/app.routing.5.ts
+++ b/public/docs/_examples/router/ts/app/app.routing.5.ts
@@ -1,4 +1,5 @@
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { loginRoutes,
@@ -12,4 +13,4 @@ export const appRoutingProviders: any[] = [
authProviders
];
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/router/ts/app/app.routing.6.ts b/public/docs/_examples/router/ts/app/app.routing.6.ts
index 33465b837b..8dc92f9dc4 100644
--- a/public/docs/_examples/router/ts/app/app.routing.6.ts
+++ b/public/docs/_examples/router/ts/app/app.routing.6.ts
@@ -1,4 +1,5 @@
// #docregion
+import { ModuleWithProviders } from '@angular/core';
// #docregion import-router
import { Routes, RouterModule } from '@angular/router';
// #enddocregion import-router
@@ -8,39 +9,13 @@ import { loginRoutes,
import { CanDeactivateGuard } from './can-deactivate-guard.service';
-// #docregion lazy-load-crisis-center
-const crisisCenterRoutes: Routes = [
- {
- path: '',
- redirectTo: '/crisis-center',
- pathMatch: 'full'
- },
- {
- path: 'crisis-center',
- loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule'
- }
-];
-
const appRoutes: Routes = [
- ...loginRoutes,
- ...crisisCenterRoutes
+ ...loginRoutes
];
-// #enddocregion lazy-load-crisis-center
export const appRoutingProviders: any[] = [
authProviders,
CanDeactivateGuard
];
-export const routing = RouterModule.forRoot(appRoutes);
-// #enddocregion
-
-/* A link parameters array
-// #docregion heroes-redirect
-{
- path: '',
- redirectTo: '/heroes',
- pathMatch: 'full'
-},
-// #enddocregion heroes-redirect
-*/
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/router/ts/app/app.routing.ts b/public/docs/_examples/router/ts/app/app.routing.ts
index 1e320cffea..cd00b9bf0c 100644
--- a/public/docs/_examples/router/ts/app/app.routing.ts
+++ b/public/docs/_examples/router/ts/app/app.routing.ts
@@ -1,35 +1,40 @@
+// #docplaster
// #docregion
+import { ModuleWithProviders } from '@angular/core';
// #docregion import-router
-import { Routes, RouterModule } from '@angular/router';
+import { Routes, RouterModule } from '@angular/router';
// #enddocregion import-router
import { loginRoutes,
- authProviders } from './login.routing';
+ authProviders } from './login.routing';
import { CanDeactivateGuard } from './can-deactivate-guard.service';
+// #docregion can-load-guard
+import { AuthGuard } from './auth-guard.service';
+// #enddocregion can-load-guard
-// #docregion lazy-load-crisis-center
-const crisisCenterRoutes: Routes = [
+// #docregion lazy-load-admin, can-load-guard
+
+const adminRoutes: Routes = [
{
- path: '',
- redirectTo: '/heroes',
- pathMatch: 'full'
- },
- {
- path: 'crisis-center',
- loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule'
+ path: 'admin',
+ loadChildren: 'app/admin/admin.module#AdminModule',
+// #enddocregion lazy-load-admin
+ canLoad: [AuthGuard]
+// #docregion lazy-load-admin
}
];
+// #enddocregion can-load-guard
const appRoutes: Routes = [
...loginRoutes,
- ...crisisCenterRoutes
+ ...adminRoutes
];
-// #enddocregion lazy-load-crisis-center
+// #enddocregion lazy-load-admin
export const appRoutingProviders: any[] = [
authProviders,
CanDeactivateGuard
];
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/router/ts/app/auth-guard.service.2.ts b/public/docs/_examples/router/ts/app/auth-guard.service.2.ts
index 9d4f3afb3b..8fd00e151a 100644
--- a/public/docs/_examples/router/ts/app/auth-guard.service.2.ts
+++ b/public/docs/_examples/router/ts/app/auth-guard.service.2.ts
@@ -1,22 +1,37 @@
// #docregion
-import { Injectable } from '@angular/core';
-import { CanActivate, Router,
- ActivatedRouteSnapshot,
- RouterStateSnapshot } from '@angular/router';
-import { AuthService } from './auth.service';
+import { Injectable } from '@angular/core';
+import {
+ CanActivate, Router,
+ ActivatedRouteSnapshot,
+ RouterStateSnapshot
+} from '@angular/router';
+import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
- canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
+ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ let url: string = state.url;
+
+ return this.checkLogin(url);
+ }
+
+ checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) { return true; }
// Store the attempted URL for redirecting
- this.authService.redirectUrl = state.url;
+ this.authService.redirectUrl = url;
- // Navigate to the login page
+ // Navigate to the login page with extras
this.router.navigate(['/login']);
return false;
}
}
+// #enddocregion
+
+/*
+// #docregion can-load-interface
+export class AuthGuard implements CanActivate, CanLoad {
+// #enddocregion can-load-interface
+*/
diff --git a/public/docs/_examples/router/ts/app/auth-guard.service.3.ts b/public/docs/_examples/router/ts/app/auth-guard.service.3.ts
new file mode 100644
index 0000000000..8e417625fe
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/auth-guard.service.3.ts
@@ -0,0 +1,40 @@
+// #docplaster
+// #docregion
+// #docregion can-activate-child
+import { Injectable } from '@angular/core';
+import {
+ CanActivate, Router,
+ ActivatedRouteSnapshot,
+ RouterStateSnapshot,
+ CanActivateChild
+} from '@angular/router';
+import { AuthService } from './auth.service';
+
+@Injectable()
+export class AuthGuard implements CanActivate, CanActivateChild {
+ constructor(private authService: AuthService, private router: Router) {}
+
+ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ let url: string = state.url;
+
+ return this.checkLogin(url);
+ }
+
+ canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ return this.canActivate(route, state);
+ }
+
+// #enddocregion can-activate-child
+ checkLogin(url: string): boolean {
+ if (this.authService.isLoggedIn) { return true; }
+
+ // Store the attempted URL for redirecting
+ this.authService.redirectUrl = url;
+
+ // Navigate to the login page
+ this.router.navigate(['/login']);
+ return false;
+ }
+// #docregion can-activate-child
+}
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/auth-guard.service.4.ts b/public/docs/_examples/router/ts/app/auth-guard.service.4.ts
new file mode 100644
index 0000000000..5d239a8432
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/auth-guard.service.4.ts
@@ -0,0 +1,47 @@
+// #docplaster
+// #docregion
+import { Injectable } from '@angular/core';
+import {
+ CanActivate, Router,
+ ActivatedRouteSnapshot,
+ RouterStateSnapshot,
+ CanActivateChild,
+ NavigationExtras
+} from '@angular/router';
+import { AuthService } from './auth.service';
+
+@Injectable()
+export class AuthGuard implements CanActivate, CanActivateChild {
+ constructor(private authService: AuthService, private router: Router) {}
+
+ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ let url: string = state.url;
+
+ return this.checkLogin(url);
+ }
+
+ canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ return this.canActivate(route, state);
+ }
+
+ checkLogin(url: string): boolean {
+ if (this.authService.isLoggedIn) { return true; }
+
+ // Store the attempted URL for redirecting
+ this.authService.redirectUrl = url;
+
+ // Create a dummy session id
+ let sessionId = 123456789;
+
+ // Set our navigation extras object
+ // that contains our global query params and fragment
+ let navigationExtras: NavigationExtras = {
+ queryParams: { 'session_id': sessionId },
+ fragment: 'anchor'
+ };
+
+ // Navigate to the login page with extras
+ this.router.navigate(['/login'], navigationExtras);
+ return false;
+ }
+}
diff --git a/public/docs/_examples/router/ts/app/auth-guard.service.ts b/public/docs/_examples/router/ts/app/auth-guard.service.ts
index 63aee1deb5..5f93d07533 100755
--- a/public/docs/_examples/router/ts/app/auth-guard.service.ts
+++ b/public/docs/_examples/router/ts/app/auth-guard.service.ts
@@ -1,20 +1,42 @@
-// #docregion
-import { Injectable } from '@angular/core';
-import { CanActivate, Router,
- ActivatedRouteSnapshot,
- RouterStateSnapshot,
- NavigationExtras } from '@angular/router';
-import { AuthService } from './auth.service';
+// #docplaster
+// #docregion, admin-can-load
+import { Injectable } from '@angular/core';
+import {
+ CanActivate, Router,
+ ActivatedRouteSnapshot,
+ RouterStateSnapshot,
+ CanActivateChild,
+ NavigationExtras,
+ CanLoad, Route
+} from '@angular/router';
+import { AuthService } from './auth.service';
@Injectable()
-export class AuthGuard implements CanActivate {
+export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(private authService: AuthService, private router: Router) {}
- canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
+ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ let url: string = state.url;
+
+ return this.checkLogin(url);
+ }
+
+ canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ return this.canActivate(route, state);
+ }
+
+ canLoad(route: Route): boolean {
+ let url = `/${route.path}`;
+
+ return this.checkLogin(url);
+ }
+// #enddocregion admin-can-load
+
+ checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) { return true; }
// Store the attempted URL for redirecting
- this.authService.redirectUrl = state.url;
+ this.authService.redirectUrl = url;
// Create a dummy session id
let sessionId = 123456789;
@@ -30,4 +52,5 @@ export class AuthGuard implements CanActivate {
this.router.navigate(['/login'], navigationExtras);
return false;
}
+// #docregion admin-can-load
}
diff --git a/public/docs/_examples/router/ts/app/auth.service.ts b/public/docs/_examples/router/ts/app/auth.service.ts
index d6f8414af1..f86a80ebfe 100755
--- a/public/docs/_examples/router/ts/app/auth.service.ts
+++ b/public/docs/_examples/router/ts/app/auth.service.ts
@@ -13,11 +13,11 @@ export class AuthService {
// store the URL so we can redirect after logging in
redirectUrl: string;
- login() {
+ login(): Observable {
return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true);
}
- logout() {
+ logout(): void {
this.isLoggedIn = false;
}
}
diff --git a/public/docs/_examples/router/ts/app/can-deactivate-guard.service.1.ts b/public/docs/_examples/router/ts/app/can-deactivate-guard.service.1.ts
index b6e16bfa4c..0b7c8247cf 100644
--- a/public/docs/_examples/router/ts/app/can-deactivate-guard.service.1.ts
+++ b/public/docs/_examples/router/ts/app/can-deactivate-guard.service.1.ts
@@ -3,7 +3,6 @@ import { Injectable } from '@angular/core';
import { CanDeactivate,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
-import { Observable } from 'rxjs/Observable';
import { CrisisDetailComponent } from './crisis-center/crisis-detail.component';
@@ -14,7 +13,7 @@ export class CanDeactivateGuard implements CanDeactivate
component: CrisisDetailComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
- ): Observable | Promise | boolean {
+ ): Promise | boolean {
// Get the Crisis Center ID
console.log(route.params['id']);
diff --git a/public/docs/_examples/router/ts/app/can-deactivate-guard.service.ts b/public/docs/_examples/router/ts/app/can-deactivate-guard.service.ts
index db8ecef5bf..44da69f9c7 100644
--- a/public/docs/_examples/router/ts/app/can-deactivate-guard.service.ts
+++ b/public/docs/_examples/router/ts/app/can-deactivate-guard.service.ts
@@ -4,12 +4,12 @@ import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
export interface CanComponentDeactivate {
- canDeactivate: () => boolean | Observable;
+ canDeactivate: () => Observable | Promise | boolean;
}
@Injectable()
export class CanDeactivateGuard implements CanDeactivate {
- canDeactivate(component: CanComponentDeactivate): Observable | Promise | boolean {
+ canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center-home.component.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center-home.component.ts
new file mode 100644
index 0000000000..a71d485c02
--- /dev/null
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center-home.component.ts
@@ -0,0 +1,13 @@
+// #docregion
+// #docplaster
+import { Component } from '@angular/core';
+
+// #docregion minus-imports
+@Component({
+ template: `
+ Welcome to the Crisis Center
+ `
+})
+export class CrisisCenterHomeComponent { }
+// #enddocregion minus-imports
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.1.ts
index a392ccfe04..ab29a0ba22 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.1.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.1.ts
@@ -1,3 +1,4 @@
+// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
@@ -6,7 +7,8 @@ import { CommonModule } from '@angular/common';
import { CrisisService } from './crisis.service';
import { CrisisCenterComponent } from './crisis-center.component';
-import { CrisisListComponent } from './crisis-list.component';
+import { CrisisListComponent } from './crisis-list.component';
+import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { crisisCenterRouting } from './crisis-center.routing';
@@ -20,13 +22,15 @@ import { crisisCenterRouting } from './crisis-center.routing';
declarations: [
CrisisCenterComponent,
CrisisListComponent,
+ CrisisCenterHomeComponent,
CrisisDetailComponent
],
-// #docregion providers
+
+ // #docregion providers
providers: [
CrisisService
]
-// #enddocregion providers
+ // #enddocregion providers
})
export class CrisisCenterModule {}
// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.ts
index 41b31d6aa5..3a66164607 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.module.ts
@@ -9,10 +9,10 @@ import { CrisisService } from './crisis.service';
import { CrisisDetailResolve } from './crisis-detail-resolve.service';
// #enddocregion crisis-detail-resolve
-import { CrisisCenterComponent } from './crisis-center.component';
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisAdminComponent } from './crisis-admin.component';
+import { CrisisCenterComponent } from './crisis-center.component';
+import { CrisisListComponent } from './crisis-list.component';
+import { CrisisCenterHomeComponent } from './crisis-center-home.component';
+import { CrisisDetailComponent } from './crisis-detail.component';
import { crisisCenterRouting } from './crisis-center.routing';
@@ -25,8 +25,8 @@ import { crisisCenterRouting } from './crisis-center.routing';
declarations: [
CrisisCenterComponent,
CrisisListComponent,
- CrisisDetailComponent,
- CrisisAdminComponent
+ CrisisCenterHomeComponent,
+ CrisisDetailComponent
],
// #docregion crisis-detail-resolve
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.1.ts
index 0d53587aa4..8ef262c189 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.1.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.1.ts
@@ -1,9 +1,12 @@
+// #docplaster
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisCenterComponent } from './crisis-center.component';
+import { CrisisCenterHomeComponent } from './crisis-center-home.component';
+import { CrisisListComponent } from './crisis-list.component';
+import { CrisisCenterComponent } from './crisis-center.component';
+import { CrisisDetailComponent } from './crisis-detail.component';
// #docregion routes
const crisisCenterRoutes: Routes = [
@@ -11,11 +14,24 @@ const crisisCenterRoutes: Routes = [
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
- { path: ':id', component: CrisisDetailComponent },
- { path: '', component: CrisisListComponent }
+ {
+ path: '',
+ component: CrisisListComponent,
+ children: [
+ {
+ path: ':id',
+ component: CrisisDetailComponent
+ },
+ {
+ path: '',
+ component: CrisisCenterHomeComponent
+ }
+ ]
+ }
]
}
];
-export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
-// #enddocregion routes
+export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
+// #docregion routes
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.2.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.2.ts
index a95ab751f3..aab186c878 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.2.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.2.ts
@@ -1,28 +1,65 @@
-// #docregion
+// #docplaster
+// #docregion routes
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisCenterComponent } from './crisis-center.component';
+import { CrisisCenterHomeComponent } from './crisis-center-home.component';
+import { CrisisListComponent } from './crisis-list.component';
+import { CrisisCenterComponent } from './crisis-center.component';
+import { CrisisDetailComponent } from './crisis-detail.component';
+// #enddocregion routes
+// #docregion can-deactivate-guard
+import { CanDeactivateGuard } from '../can-deactivate-guard.service';
+// #enddocregion can-deactivate-guard
+// #docregion crisis-detail-resolve
+import { CrisisDetailResolve } from './crisis-detail-resolve.service';
+
+// #enddocregion crisis-detail-resolve
// #docregion routes
+
const crisisCenterRoutes: Routes = [
- // #docregion redirect
+// #enddocregion routes
+ // #docregion redirect, routes
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
- // #enddocregion redirect
+ // #enddocregion redirect, routes
+ // #docregion routes
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
- { path: ':id', component: CrisisDetailComponent },
- { path: '', component: CrisisListComponent }
+ {
+ path: '',
+ component: CrisisListComponent,
+ children: [
+ {
+ path: ':id',
+ component: CrisisDetailComponent,
+ // #enddocregion routes
+ // #docregion can-deactivate-guard
+ canDeactivate: [CanDeactivateGuard],
+ // #enddocregion can-deactivate-guard
+ // #docregion crisis-detail-resolve
+ resolve: {
+ crisis: CrisisDetailResolve
+ }
+ // #enddocregion crisis-detail-resolve
+ // #docregion routes
+ },
+ {
+ path: '',
+ component: CrisisCenterHomeComponent
+ }
+ ]
+ }
]
}
+ // #docregion routes
];
-export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
-// #enddocregion routes
+export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
+// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.3.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.3.ts
index 8d92662132..e43119d517 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.3.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.3.ts
@@ -1,12 +1,14 @@
// #docplaster
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisCenterComponent } from './crisis-center.component';
-import { CrisisAdminComponent } from './crisis-admin.component';
+import { CrisisCenterHomeComponent } from './crisis-center-home.component';
+import { CrisisListComponent } from './crisis-list.component';
+import { CrisisCenterComponent } from './crisis-center.component';
+import { CrisisDetailComponent } from './crisis-detail.component';
+// #docregion can-deactivate-guard
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
const crisisCenterRoutes: Routes = [
@@ -19,36 +21,24 @@ const crisisCenterRoutes: Routes = [
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
- // #docregion admin-route-no-guard
- {
- path: 'admin',
- component: CrisisAdminComponent
- },
- // #enddocregion admin-route-no-guard
- {
- path: ':id',
- component: CrisisDetailComponent,
- canDeactivate: [CanDeactivateGuard]
- },
{
path: '',
- component: CrisisListComponent
+ component: CrisisListComponent,
+ children: [
+ {
+ path: ':id',
+ component: CrisisDetailComponent,
+ canDeactivate: [CanDeactivateGuard]
+ },
+ {
+ path: '',
+ component: CrisisCenterHomeComponent
+ }
+ ]
}
]
}
];
-export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
+export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion
-
-/*
-// #docregion auth-guard
-import { AuthGuard } from '../auth.guard';
-
-{
- path: 'admin',
- component: CrisisAdminComponent,
- canActivate: [AuthGuard]
-}
-// #enddocregion auth-guard
-*/
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.4.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.4.ts
deleted file mode 100644
index fa5d1e887c..0000000000
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.4.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-// #docplaster
-// #docregion
-import { Routes, RouterModule } from '@angular/router';
-
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisCenterComponent } from './crisis-center.component';
-import { CrisisAdminComponent } from './crisis-admin.component';
-
-import { CanDeactivateGuard } from '../can-deactivate-guard.service';
-import { AuthGuard } from '../auth-guard.service';
-
-const crisisCenterRoutes: Routes = [
- {
- path: '',
- redirectTo: '/crisis-center',
- pathMatch: 'full'
- },
- {
- path: 'crisis-center',
- component: CrisisCenterComponent,
- children: [
- {
- path: 'admin',
- component: CrisisAdminComponent,
- canActivate: [AuthGuard]
- },
- {
- path: ':id',
- component: CrisisDetailComponent,
- canDeactivate: [CanDeactivateGuard]
- },
- // #docregion default-route
- {
- path: '',
- component: CrisisListComponent
- }
- // #enddocregion default-route
- ]
- }
-];
-
-export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
-// #enddocregion
-
-/*
-// #docregion auth-guard
-import { AuthGuard } from '../auth.guard';
-
-{
- path: 'admin',
- component: CrisisAdminComponent,
- canActivate: [AuthGuard]
-}
-// #enddocregion auth-guard
-*/
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.5.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.5.ts
deleted file mode 100644
index cb7cda5d31..0000000000
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.5.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// #docplaster
-// #docregion
-import { Routes, RouterModule } from '@angular/router';
-
-import { CrisisCenterComponent } from './crisis-center.component';
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisAdminComponent } from './crisis-admin.component';
-
-import { CanDeactivateGuard } from '../can-deactivate-guard.service';
-import { AuthGuard } from '../auth-guard.service';
-// #docregion crisis-detail-resolve
-import { CrisisDetailResolve } from './crisis-detail-resolve.service';
-
-// #enddocregion crisis-detail-resolve
-
-const crisisCenterRoutes: Routes = [
- {
- path: '',
- redirectTo: '/crisis-center',
- pathMatch: 'full'
- },
- {
- path: 'crisis-center',
- component: CrisisCenterComponent,
- children: [
- // #docregion admin-route
- {
- path: 'admin',
- component: CrisisAdminComponent,
- canActivate: [AuthGuard]
- },
- // #enddocregion admin-route
- // #docregion crisis-detail-resolve
- {
- path: ':id',
- component: CrisisDetailComponent,
- canDeactivate: [CanDeactivateGuard],
- resolve: {
- crisis: CrisisDetailResolve
- }
- },
- // #enddocregion crisis-detail-resolve
- {
- path: '',
- component: CrisisListComponent
- }
- ]
- }
-];
-
-export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.ts
index 2d044f9de9..6b4fccde4d 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.routing.ts
@@ -1,50 +1,51 @@
// #docplaster
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { CrisisCenterComponent } from './crisis-center.component';
-import { CrisisDetailComponent } from './crisis-detail.component';
-import { CrisisListComponent } from './crisis-list.component';
-import { CrisisAdminComponent } from './crisis-admin.component';
+import { CrisisCenterHomeComponent } from './crisis-center-home.component';
+import { CrisisListComponent } from './crisis-list.component';
+import { CrisisCenterComponent } from './crisis-center.component';
+import { CrisisDetailComponent } from './crisis-detail.component';
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
-import { AuthGuard } from '../auth-guard.service';
+
// #docregion crisis-detail-resolve
import { CrisisDetailResolve } from './crisis-detail-resolve.service';
-// #enddocregion crisis-detail-resolve
-
-// #docregion lazy-load-crisis-center
const crisisCenterRoutes: Routes = [
+ // #docregion redirect
{
path: '',
+ redirectTo: '/crisis-center',
+ pathMatch: 'full'
+ },
+ // #enddocregion redirect
+ {
+ path: 'crisis-center',
component: CrisisCenterComponent,
children: [
- // #docregion admin-route
- {
- path: 'admin',
- component: CrisisAdminComponent,
- canActivate: [AuthGuard]
- },
- // #enddocregion admin-route
- // #docregion crisis-detail-resolve
- {
- path: ':id',
- component: CrisisDetailComponent,
- canDeactivate: [CanDeactivateGuard],
- resolve: {
- crisis: CrisisDetailResolve
- }
- // #enddocregion crisis-detail-resolve
- },
{
path: '',
- component: CrisisListComponent
+ component: CrisisListComponent,
+ children: [
+ {
+ path: ':id',
+ component: CrisisDetailComponent,
+ canDeactivate: [CanDeactivateGuard],
+ resolve: {
+ crisis: CrisisDetailResolve
+ }
+ },
+ {
+ path: '',
+ component: CrisisCenterHomeComponent
+ }
+ ]
}
]
}
];
-export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
-// #enddocregion lazy-load-crisis-center
+export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail-resolve.service.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail-resolve.service.ts
index d0d6d1f192..b4b92f30cc 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail-resolve.service.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail-resolve.service.ts
@@ -2,7 +2,6 @@
import { Injectable } from '@angular/core';
import { Router, Resolve,
ActivatedRouteSnapshot } from '@angular/router';
-import { Observable } from 'rxjs/Observable';
import { Crisis, CrisisService } from './crisis.service';
@@ -10,7 +9,7 @@ import { Crisis, CrisisService } from './crisis.service';
export class CrisisDetailResolve implements Resolve {
constructor(private cs: CrisisService, private router: Router) {}
- resolve(route: ActivatedRouteSnapshot): Observable | Promise | any {
+ resolve(route: ActivatedRouteSnapshot): Promise|boolean {
let id = +route.params['id'];
return this.cs.getCrisis(id).then(crisis => {
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts
index 9d37453cc1..c23c45ab58 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts
@@ -1,12 +1,12 @@
// #docplaster
// #docregion
-import { Component, OnInit, OnDestroy } from '@angular/core';
-import { ActivatedRoute, Router } from '@angular/router';
+import { Component, OnInit,
+ HostBinding, trigger, transition,
+ animate, style, state } from '@angular/core';
+import { ActivatedRoute, Router, Params } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { DialogService } from '../dialog.service';
-import { Observable } from 'rxjs/Observable';
-import { Subscription } from 'rxjs/Subscription';
@Component({
// #docregion template
@@ -26,16 +26,47 @@ import { Subscription } from 'rxjs/Subscription';
`,
// #enddocregion template
- styles: ['input {width: 20em}']
+ styles: ['input {width: 20em}'],
+ animations: [
+ trigger('routeAnimation', [
+ state('*',
+ style({
+ opacity: 1,
+ transform: 'translateX(0)'
+ })
+ ),
+ transition('void => *', [
+ style({
+ opacity: 0,
+ transform: 'translateX(-100%)'
+ }),
+ animate('0.2s ease-in')
+ ]),
+ transition('* => void', [
+ animate('0.5s ease-out', style({
+ opacity: 0,
+ transform: 'translateY(100%)'
+ }))
+ ])
+ ])
+ ]
})
// #docregion cancel-save
-export class CrisisDetailComponent implements OnInit, OnDestroy {
+export class CrisisDetailComponent implements OnInit {
+ @HostBinding('@routeAnimation') get routeAnimation() {
+ return true;
+ }
+
+ @HostBinding('style.display') get display() {
+ return 'block';
+ }
+
+ @HostBinding('style.position') get position() {
+ return 'absolute';
+ }
crisis: Crisis;
editName: string;
- // #enddocregion ngOnDestroy
- private sub: Subscription;
- // #enddocregion ngOnDestroy
// #enddocregion cancel-save
constructor(
@@ -47,9 +78,7 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
// #docregion ngOnInit
ngOnInit() {
- this.sub = this.route
- .params
- .subscribe(params => {
+ this.route.params.forEach((params: Params) => {
let id = +params['id'];
this.service.getCrisis(id)
.then(crisis => {
@@ -64,14 +93,6 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
}
// #enddocregion ngOnInit
- // #enddocregion ngOnDestroy
- ngOnDestroy() {
- if (this.sub) {
- this.sub.unsubscribe();
- }
- }
- // #enddocregion ngOnDestroy
-
// #docregion cancel-save
cancel() {
this.gotoCrises();
@@ -84,7 +105,7 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
// #enddocregion cancel-save
// #docregion cancel-save-only
- canDeactivate(): Observable | Promise | boolean {
+ canDeactivate(): Promise | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
@@ -95,15 +116,16 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
}
// #enddocregion cancel-save-only
- // #docregion gotoCrises
+ // #docregion gotoCrises, relative-navigation
gotoCrises() {
let crisisId = this.crisis ? this.crisis.id : null;
- // Pass along the hero id if available
- // so that the CrisisListComponent can select that hero.
+ // Pass along the crisis id if available
+ // so that the CrisisListComponent can select that crisis.
// Add a totally useless `foo` parameter for kicks.
- this.router.navigate(['/crisis-center', { id: crisisId, foo: 'foo' }]);
+ // Relative navigation back to the crises
+ this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });
}
- // #enddocregion gotoCrises
+ // #enddocregion gotoCrises, relative-navigation
// #docregion cancel-save
}
// #enddocregion cancel-save
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.ts
index 303f8c6d43..17ae9ff195 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.ts
@@ -1,11 +1,12 @@
// #docplaster
// #docregion
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, HostBinding,
+ trigger, transition,
+ animate, style, state } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Crisis } from './crisis.service';
import { DialogService } from '../dialog.service';
-import { Observable } from 'rxjs/Observable';
@Component({
template: `
@@ -23,10 +24,45 @@ import { Observable } from 'rxjs/Observable';
`,
- styles: ['input {width: 20em}']
+ styles: ['input {width: 20em}'],
+ // #enddocregion template
+ animations: [
+ trigger('routeAnimation', [
+ state('*',
+ style({
+ opacity: 1,
+ transform: 'translateX(0)'
+ })
+ ),
+ transition('void => *', [
+ style({
+ opacity: 0,
+ transform: 'translateX(-100%)'
+ }),
+ animate('0.2s ease-in')
+ ]),
+ transition('* => void', [
+ animate('0.5s ease-out', style({
+ opacity: 0,
+ transform: 'translateY(100%)'
+ }))
+ ])
+ ])
+ ]
})
-
export class CrisisDetailComponent implements OnInit {
+ @HostBinding('@routeAnimation') get routeAnimation() {
+ return true;
+ }
+
+ @HostBinding('style.display') get display() {
+ return 'block';
+ }
+
+ @HostBinding('style.position') get position() {
+ return 'absolute';
+ }
+
crisis: Crisis;
editName: string;
@@ -34,7 +70,7 @@ export class CrisisDetailComponent implements OnInit {
private route: ActivatedRoute,
private router: Router,
public dialogService: DialogService
- ) { }
+ ) { }
// #docregion crisis-detail-resolve
ngOnInit() {
@@ -54,7 +90,7 @@ export class CrisisDetailComponent implements OnInit {
this.gotoCrises();
}
- canDeactivate(): Observable | Promise | boolean {
+ canDeactivate(): Promise | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
@@ -67,12 +103,12 @@ export class CrisisDetailComponent implements OnInit {
// #docregion gotoCrises
gotoCrises() {
let crisisId = this.crisis ? this.crisis.id : null;
- // Pass along the hero id if available
- // so that the CrisisListComponent can select that hero.
+ // Pass along the crisis id if available
+ // so that the CrisisListComponent can select that crisis.
// Add a totally useless `foo` parameter for kicks.
// #docregion gotoCrises-navigate
- // Absolute link
- this.router.navigate(['/crisis-center', { id: crisisId, foo: 'foo' }]);
+ // Relative navigation back to the crises
+ this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });
// #enddocregion gotoCrises-navigate
}
// #enddocregion gotoCrises
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts
index 2d1df3df33..80fa3483cd 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts
@@ -23,10 +23,12 @@ export class CrisisListComponent implements OnInit, OnDestroy {
selectedId: number;
private sub: Subscription;
+ // #docregion relative-navigation-ctor
constructor(
private service: CrisisService,
private route: ActivatedRoute,
private router: Router) {}
+ // #enddocregion relative-navigation-ctor
ngOnInit() {
this.sub = this.route
@@ -45,7 +47,14 @@ export class CrisisListComponent implements OnInit, OnDestroy {
// #docregion select
onSelect(crisis: Crisis) {
// Absolute link
- this.router.navigate(['/crisis-center', crisis.id]);
+ this.router.navigate([crisis.id]);
}
// #enddocregion select
}
+// #enddocregion
+
+/*
+// #docregion relative-navigation-router-link
+{{ crisis.name }}
+// #enddocregion relative-navigation-router-link
+*/
diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts
index 7a6dcb2e9e..350867adbc 100644
--- a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts
+++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts
@@ -1,10 +1,9 @@
// #docplaster
// #docregion
-import { Component, OnInit, OnDestroy } from '@angular/core';
-import { ActivatedRoute, Router } from '@angular/router';
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router, Params } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
-import { Subscription } from 'rxjs/Subscription';
@Component({
template: `
@@ -15,38 +14,38 @@ import { Subscription } from 'rxjs/Subscription';
{{crisis.id}} {{crisis.name}}
+
+
`
})
-export class CrisisListComponent implements OnInit, OnDestroy {
+export class CrisisListComponent implements OnInit {
crises: Crisis[];
- private selectedId: number;
- private sub: Subscription;
+ public selectedId: number;
constructor(
private service: CrisisService,
private route: ActivatedRoute,
- private router: Router) { }
+ private router: Router
+ ) { }
- isSelected(crisis: Crisis) { return crisis.id === this.selectedId; }
+ isSelected(crisis: Crisis) {
+ return crisis.id === this.selectedId;
+ }
ngOnInit() {
- this.sub = this.route
- .params
- .subscribe(params => {
- this.selectedId = +params['id'];
- this.service.getCrises()
- .then(crises => this.crises = crises);
- });
- }
-
- ngOnDestroy() {
- if (this.sub) {
- this.sub.unsubscribe();
- }
+ this.route.params.forEach((params: Params) => {
+ this.selectedId = params['id'];
+ this.service.getCrises()
+ .then(crises => this.crises = crises);
+ });
}
+ // #docregion relative-navigation
onSelect(crisis: Crisis) {
- // Navigate with Absolute link
- this.router.navigate(['/crisis-center', crisis.id]);
+ this.selectedId = crisis.id;
+
+ // Navigate with relative link
+ this.router.navigate([crisis.id], { relativeTo: this.route });
}
+ // #enddocregion relative-navigation
}
diff --git a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts
index 338b9ce3c4..90d0510bd7 100644
--- a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts
+++ b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts
@@ -1,10 +1,11 @@
// #docplaster
// #docregion
-import { Component, OnInit, OnDestroy } from '@angular/core';
-import { Router, ActivatedRoute } from '@angular/router';
+import { Component, OnInit } from '@angular/core';
+// #docregion imports
+import { Router, ActivatedRoute, Params } from '@angular/router';
+// #enddocregion imports
import { Hero, HeroService } from './hero.service';
-import { Subscription } from 'rxjs/Subscription';
@Component({
template: `
@@ -23,34 +24,26 @@ import { Subscription } from 'rxjs/Subscription';
`
})
-export class HeroDetailComponent implements OnInit, OnDestroy {
+export class HeroDetailComponent implements OnInit {
hero: Hero;
- // #docregion ngOnInit
- private sub: Subscription;
- // #enddocregion ngOnInit
// #docregion ctor
constructor(
private route: ActivatedRoute,
private router: Router,
- private service: HeroService) {}
+ private service: HeroService
+ ) {}
// #enddocregion ctor
// #docregion ngOnInit
ngOnInit() {
- this.sub = this.route.params.subscribe(params => {
- let id = +params['id']; // (+) converts string 'id' to a number
- this.service.getHero(id).then(hero => this.hero = hero);
- });
+ this.route.params.forEach((params: Params) => {
+ let id = +params['id']; // (+) converts string 'id' to a number
+ this.service.getHero(id).then(hero => this.hero = hero);
+ });
}
// #enddocregion ngOnInit
- // #docregion ngOnDestroy
- ngOnDestroy() {
- this.sub.unsubscribe();
- }
- // #enddocregion ngOnDestroy
-
// #docregion gotoHeroes
gotoHeroes() { this.router.navigate(['/heroes']); }
// #enddocregion gotoHeroes
diff --git a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts
index 20b851ae6e..a263fe65f0 100644
--- a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts
+++ b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts
@@ -1,11 +1,15 @@
// #docplaster
// #docregion
-import { Component, OnInit, OnDestroy } from '@angular/core';
-import { Router, ActivatedRoute } from '@angular/router';
+// #docregion route-animation-imports
+import { Component, OnInit, HostBinding,
+ trigger, transition, animate,
+ style, state } from '@angular/core';
+// #enddocregion route-animation-imports
+import { Router, ActivatedRoute, Params } from '@angular/router';
import { Hero, HeroService } from './hero.service';
-import { Subscription } from 'rxjs/Subscription';
+// #docregion route-animation
@Component({
template: `
HEROES
@@ -21,15 +25,48 @@ import { Subscription } from 'rxjs/Subscription';
Back
- `
+ `,
+ animations: [
+ trigger('routeAnimation', [
+ state('*',
+ style({
+ opacity: 1,
+ transform: 'translateX(0)'
+ })
+ ),
+ transition('void => *', [
+ style({
+ opacity: 0,
+ transform: 'translateX(-100%)'
+ }),
+ animate('0.2s ease-in')
+ ]),
+ transition('* => void', [
+ animate('0.5s ease-out', style({
+ opacity: 0,
+ transform: 'translateY(100%)'
+ }))
+ ])
+ ])
+ ]
})
-export class HeroDetailComponent implements OnInit, OnDestroy {
+// #docregion route-animation-host-binding
+export class HeroDetailComponent implements OnInit {
+// #enddocregion route-animation
+ @HostBinding('@routeAnimation') get routeAnimation() {
+ return true;
+ }
+
+ @HostBinding('style.display') get display() {
+ return 'block';
+ }
+
+ @HostBinding('style.position') get position() {
+ return 'absolute';
+ }
+
hero: Hero;
- // #docregion ngOnInit
- private sub: Subscription;
-
- // #enddocregion ngOnInit
// #docregion ctor
constructor(
private route: ActivatedRoute,
@@ -39,19 +76,13 @@ export class HeroDetailComponent implements OnInit, OnDestroy {
// #docregion ngOnInit
ngOnInit() {
- this.sub = this.route.params.subscribe(params => {
+ this.route.params.forEach((params: Params) => {
let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero);
});
}
// #enddocregion ngOnInit
- // #docregion ngOnDestroy
- ngOnDestroy() {
- this.sub.unsubscribe();
- }
- // #enddocregion ngOnDestroy
-
// #docregion gotoHeroes-navigate
gotoHeroes() {
let heroId = this.hero ? this.hero.id : null;
@@ -60,4 +91,6 @@ export class HeroDetailComponent implements OnInit, OnDestroy {
this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);
}
// #enddocregion gotoHeroes-navigate
+// #docregion route-animation-host-binding
}
+// #enddocregion route-animation-host-binding
diff --git a/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts b/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts
index 831f24adc4..068c9680d0 100644
--- a/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts
+++ b/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts
@@ -1,13 +1,12 @@
// #docplaster
// #docregion
// TODO SOMEDAY: Feature Componetized like CrisisCenter
-import { Component, OnInit, OnDestroy } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
// #docregion import-router
-import { Router, ActivatedRoute } from '@angular/router';
+import { Router, ActivatedRoute, Params } from '@angular/router';
// #enddocregion import-router
import { Hero, HeroService } from './hero.service';
-import { Subscription } from 'rxjs/Subscription';
@Component({
// #docregion template
@@ -23,32 +22,26 @@ import { Subscription } from 'rxjs/Subscription';
`
// #enddocregion template
})
-export class HeroListComponent implements OnInit, OnDestroy {
+export class HeroListComponent implements OnInit {
heroes: Hero[];
// #docregion ctor
private selectedId: number;
- private sub: Subscription;
constructor(
private service: HeroService,
private route: ActivatedRoute,
- private router: Router) {}
+ private router: Router
+ ) {}
// #enddocregion ctor
ngOnInit() {
- this.sub = this.route
- .params
- .subscribe(params => {
+ this.route.params.forEach((params: Params) => {
this.selectedId = +params['id'];
this.service.getHeroes()
.then(heroes => this.heroes = heroes);
});
}
-
- ngOnDestroy() {
- this.sub.unsubscribe();
- }
// #enddocregion ctor
// #docregion isSelected
diff --git a/public/docs/_examples/router/ts/app/heroes/heroes.routing.ts b/public/docs/_examples/router/ts/app/heroes/heroes.routing.ts
index 89270ec492..4831fdd97b 100644
--- a/public/docs/_examples/router/ts/app/heroes/heroes.routing.ts
+++ b/public/docs/_examples/router/ts/app/heroes/heroes.routing.ts
@@ -1,4 +1,5 @@
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
@@ -11,5 +12,5 @@ const heroesRoutes: Routes = [
// #enddocregion hero-detail-route
];
-export const heroesRouting = RouterModule.forChild(heroesRoutes);
+export const heroesRouting: ModuleWithProviders = RouterModule.forChild(heroesRoutes);
// #enddocregion
diff --git a/public/docs/_examples/router/ts/app/login.component.ts b/public/docs/_examples/router/ts/app/login.component.ts
index 6dd5605fb1..41c88f4068 100755
--- a/public/docs/_examples/router/ts/app/login.component.ts
+++ b/public/docs/_examples/router/ts/app/login.component.ts
@@ -32,7 +32,7 @@ export class LoginComponent {
if (this.authService.isLoggedIn) {
// Get the redirect URL from our auth service
// If no redirect has been set, use the default
- let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/crisis-center/admin';
+ let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/admin';
// #docregion preserve
// Set our navigation extras object
diff --git a/public/docs/_examples/router/ts/app/main.ts b/public/docs/_examples/router/ts/app/main.ts
index ba9421d573..961a226688 100644
--- a/public/docs/_examples/router/ts/app/main.ts
+++ b/public/docs/_examples/router/ts/app/main.ts
@@ -1,6 +1,6 @@
// #docregion
-import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
-browserDynamicPlatform().bootstrapModule(AppModule);
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/router/ts/index.html b/public/docs/_examples/router/ts/index.html
index b15ea73dfa..abcbea6c31 100644
--- a/public/docs/_examples/router/ts/index.html
+++ b/public/docs/_examples/router/ts/index.html
@@ -1,6 +1,5 @@
-
diff --git a/public/docs/_examples/security/ts/app/bypass-security.component.html b/public/docs/_examples/security/ts/app/bypass-security.component.html
index 1b0a9d0c0e..374dcc8d64 100644
--- a/public/docs/_examples/security/ts/app/bypass-security.component.html
+++ b/public/docs/_examples/security/ts/app/bypass-security.component.html
@@ -2,7 +2,7 @@
Bypass Security Component
-A untrusted URL:
+An untrusted URL:
Click me
A trusted URL:
Click me
diff --git a/public/docs/_examples/security/ts/app/bypass-security.component.ts b/public/docs/_examples/security/ts/app/bypass-security.component.ts
index a18d4251a5..7c30903955 100644
--- a/public/docs/_examples/security/ts/app/bypass-security.component.ts
+++ b/public/docs/_examples/security/ts/app/bypass-security.component.ts
@@ -1,7 +1,7 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
-import { DomSanitizationService, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';
+import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';
@Component({
selector: 'bypass-security',
@@ -14,9 +14,9 @@ export class BypassSecurityComponent {
videoUrl: SafeResourceUrl;
// #docregion trust-url
- constructor(private sanitizer: DomSanitizationService) {
+ constructor(private sanitizer: DomSanitizer) {
// javascript: URLs are dangerous if attacker controlled.
- // Angular sanitizes them in data binding, but we can
+ // Angular sanitizes them in data binding, but you can
// explicitly tell Angular to trust this value:
this.dangerousUrl = 'javascript:alert("Hi there")';
this.trustedUrl = sanitizer.bypassSecurityTrustUrl(this.dangerousUrl);
@@ -28,7 +28,7 @@ export class BypassSecurityComponent {
updateVideoUrl(id: string) {
// Appending an ID to a YouTube URL is safe.
// Always make sure to construct SafeValue objects as
- // close as possible to the input data, so
+ // close as possible to the input data so
// that it's easier to check if the value is safe.
this.dangerousVideoUrl = 'https://www.youtube.com/embed/' + id;
this.videoUrl =
diff --git a/public/docs/_examples/security/ts/app/inner-html-binding.component.ts b/public/docs/_examples/security/ts/app/inner-html-binding.component.ts
index 0419e5b324..88475e3724 100644
--- a/public/docs/_examples/security/ts/app/inner-html-binding.component.ts
+++ b/public/docs/_examples/security/ts/app/inner-html-binding.component.ts
@@ -8,6 +8,6 @@ import { Component } from '@angular/core';
})
// #docregion inner-html-controller
export class InnerHtmlBindingComponent {
- // E.g. a user/attacker controlled value from a URL.
+ // For example, a user/attacker-controlled value from a URL.
htmlSnippet = 'Template Syntax ';
}
diff --git a/public/docs/_examples/server-communication/dart/pubspec.yaml b/public/docs/_examples/server-communication/dart/pubspec.yaml
index 3d8e06cbe0..a2a1b30e93 100644
--- a/public/docs/_examples/server-communication/dart/pubspec.yaml
+++ b/public/docs/_examples/server-communication/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
http: ^0.11.3+3
diff --git a/public/docs/_examples/server-communication/ts/app/app.module.1.ts b/public/docs/_examples/server-communication/ts/app/app.module.1.ts
index 51e52573cb..51329e31cb 100644
--- a/public/docs/_examples/server-communication/ts/app/app.module.1.ts
+++ b/public/docs/_examples/server-communication/ts/app/app.module.1.ts
@@ -14,7 +14,7 @@ import { AppComponent } from './app.component';
JsonpModule
],
declarations: [ AppComponent ],
- bootstrap: [ AppComponent ]
+ bootstrap: [ AppComponent ]
})
export class AppModule { }
diff --git a/public/docs/_examples/server-communication/ts/app/app.module.ts b/public/docs/_examples/server-communication/ts/app/app.module.ts
index 528110661b..95490f2b1d 100644
--- a/public/docs/_examples/server-communication/ts/app/app.module.ts
+++ b/public/docs/_examples/server-communication/ts/app/app.module.ts
@@ -2,11 +2,12 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { HttpModule, JsonpModule, XHRBackend } from '@angular/http';
+import { HttpModule, JsonpModule } from '@angular/http';
-import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
-import { HeroData } from './hero-data';
-import { AppComponent } from './app.component';
+import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
+import { HeroData } from './hero-data';
+
+import { AppComponent } from './app.component';
import { HeroListComponent } from './toh/hero-list.component';
import { HeroListPromiseComponent } from './toh/hero-list.component.promise';
@@ -19,11 +20,10 @@ import { WikiSmartComponent } from './wiki/wiki-smart.component';
BrowserModule,
FormsModule,
HttpModule,
- JsonpModule
- ],
- providers: [
- { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
- { provide: SEED_DATA, useClass: HeroData } // in-mem server data
+ JsonpModule,
+ // #docregion in-mem-web-api
+ InMemoryWebApiModule.forRoot(HeroData)
+ // #enddocregion in-mem-web-api
],
declarations: [
AppComponent,
diff --git a/public/docs/_examples/server-communication/ts/app/hero-data.ts b/public/docs/_examples/server-communication/ts/app/hero-data.ts
index ad10b464c7..e5e0bab986 100644
--- a/public/docs/_examples/server-communication/ts/app/hero-data.ts
+++ b/public/docs/_examples/server-communication/ts/app/hero-data.ts
@@ -1,5 +1,6 @@
// #docregion
-export class HeroData {
+import { InMemoryDbService } from 'angular2-in-memory-web-api';
+export class HeroData implements InMemoryDbService {
createDb() {
let heroes = [
{ id: '1', name: 'Windstorm' },
diff --git a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.1.ts b/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.1.ts
index 518bc2b05f..25911b0d37 100644
--- a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.1.ts
+++ b/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.1.ts
@@ -18,7 +18,7 @@ export class WikipediaService {
return this.jsonp
.get(wikiUrl + queryString)
- .map(request => request.json()[1]);
+ .map(response => response.json()[1]);
// #enddocregion query-string
}
}
diff --git a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.ts b/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.ts
index 96eca70af1..742dfed1b9 100644
--- a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.ts
+++ b/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.ts
@@ -22,7 +22,7 @@ export class WikipediaService {
// TODO: Add error handling
return this.jsonp
.get(wikiUrl, { search: params })
- .map(request => request.json()[1]);
+ .map(response => response.json()[1]);
// #enddocregion call-jsonp
}
}
diff --git a/public/docs/_examples/server-communication/ts/index.html b/public/docs/_examples/server-communication/ts/index.html
index c2d2656c84..d265bef2f9 100644
--- a/public/docs/_examples/server-communication/ts/index.html
+++ b/public/docs/_examples/server-communication/ts/index.html
@@ -2,7 +2,7 @@
- Angular 2 Http Demo
+ Angular Http Demo
diff --git a/public/docs/_examples/structural-directives/dart/pubspec.yaml b/public/docs/_examples/structural-directives/dart/pubspec.yaml
index daba4aa174..c4c0bca74a 100644
--- a/public/docs/_examples/structural-directives/dart/pubspec.yaml
+++ b/public/docs/_examples/structural-directives/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/structural-directives/ts/index.html b/public/docs/_examples/structural-directives/ts/index.html
index da815d8e69..2dc2548cc4 100644
--- a/public/docs/_examples/structural-directives/ts/index.html
+++ b/public/docs/_examples/structural-directives/ts/index.html
@@ -2,7 +2,7 @@
- Angular 2 Structural Directives
+ Angular Structural Directives
diff --git a/public/docs/_examples/style-guide/e2e-spec.ts b/public/docs/_examples/style-guide/e2e-spec.ts
index c0fedf822e..8066df6e7b 100644
--- a/public/docs/_examples/style-guide/e2e-spec.ts
+++ b/public/docs/_examples/style-guide/e2e-spec.ts
@@ -57,19 +57,6 @@ describe('Style Guide', function () {
expect(buttons.get(1).getText()).toBe('Hide toast');
});
- it('03-05', function () {
- browser.get('#/03-05');
-
- let div = element(by.tagName('sg-app > div'));
- expect(div.getText()).toBe('Actual favorite: Windstorm');
-
- let lis = element.all(by.tagName('sg-app > ul > li'));
- expect(lis.get(0).getText()).toBe('Windstorm');
- expect(lis.get(1).getText()).toBe('Bombasto');
- expect(lis.get(2).getText()).toBe('Magneta');
- expect(lis.get(3).getText()).toBe('Tornado');
- });
-
it('03-06', function () {
browser.get('#/03-06');
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.avoid.ts
deleted file mode 100644
index cff95fd096..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.avoid.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// #docregion
-// #docregion example
-/* avoid */
-
-import {Injectable} from '@angular/core';
-import {Http, Response} from '@angular/http';
-
-import {Hero} from './hero.model';
-import {ExceptionService, SpinnerService, ToastService} from '../../shared';
-// #enddocregion example
-
-@Injectable()
-export class HeroService {
-
- constructor(
- private exceptionService: ExceptionService,
- private spinnerService: SpinnerService,
- private toastService: ToastService,
- private http: Http
- ) { }
-
- getHero(id: number) {
- return this.http.get(`api/heroes/${id}`)
- .map((res: Response) => res.json().data);
- }
-
- getHeroes() {
- return this.http.get(`api/heroes`)
- .map((res: Response) => res.json().data);
- }
-
-}
-
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.ts
deleted file mode 100644
index 85fa486432..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// #docregion
-// #docregion example
-import { Injectable } from '@angular/core';
-import { Http, Response } from '@angular/http';
-
-import { Hero } from './hero.model';
-import { ExceptionService, SpinnerService, ToastService } from '../../shared';
-// #enddocregion example
-
-@Injectable()
-export class HeroService {
- cachedHeroes: Hero[];
-
- constructor(
- private exceptionService: ExceptionService,
- private spinnerService: SpinnerService,
- private toastService: ToastService,
- private http: Http
- ) { }
-
- getHero(id: number) {
- return this.http.get(`app/heroes/${id}`)
- .map((res: Response) => res.json().data);
- }
-
- getHeroes() {
- return this.http.get(`api/heroes`)
- .map((res: Response) => res.json().data);
- }
-
-}
-
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/app.component.html b/public/docs/_examples/style-guide/ts/03-05/app/app.component.html
deleted file mode 100644
index 67fb0d5964..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/app.component.html
+++ /dev/null
@@ -1,6 +0,0 @@
-Actual favorite: {{favorite?.name}}
-
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-05/app/app.component.ts
deleted file mode 100644
index 8268f0d0b9..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/app.component.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-
-import { Hero, HeroService } from './+heroes';
-import { ExceptionService, SpinnerService, ToastService } from './shared';
-
-@Component({
- moduleId: module.id,
- selector: 'sg-app',
- templateUrl: 'app.component.html',
- providers: [HeroService, ExceptionService, SpinnerService, ToastService]
-})
-export class AppComponent implements OnInit {
- favorite: Hero;
- heroes: Hero[];
-
- constructor(private heroService: HeroService) { }
-
- ngOnInit() {
- this.heroService.getHero(1).subscribe(hero => this.favorite = hero);
- this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes);
- }
-}
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/app.module.ts b/public/docs/_examples/style-guide/ts/03-05/app/app.module.ts
deleted file mode 100644
index b70c8416c7..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/app.module.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { RouterModule } from '@angular/router';
-
-import { AppComponent } from './app.component';
-
-export const route = { path: '03-05', component: AppComponent };
-
-@NgModule({
- imports: [
- BrowserModule,
- RouterModule.forChild([{ path: '03-05', component: AppComponent }])
- ],
- declarations: [
- AppComponent
- ],
- exports: [ AppComponent ]
-})
-export class AppModule {}
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/index.ts b/public/docs/_examples/style-guide/ts/03-05/app/index.ts
deleted file mode 100644
index aa9e5b0b7c..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './+heroes';
-export * from './shared';
-export * from './app.component';
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/exception.service.ts
deleted file mode 100644
index 7180c88e6b..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/exception.service.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { Injectable } from '@angular/core';
-
-@Injectable()
-export class ExceptionService { }
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/index.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/index.ts
deleted file mode 100644
index e4e6723f91..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// #docregion
-// #docregion example
-export * from './exception.service';
-export * from './spinner';
-export * from './toast';
-// #enddocregion example
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/index.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/index.ts
deleted file mode 100644
index 1d619300c0..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// #docregion
-export * from './spinner.component';
-export * from './spinner.service';
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.component.ts
deleted file mode 100644
index 1fd2a01500..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.component.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Component, OnDestroy, OnInit } from '@angular/core';
-
-import { SpinnerService } from './spinner.service';
-
-@Component({
- selector: 'toh-spinner',
- template: 'spinner
'
-})
-
-export class SpinnerComponent implements OnDestroy, OnInit {
- constructor(private spinnerService: SpinnerService) { }
-
- ngOnInit() { }
-
- ngOnDestroy() { }
-}
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.service.ts
deleted file mode 100644
index ad5d2ed6e0..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.service.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Injectable } from '@angular/core';
-
-export interface ISpinnerState { }
-
-@Injectable()
-export class SpinnerService {
- spinnerState: any;
-
- show() { }
-
- hide() { }
-}
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/index.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/index.ts
deleted file mode 100644
index 01b41aff98..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// #docregion
-export * from './toast.component';
-export * from './toast.service';
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.component.ts
deleted file mode 100644
index 24afa50a5b..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.component.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-
-import { ToastService } from './toast.service';
-
-@Component({
- moduleId: module.id,
- selector: 'toh-toast',
- templateUrl: 'toast
'
-})
-export class ToastComponent implements OnInit {
- constructor(toastService: ToastService) { }
-
- ngOnInit() { }
-}
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.service.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.service.ts
deleted file mode 100644
index e92e75ee45..0000000000
--- a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.service.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { Injectable } from '@angular/core';
-
-@Injectable()
-export class ToastService {
- activate: (message?: string, title?: string) => void;
-}
diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/+heroes/index.ts
deleted file mode 100644
index c3da79f741..0000000000
--- a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './shared';
diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.model.ts
deleted file mode 100644
index c3277621cb..0000000000
--- a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.model.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// #docregion
-// #docregion example
-export class Hero {
- name: string;
- power: string;
-}
-// #enddocregion example
diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/index.ts
deleted file mode 100644
index dbb150d3f8..0000000000
--- a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './hero.model';
-export * from './hero.service';
diff --git a/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts
index 8268f0d0b9..17822c8a3e 100644
--- a/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts
+++ b/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts
@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';
-import { Hero, HeroService } from './+heroes';
+import { Hero, HeroService } from './heroes';
import { ExceptionService, SpinnerService, ToastService } from './shared';
@Component({
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/heroes/index.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/03-05/app/+heroes/index.ts
rename to public/docs/_examples/style-guide/ts/03-06/app/heroes/index.ts
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.model.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.model.ts
rename to public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.model.ts
diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.avoid.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.avoid.ts
rename to public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.avoid.ts
diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.ts
rename to public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.ts
diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/index.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/index.ts
rename to public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/index.ts
diff --git a/public/docs/_examples/style-guide/ts/03-06/app/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/index.ts
index aa9e5b0b7c..251d78ac56 100644
--- a/public/docs/_examples/style-guide/ts/03-06/app/index.ts
+++ b/public/docs/_examples/style-guide/ts/03-06/app/index.ts
@@ -1,3 +1,3 @@
-export * from './+heroes';
+export * from './heroes';
export * from './shared';
export * from './app.component';
diff --git a/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts b/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts
index d41269c2c5..dc96beac4c 100644
--- a/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts
+++ b/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts
@@ -2,7 +2,7 @@
import { Component } from '@angular/core';
// #docregion example
-import { HeroesComponent } from './+heroes';
+import { HeroesComponent } from './heroes';
// #enddocregion example
@Component({
diff --git a/public/docs/_examples/style-guide/ts/04-13/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/04-13/app/heroes/index.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/04-13/app/+heroes/index.ts
rename to public/docs/_examples/style-guide/ts/04-13/app/heroes/index.ts
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/app.module.ts b/public/docs/_examples/style-guide/ts/04-14/app/app.module.ts
index be01c06624..a9377ce9d6 100644
--- a/public/docs/_examples/style-guide/ts/04-14/app/app.module.ts
+++ b/public/docs/_examples/style-guide/ts/04-14/app/app.module.ts
@@ -3,7 +3,7 @@ import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
-import { HeroesComponent } from './+heroes';
+import { HeroesComponent } from './heroes';
@NgModule({
imports: [
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.css b/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.css
similarity index 100%
rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.css
rename to public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.css
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.html
similarity index 100%
rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.html
rename to public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.html
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.ts
rename to public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.ts
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/heroes/index.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/index.ts
rename to public/docs/_examples/style-guide/ts/04-14/app/heroes/index.ts
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/hero.model.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/hero.model.ts
rename to public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/hero.model.ts
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/index.ts
similarity index 100%
rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/index.ts
rename to public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/index.ts
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/index.ts
index aa9e5b0b7c..251d78ac56 100644
--- a/public/docs/_examples/style-guide/ts/04-14/app/index.ts
+++ b/public/docs/_examples/style-guide/ts/04-14/app/index.ts
@@ -1,3 +1,3 @@
-export * from './+heroes';
+export * from './heroes';
export * from './shared';
export * from './app.component';
diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.service.ts
index f8690e9c2f..3f83d92fe8 100644
--- a/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.service.ts
+++ b/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.service.ts
@@ -2,7 +2,7 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
-import { Hero } from './hero.model.ts';
+import { Hero } from './hero.model';
@Injectable()
export class HeroService {
diff --git a/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.ts b/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.ts
index b8ebd4cc46..5f18cc5b0c 100644
--- a/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.ts
+++ b/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.ts
@@ -2,7 +2,7 @@
// #docregion
import { Component } from '@angular/core';
-import { Hero } from '../shared/hero.model.ts';
+import { Hero } from '../shared/hero.model';
// #docregion example
@Component({
diff --git a/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.service.ts
index f8690e9c2f..3f83d92fe8 100644
--- a/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.service.ts
+++ b/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.service.ts
@@ -2,7 +2,7 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
-import { Hero } from './hero.model.ts';
+import { Hero } from './hero.model';
@Injectable()
export class HeroService {
diff --git a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.service.ts
index f8690e9c2f..3f83d92fe8 100644
--- a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.service.ts
+++ b/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.service.ts
@@ -2,7 +2,7 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
-import { Hero } from './hero.model.ts';
+import { Hero } from './hero.model';
@Injectable()
export class HeroService {
diff --git a/public/docs/_examples/style-guide/ts/app/app.routes.ts b/public/docs/_examples/style-guide/ts/app/app.routes.ts
index 3d5d6b3c15..1fb26f08ea 100644
--- a/public/docs/_examples/style-guide/ts/app/app.routes.ts
+++ b/public/docs/_examples/style-guide/ts/app/app.routes.ts
@@ -1,4 +1,4 @@
-import { RouterConfig } from '@angular/router';
+import { Routes } from '@angular/router';
import { AppComponent as S0101 } from '../01-01/app';
// import { AppComponent as S0207 } from '../02-07/app';
@@ -27,7 +27,7 @@ import { AppComponent as S0101 } from '../01-01/app';
// import { AppComponent as S0704 } from '../07-04/app';
// import { AppComponent as S0901 } from '../09-01/app';
-export const routes: RouterConfig = [
+export const routes: Routes = [
{ path: '', redirectTo: '/01-01', pathMatch: 'full' },
{ path: '01-01', component: S0101 },
// { path: '02-07', component: S0207 },
@@ -56,4 +56,3 @@ export const routes: RouterConfig = [
// { path: '07-04', component: S0704 },
// { path: '09-01', component: S0901 },
];
-
diff --git a/public/docs/_examples/style-guide/ts/app/main.ts b/public/docs/_examples/style-guide/ts/app/main.ts
index 77e1c29934..579ffbb101 100644
--- a/public/docs/_examples/style-guide/ts/app/main.ts
+++ b/public/docs/_examples/style-guide/ts/app/main.ts
@@ -1,17 +1,15 @@
import { NgModule } from '@angular/core';
-import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
-import { HttpModule,
- XHRBackend } from '@angular/http';
+import { HttpModule } from '@angular/http';
+import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
+
import { RouterModule } from '@angular/router';
import { HashLocationStrategy,
LocationStrategy } from '@angular/common';
-import { InMemoryBackendService,
- SEED_DATA } from 'angular2-in-memory-web-api';
-
import 'rxjs/add/operator/map';
import { HeroData } from './hero-data';
@@ -24,7 +22,6 @@ import * as s0301 from '../03-01/app/app.module';
import * as s0302 from '../03-02/app/app.module';
import * as s0303 from '../03-03/app/app.module';
import * as s0304 from '../03-04/app/app.module';
-import * as s0305 from '../03-05/app/app.module';
import * as s0306 from '../03-06/app/app.module';
import * as s0410 from '../04-10/app/app.module';
import * as s0414 from '../04-14/app/app.module';
@@ -49,6 +46,7 @@ const moduleMetadata = {
imports: [
BrowserModule,
HttpModule,
+ InMemoryWebApiModule.forRoot(HeroData),
s0101.AppModule,
s0207.AppModule,
@@ -57,7 +55,6 @@ const moduleMetadata = {
s0302.AppModule,
s0303.AppModule,
s0304.AppModule,
- s0305.AppModule,
s0306.AppModule,
s0410.AppModule,
s0414.AppModule,
@@ -77,22 +74,21 @@ const moduleMetadata = {
s0704.AppModule,
s0901.AppModule,
+
RouterModule.forRoot([
{ path: '', redirectTo: '/01-01', pathMatch: 'full' }
], {/* enableTracing: true */}),
],
- declarations: [AppComponent],
providers: [
- { provide: LocationStrategy, useClass: HashLocationStrategy },
- { provide: XHRBackend, useClass: InMemoryBackendService },
- { provide: SEED_DATA, useClass: HeroData }
+ { provide: LocationStrategy, useClass: HashLocationStrategy }
],
- bootstrap: [ AppComponent ]
+ declarations: [ AppComponent ],
+ bootstrap: [ AppComponent ]
};
@NgModule(moduleMetadata)
class MainModule { }
-browserDynamicPlatform().bootstrapModule(MainModule);
+platformBrowserDynamic().bootstrapModule(MainModule);
diff --git a/public/docs/_examples/style-guide/ts/systemjs.custom.js b/public/docs/_examples/style-guide/ts/systemjs.custom.js
index 1ffb1b863a..bc5a4d2eb3 100644
--- a/public/docs/_examples/style-guide/ts/systemjs.custom.js
+++ b/public/docs/_examples/style-guide/ts/systemjs.custom.js
@@ -9,12 +9,12 @@
'03-03', '03-03/app', '03-03/app/shared',
'03-04', '03-04/app', '03-04/app/shared',
'03-05', '03-05/app', '03-05/app/shared', '03-05/app/shared/spinner', '03-05/app/shared/toast',
- '03-05/app/+heroes', '03-05/app/+heroes/shared',
+ '03-05/app/heroes', '03-05/app/heroes/shared',
'03-06', '03-06/app', '03-06/app/shared', '03-06/app/shared/spinner', '03-06/app/shared/toast',
- '03-06/app/+heroes', '03-06/app/+heroes/shared',
- '04-10', '04-10/app', '04-10/app/shared', '04-10/app/+heroes', '04-10/app/shared/spinner', '04-10/app/shared/toast',
+ '03-06/app/heroes', '03-06/app/heroes/shared',
+ '04-10', '04-10/app', '04-10/app/shared', '04-10/app/heroes', '04-10/app/shared/spinner', '04-10/app/shared/toast',
'04-10/app/shared/filter-text', '04-10/app/shared/modal', '04-10/app/shared/nav',
- '04-14', '04-14/app', '04-14/app/+heroes', '04-14/app/+heroes/shared', '04-14/app/shared',
+ '04-14', '04-14/app', '04-14/app/heroes', '04-14/app/heroes/shared', '04-14/app/shared',
'05-02', '05-02/app', '05-02/app/heroes', '05-02/app/heroes/shared', '05-02/app/heroes/shared/hero-button',
'05-03', '05-03/app', '05-03/app/heroes', '05-03/app/heroes/shared', '05-03/app/heroes/shared/hero-button',
'05-04', '05-04/app', '05-04/app/heroes', '05-04/app/heroes/shared',
@@ -23,7 +23,7 @@
'05-14', '05-14/app', '05-14/app/shared', '05-14/app/shared/toast',
'05-15', '05-15/app', '05-15/app/heroes', '05-15/app/heroes/hero-list', '05-15/app/heroes/shared',
'05-16', '05-16/app', '05-16/app/heroes',
- '05-17', '05-17/app', '05-17/app/heroes', '05-17/app/heroes/hero', '05-17/app/heroes/hero-list',
+ '05-17', '05-17/app', '05-17/app/heroes', '05-17/app/heroes/hero', '05-17/app/heroes/hero-list',
'05-17/app/heroes/shared',
'06-01', '06-01/app', '06-01/app/shared',
'06-03', '06-03/app', '06-03/app/shared',
diff --git a/public/docs/_examples/styleguide/e2e-spec.ts b/public/docs/_examples/styleguide/e2e-spec.ts
index 6dc2753038..321e86c8a1 100644
--- a/public/docs/_examples/styleguide/e2e-spec.ts
+++ b/public/docs/_examples/styleguide/e2e-spec.ts
@@ -2,7 +2,7 @@
'use strict';
describe('Documentation StyleGuide E2E Tests', function() {
- let expectedMsg = 'My First Angular 2 App';
+ let expectedMsg = 'My First Angular App';
beforeEach(function () {
browser.get('');
diff --git a/public/docs/_examples/styleguide/js/app.js b/public/docs/_examples/styleguide/js/app.js
index 61a0f2ae31..d38669cd78 100644
--- a/public/docs/_examples/styleguide/js/app.js
+++ b/public/docs/_examples/styleguide/js/app.js
@@ -8,7 +8,7 @@ app.AppComponent =
selector: 'my-app',
// #enddocregion
// #docregion view
- template: 'My First Angular 2 App '
+ template: 'My First Angular App '
})
// #enddocregion
// #docregion class
@@ -48,7 +48,7 @@ app.AppComponent = function AppComponent () {}
app.AppComponent.annotations = [
new ng.core.Component({
selector: 'my-app',
- template: 'My First Angular 2 App '
+ template: 'My First Angular App '
})
];
// #enddocregion
diff --git a/public/docs/_examples/styleguide/js/index.html b/public/docs/_examples/styleguide/js/index.html
index b7da03d83a..d863bfcecb 100644
--- a/public/docs/_examples/styleguide/js/index.html
+++ b/public/docs/_examples/styleguide/js/index.html
@@ -10,7 +10,7 @@
-
+
diff --git a/public/docs/_examples/styleguide/ts/app/app.component.ts b/public/docs/_examples/styleguide/ts/app/app.component.ts
index 7659920b9f..8b71f6ddc4 100644
--- a/public/docs/_examples/styleguide/ts/app/app.component.ts
+++ b/public/docs/_examples/styleguide/ts/app/app.component.ts
@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
- template: 'My First Angular 2 App '
+ template: 'My First Angular App '
})
export class AppComponent { }
diff --git a/public/docs/_examples/styles.css b/public/docs/_examples/styles.css
index 62ddfa5121..d7b83f9e81 100644
--- a/public/docs/_examples/styles.css
+++ b/public/docs/_examples/styles.css
@@ -1,3 +1,4 @@
+/* #docregion , quickstart, toh */
/* Master Styles */
h1 {
color: #369;
@@ -12,10 +13,12 @@ h2, h3 {
body {
margin: 2em;
}
+/* #enddocregion quickstart */
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
+/* #enddocregion toh */
a {
cursor: pointer;
cursor: hand;
@@ -135,7 +138,7 @@ nav a.active {
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
-
+/* #docregion toh */
/* everywhere else */
* {
font-family: Arial, Helvetica, sans-serif;
diff --git a/public/docs/_examples/systemjs.config.js b/public/docs/_examples/systemjs.config.js
index 1921a431c0..cc06fc9422 100644
--- a/public/docs/_examples/systemjs.config.js
+++ b/public/docs/_examples/systemjs.config.js
@@ -1,59 +1,46 @@
/**
- * System configuration for Angular 2 samples
+ * System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
-(function(global) {
+(function (global) {
+ System.config({
+ paths: {
+ // paths serve as alias
+ 'npm:': 'node_modules/'
+ },
+ // map tells the System loader where to look for things
+ map: {
+ // our app is within the app folder
+ app: 'app',
- // map tells the System loader where to look for things
- var map = {
- 'app': 'app', // 'dist',
-
- '@angular': 'node_modules/@angular',
- 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
- 'rxjs': 'node_modules/rxjs'
- };
-
- // packages tells the System loader how to load when no filename and/or no extension
- var packages = {
- 'app': { main: 'main.js', defaultExtension: 'js' },
- 'rxjs': { defaultExtension: 'js' },
- 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
- };
-
- var ngPackageNames = [
- 'common',
- 'compiler',
- 'core',
- 'forms',
- 'http',
- 'platform-browser',
- 'platform-browser-dynamic',
- 'router',
- 'router-deprecated',
- 'upgrade',
- ];
-
- // Individual files (~300 requests):
- function packIndex(pkgName) {
- packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
- }
-
- // Bundled (~40 requests):
- function packUmd(pkgName) {
- packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
- }
-
- // Most environments should use UMD; some (Karma) need the individual index files
- var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
-
- // Add package entries for angular packages
- ngPackageNames.forEach(setPackageConfig);
-
- var config = {
- map: map,
- packages: packages
- };
-
- System.config(config);
+ // angular bundles
+ '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
+ '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
+ '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
+ '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
+ '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
+ '@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',
+ 'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
+ },
+ // packages tells the System loader how to load when no filename and/or no extension
+ packages: {
+ app: {
+ main: './main.js',
+ defaultExtension: 'js'
+ },
+ rxjs: {
+ defaultExtension: 'js'
+ },
+ 'angular2-in-memory-web-api': {
+ main: './index.js',
+ defaultExtension: 'js'
+ }
+ }
+ });
})(this);
diff --git a/public/docs/_examples/systemjs.config.plunker.build.js b/public/docs/_examples/systemjs.config.plunker.build.js
index 3ccf77808c..36ad2c7d16 100644
--- a/public/docs/_examples/systemjs.config.plunker.build.js
+++ b/public/docs/_examples/systemjs.config.plunker.build.js
@@ -1,84 +1,13 @@
/**
- * PLUNKER CURRENT BUILD VERSION
+ * PLUNKER VERSION FOR CURRENT ANGULAR BUILD
* (based on systemjs.config.js in angular.io)
- * System configuration for Angular 2 samples
+ * System configuration for Angular samples
* Adjust as necessary for your application needs.
+ *
+ * UNTESTED !
*/
-(function(global) {
-
- var ngVer = '@2.0.0-rc.5'; // lock in the angular package version; do not let it float to current!
- var routerVer = '@3.0.0-rc.1'; // lock router version
- var formsVer = '@0.3.0'; // lock forms version
- var routerDeprecatedVer = '@2.0.0-rc.2'; // temporarily until we update all the guides
-
- //map tells the System loader where to look for things
- var map = {
- 'app': 'app',
-
-
- '@angular/core': 'https://cdn.rawgit.com/angular/core-builds/master',
- '@angular/common': 'https://cdn.rawgit.com/angular/common-builds/master',
- '@angular/compiler':'https://cdn.rawgit.com/angular/compiler-builds/master',
- '@angular/forms':'https://cdn.rawgit.com/angular/forms-builds/master',
- '@angular/http':'https://cdn.rawgit.com/angular/http-builds/master',
- '@angular/platform-browser':'https://cdn.rawgit.com/angular/platform-browser-builds/master',
- '@angular/platform-browser-dynamic': 'https://cdn.rawgit.com/angular/platform-browser-dynamic-builds/master',
- '@angular/router': 'https://cdn.rawgit.com/angular/router-builds/master',
-
- 'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6',
- 'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js',
- 'typescript': 'https://npmcdn.com/typescript@1.9.0-dev.20160409/lib/typescript.js',
-
- 'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api',
- };
-
- //packages tells the System loader how to load when no filename and/or no extension
- var packages = {
- app: {
- main: 'main.ts',
- defaultExtension: 'ts'
- },
- '@angular/core': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- '@angular/compiler': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- '@angular/common': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- '@angular/forms': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- '@angular/http': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- '@angular/platform-browser-dynamic': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- '@angular/platform-browser': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- '@angular/router': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- 'angular2-in-memory-web-api': {
- main: 'index.js',
- defaultExtension: 'js'
- },
- rxjs: {
- defaultExtension: 'js'
- }
- }
- var config = {
+(function (global) {
+ System.config({
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: 'ts',
typescriptOptions: {
@@ -89,17 +18,57 @@
"exports": "ts"
}
},
- map: map,
- packages: packages
- };
+ paths: {
+ // paths serve as alias
+ 'npm:': 'https://unpkg.com/',
+ 'ng:': 'https://cdn.rawgit.com/angular/'
+ },
+ // map tells the System loader where to look for things
+ map: {
+ // our app is within the app folder
+ app: 'app',
- System.config(config);
+ // angular bundles
+ '@angular/core': 'ng:core-builds/master/bundles/core.umd.js',
+ '@angular/common': 'ng:common-builds/master/bundles/common.umd.js',
+ '@angular/compiler': 'ng:compiler-builds/master/bundles/compiler.umd.js',
+ '@angular/platform-browser': 'ng:platform-browser-builds/master/bundles/platform-browser.umd.js',
+ '@angular/platform-browser-dynamic': 'ng:platform-browser-dynamic-builds/master/bundles/platform-browser-dynamic.umd.js',
+ '@angular/http': 'ng:http-builds/master/bundles/http.umd.js',
+ '@angular/router': 'ng:router-builds/master/bundles/router.umd.js',
+ '@angular/forms': 'ng:forms-builds/master/bundles/forms.umd.js',
+ '@angular/upgrade': 'ng:upgrade-builds/master/bundles/upgrade.umd.js',
+ // angular testing umd bundles (overwrite the shim mappings)
+ '@angular/core/testing': 'ng:core-builds/master/bundles/core-testing.umd.js',
+ '@angular/common/testing': 'ng:common-builds/master/bundles/common-testing.umd.js',
+ '@angular/compiler/testing': 'ng:compiler-builds/master/bundles/compiler-testing.umd.js',
+ '@angular/platform-browser/testing': 'ng:platform-browser-builds/master/bundles/platform-browser-testing.umd.js',
+ '@angular/platform-browser-dynamic/testing': 'ng:platform-browser-dynamic-builds/master/bundles/platform-browser-dynamic-testing.umd.js',
+ '@angular/http/testing': 'ng:http-builds/master/bundles/http-testing.umd.js',
+ '@angular/router/testing': 'ng:router-builds/master/bundles/router-testing.umd.js',
+ '@angular/forms/testing': 'ng:forms-builds/master/bundles/forms-testing.umd.js',
+
+ // other libraries
+ 'rxjs': 'npm:rxjs',
+ 'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
+ 'ts': 'npm:plugin-typescript@4.0.10/lib/plugin.js',
+ 'typescript': 'npm:typescript@2.0.2/lib/typescript.js',
+
+ },
+ // packages tells the System loader how to load when no filename and/or no extension
+ packages: {
+ app: {
+ main: './main.ts',
+ defaultExtension: 'ts'
+ },
+ rxjs: {
+ defaultExtension: 'js'
+ },
+ 'angular2-in-memory-web-api': {
+ main: './index.js',
+ defaultExtension: 'js'
+ }
+ }
+ });
})(this);
-
-
-/*
-Copyright 2016 Google Inc. All Rights Reserved.
-Use of this source code is governed by an MIT-style license that
-can be found in the LICENSE file at http://angular.io/license
-*/
diff --git a/public/docs/_examples/systemjs.config.plunker.js b/public/docs/_examples/systemjs.config.plunker.js
index d55c4db274..ccfee00019 100644
--- a/public/docs/_examples/systemjs.config.plunker.js
+++ b/public/docs/_examples/systemjs.config.plunker.js
@@ -1,63 +1,11 @@
/**
- * PLUNKER VERSION (based on systemjs.config.js in angular.io)
- * System configuration for Angular 2 samples
+ * PLUNKER VERSION
+ * (based on systemjs.config.js in angular.io)
+ * System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
-(function(global) {
-
- var ngVer = '@2.0.0-rc.5'; // lock in the angular package version; do not let it float to current!
- var routerVer = '@3.0.0-rc.1'; // lock router version
- var formsVer = '@0.3.0'; // lock forms version
- var routerDeprecatedVer = '@2.0.0-rc.2'; // temporarily until we update all the guides
-
- //map tells the System loader where to look for things
- var map = {
- 'app': 'app',
-
- '@angular': 'https://npmcdn.com/@angular', // sufficient if we didn't pin the version
- '@angular/router': 'https://npmcdn.com/@angular/router' + routerVer,
- '@angular/forms': 'https://npmcdn.com/@angular/forms' + formsVer,
- '@angular/router-deprecated': 'https://npmcdn.com/@angular/router-deprecated' + routerDeprecatedVer,
- 'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest
- 'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6',
- 'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js',
- 'typescript': 'https://npmcdn.com/typescript@1.9.0-dev.20160409/lib/typescript.js',
- };
-
- //packages tells the System loader how to load when no filename and/or no extension
- var packages = {
- 'app': { main: 'main.ts', defaultExtension: 'ts' },
- 'rxjs': { defaultExtension: 'js' },
- 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
- };
-
- var ngPackageNames = [
- 'common',
- 'compiler',
- 'core',
- 'http',
- 'platform-browser',
- 'platform-browser-dynamic',
- 'upgrade',
- ];
-
- // Add map entries for each angular package
- // only because we're pinning the version with `ngVer`.
- ngPackageNames.forEach(function(pkgName) {
- map['@angular/'+pkgName] = 'https://npmcdn.com/@angular/' + pkgName + ngVer;
- });
-
- // Add package entries for angular packages
- ngPackageNames.concat(['forms', 'router', 'router-deprecated']).forEach(function(pkgName) {
-
- // Bundled (~40 requests):
- packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
-
- // Individual files (~300 requests):
- //packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
- });
-
- var config = {
+(function (global) {
+ System.config({
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: 'ts',
typescriptOptions: {
@@ -68,10 +16,46 @@
"exports": "ts"
}
},
- map: map,
- packages: packages
- };
+ paths: {
+ // paths serve as alias
+ 'npm:': 'https://unpkg.com/'
+ },
+ // map tells the System loader where to look for things
+ map: {
+ // our app is within the app folder
+ app: 'app',
- System.config(config);
+ // angular bundles
+ '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
+ '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
+ '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
+ '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
+ '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
+ '@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',
+ 'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
+ 'ts': 'npm:plugin-typescript@4.0.10/lib/plugin.js',
+ 'typescript': 'npm:typescript@2.0.2/lib/typescript.js',
+
+ },
+ // packages tells the System loader how to load when no filename and/or no extension
+ packages: {
+ app: {
+ main: './main.ts',
+ defaultExtension: 'ts'
+ },
+ rxjs: {
+ defaultExtension: 'js'
+ },
+ 'angular2-in-memory-web-api': {
+ main: './index.js',
+ defaultExtension: 'js'
+ }
+ }
+ });
})(this);
diff --git a/public/docs/_examples/template-syntax/dart/lib/app_component.dart b/public/docs/_examples/template-syntax/dart/lib/app_component.dart
index 6d9199c175..6a3def5aa4 100644
--- a/public/docs/_examples/template-syntax/dart/lib/app_component.dart
+++ b/public/docs/_examples/template-syntax/dart/lib/app_component.dart
@@ -108,8 +108,7 @@ class AppComponent implements OnInit, AfterViewInit {
bool onSave([UIEvent event = null]) {
HtmlElement el = event?.target;
- var evtMsg =
- event != null ? ' Event target is ${el.innerHtml}.' : '';
+ var evtMsg = event != null ? ' Event target is ${el.innerHtml}.' : '';
alerter('Saved. $evtMsg');
return false;
}
@@ -126,8 +125,12 @@ class AppComponent implements OnInit, AfterViewInit {
}
String getStyles(Element el) {
- var showStyles = setStyles();
- return JSON.encode(showStyles);
+ final style = el.style;
+ final Map styles = {};
+ for (var i = 0; i < style.length; i++) {
+ styles[style.item(i)] = style.getPropertyValue(style.item(i));
+ }
+ return JSON.encode(styles);
}
Map _previousClasses = {};
@@ -140,8 +143,8 @@ class AppComponent implements OnInit, AfterViewInit {
};
// #docregion setClasses
// compensate for DevMode (sigh)
- if (JSON.encode(_previousClasses) ==
- JSON.encode(classes)) return _previousClasses;
+ if (JSON.encode(_previousClasses) == JSON.encode(classes))
+ return _previousClasses;
_previousClasses = classes;
// #enddocregion setClasses
return classes;
@@ -149,8 +152,8 @@ class AppComponent implements OnInit, AfterViewInit {
// #enddocregion setClasses
// #docregion setStyles
- Map setStyles() {
- return {
+ Map setStyles() {
+ return {
'font-style': canSave ? 'italic' : 'normal', // italic
'font-weight': !isUnchanged ? 'bold' : 'normal', // normal
'font-size': isSpecial ? '24px' : '8px' // 24px
@@ -158,8 +161,27 @@ class AppComponent implements OnInit, AfterViewInit {
}
// #enddocregion setStyles
+ // #docregion NgStyle
+ bool isItalic = false;
+ bool isBold = false;
+ String fontSize = 'large';
+
+ Map setStyle() {
+ return {
+ 'font-style': isItalic ? 'italic' : 'normal',
+ 'font-weight': isBold ? 'bold' : 'normal',
+ 'font-size': fontSize
+ };
+ }
+ // #enddocregion NgStyle
+
String title = 'Template Syntax';
+ // #docregion evil-title
+ String evilTitle = 'Template Syntax';
+ // #enddocregion evil-title
+
String toeChoice;
+
String toeChooser(Element picker) {
List choices = picker.children;
for (var i = 0; i < choices.length; i++) {
@@ -187,13 +209,16 @@ class AppComponent implements OnInit, AfterViewInit {
int heroesNoTrackByChangeCount = 0;
int heroesWithTrackByChangeCount = 0;
- @ViewChildren('noTrackBy') QueryList childrenNoTrackBy;
- @ViewChildren('withTrackBy') QueryList childrenWithTrackBy;
+ @ViewChildren('noTrackBy')
+ QueryList childrenNoTrackBy;
+ @ViewChildren('withTrackBy')
+ QueryList childrenWithTrackBy;
void _detectNgForTrackByEffects() {
/// Converts [viewChildren] to a list of [Element].
List _extractChildren(QueryList viewChildren) =>
- viewChildren.toList()[0].nativeElement.children.toList() as List;
+ viewChildren.toList()[0].nativeElement.children.toList()
+ as List;
{
// Updates 'without TrackBy' statistics.
diff --git a/public/docs/_examples/template-syntax/dart/lib/app_component.html b/public/docs/_examples/template-syntax/dart/lib/app_component.html
index c7542c3039..9fd72765ed 100644
--- a/public/docs/_examples/template-syntax/dart/lib/app_component.html
+++ b/public/docs/_examples/template-syntax/dart/lib/app_component.html
@@ -197,13 +197,18 @@ button
-Interpolated:
-Property bound:
+ is the interpolated image.
+ is the property bound image.
-The interpolated title is {{title}}
-
+"{{title}}" is the interpolated title.
+" " is the property bound title.
+
+"{{evilTitle}}" is the interpolated evil title.
+" " is the property bound evil title.
+
+
top
@@ -409,6 +414,18 @@ bindon-ngModel
NgStyle Binding
+
+
+
+
This div is x-large.
diff --git a/public/docs/_examples/template-syntax/dart/pubspec.yaml b/public/docs/_examples/template-syntax/dart/pubspec.yaml
index 92574e0a45..65bea5b496 100644
--- a/public/docs/_examples/template-syntax/dart/pubspec.yaml
+++ b/public/docs/_examples/template-syntax/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/template-syntax/dart/web/assets/images/hero.png b/public/docs/_examples/template-syntax/dart/web/assets/images/hero.png
index b60c3ecc30..2a128ac367 100644
Binary files a/public/docs/_examples/template-syntax/dart/web/assets/images/hero.png and b/public/docs/_examples/template-syntax/dart/web/assets/images/hero.png differ
diff --git a/public/docs/_examples/template-syntax/dart/web/assets/images/ng-logo.png b/public/docs/_examples/template-syntax/dart/web/assets/images/ng-logo.png
index 7929242740..1e488b1a49 100644
Binary files a/public/docs/_examples/template-syntax/dart/web/assets/images/ng-logo.png and b/public/docs/_examples/template-syntax/dart/web/assets/images/ng-logo.png differ
diff --git a/public/docs/_examples/template-syntax/dart/web/assets/images/villain.png b/public/docs/_examples/template-syntax/dart/web/assets/images/villain.png
index d1e71cf00b..26697d1a42 100644
Binary files a/public/docs/_examples/template-syntax/dart/web/assets/images/villain.png and b/public/docs/_examples/template-syntax/dart/web/assets/images/villain.png differ
diff --git a/public/docs/_examples/template-syntax/ts/app/main.ts b/public/docs/_examples/template-syntax/ts/app/main.ts
index 458fd21eb1..6af7a5b2ae 100644
--- a/public/docs/_examples/template-syntax/ts/app/main.ts
+++ b/public/docs/_examples/template-syntax/ts/app/main.ts
@@ -1,5 +1,5 @@
-import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
-browserDynamicPlatform().bootstrapModule(AppModule);
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/template-syntax/ts/images/hero.png b/public/docs/_examples/template-syntax/ts/images/hero.png
index b60c3ecc30..2a128ac367 100644
Binary files a/public/docs/_examples/template-syntax/ts/images/hero.png and b/public/docs/_examples/template-syntax/ts/images/hero.png differ
diff --git a/public/docs/_examples/template-syntax/ts/images/ng-logo.png b/public/docs/_examples/template-syntax/ts/images/ng-logo.png
index 7929242740..1e488b1a49 100644
Binary files a/public/docs/_examples/template-syntax/ts/images/ng-logo.png and b/public/docs/_examples/template-syntax/ts/images/ng-logo.png differ
diff --git a/public/docs/_examples/template-syntax/ts/images/villain.png b/public/docs/_examples/template-syntax/ts/images/villain.png
index d1e71cf00b..26697d1a42 100644
Binary files a/public/docs/_examples/template-syntax/ts/images/villain.png and b/public/docs/_examples/template-syntax/ts/images/villain.png differ
diff --git a/public/docs/_examples/testing/ts/1st-specs.html b/public/docs/_examples/testing/ts/1st-specs.html
new file mode 100644
index 0000000000..098b607f81
--- /dev/null
+++ b/public/docs/_examples/testing/ts/1st-specs.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
1st Specs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/docs/_examples/testing/ts/1st-specs.plnkr.json b/public/docs/_examples/testing/ts/1st-specs.plnkr.json
new file mode 100644
index 0000000000..945ec90060
--- /dev/null
+++ b/public/docs/_examples/testing/ts/1st-specs.plnkr.json
@@ -0,0 +1,12 @@
+{
+ "description": "Testing - 1st.specs",
+ "files":[
+ "browser-test-shim.js",
+ "styles.css",
+
+ "app/1st.spec.ts",
+ "1st-specs.html"
+ ],
+ "main": "1st-specs.html",
+ "tags": ["testing"]
+}
diff --git a/public/docs/_examples/testing/ts/1st.spec.ts b/public/docs/_examples/testing/ts/1st.spec.ts
deleted file mode 100644
index bcac7a1aa7..0000000000
--- a/public/docs/_examples/testing/ts/1st.spec.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// #docplaster
-// #docregion it
- it('true is true', () => expect(true).toEqual(true));
- // #enddocregion it
-
-// #docregion describe
- describe('1st tests', () => {
-
- it('true is true', () => expect(true).toEqual(true));
-
- // #enddocregion describe
- // #docregion another-test
- it('null is not the same thing as undefined',
- () => expect(null).not.toEqual(undefined)
- );
- // #enddocregion another-test
-
- // #docregion describe
-});
-// #enddocregion describe
diff --git a/public/docs/_examples/testing/ts/app-specs.html b/public/docs/_examples/testing/ts/app-specs.html
new file mode 100644
index 0000000000..c41fbf88ea
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app-specs.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
Sample App Specs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/docs/_examples/testing/ts/app-specs.plnkr.json b/public/docs/_examples/testing/ts/app-specs.plnkr.json
new file mode 100644
index 0000000000..afd126bb45
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app-specs.plnkr.json
@@ -0,0 +1,23 @@
+{
+ "description": "Testing - app.specs",
+ "files":[
+ "browser-test-shim.js",
+ "systemjs.config.extras.js",
+ "styles.css",
+
+ "app/**/*.css",
+ "app/**/*.html",
+ "app/**/*.ts",
+ "app/**/*.spec.ts",
+
+ "testing/*.ts",
+
+ "!app/main.ts",
+ "!app/bag/*.*",
+ "!app/1st.spec.ts",
+
+ "app-specs.html"
+ ],
+ "main": "app-specs.html",
+ "tags": ["testing"]
+}
diff --git a/public/docs/_examples/testing/ts/app/1st.spec.ts b/public/docs/_examples/testing/ts/app/1st.spec.ts
new file mode 100644
index 0000000000..63f1ab134c
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/1st.spec.ts
@@ -0,0 +1,5 @@
+// #docplaster
+// #docregion
+describe('1st tests', () => {
+ it('true is true', () => expect(true).toBe(true));
+});
diff --git a/public/docs/_examples/testing/ts/app/about.component.spec.ts b/public/docs/_examples/testing/ts/app/about.component.spec.ts
new file mode 100644
index 0000000000..dbc7361823
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/about.component.spec.ts
@@ -0,0 +1,26 @@
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { AboutComponent } from './about.component';
+import { HighlightDirective } from './shared/highlight.directive';
+
+let fixture: ComponentFixture
;
+
+describe('AboutComponent (highlightDirective)', () => {
+ // #docregion tests
+ beforeEach(() => {
+ fixture = TestBed.configureTestingModule({
+ declarations: [ AboutComponent, HighlightDirective],
+ schemas: [ NO_ERRORS_SCHEMA ]
+ })
+ .createComponent(AboutComponent);
+ fixture.detectChanges(); // initial binding
+ });
+
+ it('should have skyblue ', () => {
+ const de = fixture.debugElement.query(By.css('h2'));
+ expect(de.styles['backgroundColor']).toBe('skyblue');
+ });
+ // #enddocregion tests
+});
diff --git a/public/docs/_examples/testing/ts/app/about.component.ts b/public/docs/_examples/testing/ts/app/about.component.ts
new file mode 100644
index 0000000000..90e7132b4c
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/about.component.ts
@@ -0,0 +1,9 @@
+// #docregion
+import { Component } from '@angular/core';
+@Component({
+ template: `
+ About
+
+ All about this sample
`
+})
+export class AboutComponent { }
diff --git a/public/docs/_examples/testing/ts/app/app-routing.module.ts b/public/docs/_examples/testing/ts/app/app-routing.module.ts
new file mode 100644
index 0000000000..6096a513df
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/app-routing.module.ts
@@ -0,0 +1,16 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { AboutComponent } from './about.component';
+
+@NgModule({
+ imports: [
+ RouterModule.forRoot([
+ { path: '', redirectTo: 'dashboard', pathMatch: 'full'},
+ { path: 'about', component: AboutComponent },
+ { path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule'}
+ ])
+ ],
+ exports: [ RouterModule ] // re-export the module declarations
+})
+export class AppRoutingModule { };
diff --git a/public/docs/_examples/testing/ts/app/app.component.css b/public/docs/_examples/testing/ts/app/app.component.css
deleted file mode 100644
index 137e9be7be..0000000000
--- a/public/docs/_examples/testing/ts/app/app.component.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/* #docplaster */
-/* #docregion css */
-h1 {
- font-size: 1.2em;
- color: #999;
- margin-bottom: 0;
-}
-h2 {
- font-size: 2em;
- margin-top: 0;
- padding-top: 0;
-}
-nav a {
- padding: 5px 10px;
- text-decoration: none;
- margin-top: 10px;
- display: inline-block;
- background-color: #eee;
- border-radius: 4px;
-}
-nav a:visited, a:link {
- color: #607D8B;
-}
-nav a:hover {
- color: #039be5;
- background-color: #CFD8DC;
-}
-nav a.router-link-active {
- color: #039be5;
-}
-/* #enddocregion css */
diff --git a/public/docs/_examples/testing/ts/app/app.component.html b/public/docs/_examples/testing/ts/app/app.component.html
new file mode 100644
index 0000000000..232bcebb6d
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/app.component.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Dashboard
+ Heroes
+ About
+
+
+
diff --git a/public/docs/_examples/testing/ts/app/app.component.router.spec.ts b/public/docs/_examples/testing/ts/app/app.component.router.spec.ts
new file mode 100644
index 0000000000..36e34a983e
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/app.component.router.spec.ts
@@ -0,0 +1,201 @@
+// For more examples:
+// https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts
+
+import { async, ComponentFixture, fakeAsync, TestBed, tick,
+} from '@angular/core/testing';
+
+import { RouterTestingModule } from '@angular/router/testing';
+import { SpyLocation } from '@angular/common/testing';
+
+// tslint:disable:no-unused-variable
+import { newEvent } from '../testing';
+// tslint:enable:no-unused-variable
+
+// r - for relatively obscure router symbols
+import * as r from '@angular/router';
+import { Router, RouterLinkWithHref } from '@angular/router';
+
+import { By } from '@angular/platform-browser';
+import { DebugElement, Type } from '@angular/core';
+import { Location } from '@angular/common';
+
+import { AppModule } from './app.module';
+import { AppComponent } from './app.component';
+import { AboutComponent } from './about.component';
+import { DashboardHeroComponent } from './dashboard/dashboard-hero.component';
+import { TwainService } from './shared/twain.service';
+
+let comp: AppComponent;
+let fixture: ComponentFixture;
+let page: Page;
+let router: Router;
+let location: SpyLocation;
+
+describe('AppComponent & RouterTestingModule', () => {
+
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ imports: [ AppModule, RouterTestingModule ]
+ })
+ .compileComponents();
+ }));
+
+ it('should navigate to "Dashboard" immediately', fakeAsync(() => {
+ createComponent();
+ expect(location.path()).toEqual('/dashboard', 'after initialNavigation()');
+ expectElementOf(DashboardHeroComponent);
+ }));
+
+ it('should navigate to "About" on click', fakeAsync(() => {
+ createComponent();
+ // page.aboutLinkDe.triggerEventHandler('click', null); // fails
+ // page.aboutLinkDe.nativeElement.dispatchEvent(newEvent('click')); // fails
+ page.aboutLinkDe.nativeElement.click(); // fails in phantom
+
+ advance();
+ expectPathToBe('/about');
+ expectElementOf(AboutComponent);
+
+ page.expectEvents([
+ [r.NavigationStart, '/about'], [r.RoutesRecognized, '/about'],
+ [r.NavigationEnd, '/about']
+ ]);
+ }));
+
+ it('should navigate to "About" w/ browser location URL change', fakeAsync(() => {
+ createComponent();
+ location.simulateHashChange('/about');
+ // location.go('/about'); // also works ... except in plunker
+ advance();
+ expectPathToBe('/about');
+ expectElementOf(AboutComponent);
+ }));
+
+ // Can't navigate to lazy loaded modules with this technique
+ xit('should navigate to "Heroes" on click', fakeAsync(() => {
+ createComponent();
+ page.heroesLinkDe.nativeElement.click();
+ advance();
+ expectPathToBe('/heroes');
+ }));
+
+});
+
+
+///////////////
+import { NgModuleFactoryLoader } from '@angular/core';
+import { SpyNgModuleFactoryLoader } from '@angular/router/testing';
+
+import { HeroModule } from './hero/hero.module'; // should be lazy loaded
+import { HeroListComponent } from './hero/hero-list.component';
+
+let loader: SpyNgModuleFactoryLoader;
+
+///////// Can't get lazy loaded Heroes to work yet
+xdescribe('AppComponent & Lazy Loading', () => {
+
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ imports: [ AppModule, RouterTestingModule ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(fakeAsync(() => {
+ createComponent();
+ loader = TestBed.get(NgModuleFactoryLoader);
+ loader.stubbedModules = {expected: HeroModule};
+ router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]);
+ }));
+
+ it('dummy', () => expect(true).toBe(true) );
+
+
+ it('should navigate to "Heroes" on click', async(() => {
+ page.heroesLinkDe.nativeElement.click();
+ advance();
+ expectPathToBe('/heroes');
+ expectElementOf(HeroListComponent);
+ }));
+
+ xit('can navigate to "Heroes" w/ browser location URL change', fakeAsync(() => {
+ location.go('/heroes');
+ advance();
+ expectPathToBe('/heroes');
+ expectElementOf(HeroListComponent);
+
+ page.expectEvents([
+ [r.NavigationStart, '/heroes'], [r.RoutesRecognized, '/heroes'],
+ [r.NavigationEnd, '/heroes']
+ ]);
+ }));
+});
+
+////// Helpers /////////
+
+/** Wait a tick, then detect changes */
+function advance(): void {
+ tick();
+ fixture.detectChanges();
+}
+
+function createComponent() {
+ fixture = TestBed.createComponent(AppComponent);
+ comp = fixture.componentInstance;
+
+ const injector = fixture.debugElement.injector;
+ location = injector.get(Location);
+ router = injector.get(Router);
+ router.initialNavigation();
+ spyOn(injector.get(TwainService), 'getQuote')
+ .and.returnValue(Promise.resolve('Test Quote')); // fakes it
+
+ advance();
+
+ page = new Page();
+}
+
+class Page {
+ aboutLinkDe: DebugElement;
+ dashboardLinkDe: DebugElement;
+ heroesLinkDe: DebugElement;
+ recordedEvents: any[] = [];
+
+ // for debugging
+ comp: AppComponent;
+ location: SpyLocation;
+ router: Router;
+ fixture: ComponentFixture;
+
+ expectEvents(pairs: any[]) {
+ const events = this.recordedEvents;
+ expect(events.length).toEqual(pairs.length, 'actual/expected events length mismatch');
+ for (let i = 0; i < events.length; ++i) {
+ expect((events[i].constructor).name).toBe(pairs[i][0].name, 'unexpected event name');
+ expect((events[i]).url).toBe(pairs[i][1], 'unexpected event url');
+ }
+ }
+
+ constructor() {
+ router.events.forEach(e => this.recordedEvents.push(e));
+ const links = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref));
+ this.aboutLinkDe = links[2];
+ this.dashboardLinkDe = links[0];
+ this.heroesLinkDe = links[1];
+
+ // for debugging
+ this.comp = comp;
+ this.fixture = fixture;
+ this.router = router;
+ }
+}
+
+function expectPathToBe(path: string, expectationFailOutput?: any) {
+ expect(location.path()).toEqual(path, expectationFailOutput || 'location.path()');
+}
+
+function expectElementOf(type: Type): any {
+ const el = fixture.debugElement.query(By.directive(type));
+ expect(el).toBeTruthy('expected an element for ' + type.name);
+ return el;
+}
diff --git a/public/docs/_examples/testing/ts/app/app.component.spec.ts b/public/docs/_examples/testing/ts/app/app.component.spec.ts
index f6c30b0e76..2f10eec6d5 100644
--- a/public/docs/_examples/testing/ts/app/app.component.spec.ts
+++ b/public/docs/_examples/testing/ts/app/app.component.spec.ts
@@ -1,83 +1,148 @@
-/* tslint:disable:no-unused-variable */
-import { AppComponent } from './app.component';
-
-import { By } from '@angular/platform-browser';
-import { DebugElement } from '@angular/core';
-
-import {
- async, inject
+// #docplaster
+import { async, ComponentFixture, TestBed
} from '@angular/core/testing';
-import { ComponentFixture, TestComponentBuilder } from '@angular/core/testing';
+import { DebugElement } from '@angular/core';
+import { By } from '@angular/platform-browser';
-import { Hero, HeroService, MockHeroService } from './mock-hero.service';
+ // #docregion setup-schemas
+ import { NO_ERRORS_SCHEMA } from '@angular/core';
+ // #enddocregion setup-schemas
+ // #docregion setup-stubs-w-imports
+ import { Component } from '@angular/core';
+ // #docregion setup-schemas
+ import { AppComponent } from './app.component';
+ // #enddocregion setup-schemas
+ import { BannerComponent } from './banner.component';
+ import { RouterLinkStubDirective } from '../testing';
+ // #docregion setup-schemas
+ import { RouterOutletStubComponent } from '../testing';
-import { Router, MockRouter,
- RouterLink, MockRouterLink,
- RouterOutlet, MockRouterOutlet } from './mock-router';
+ // #enddocregion setup-schemas
+ @Component({selector: 'app-welcome', template: ''})
+ class WelcomeStubComponent {}
-describe('AppComponent', () => {
- let fixture: ComponentFixture;
- let comp: AppComponent;
+ // #enddocregion setup-stubs-w-imports
- beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
- tcb
- .overrideDirective(AppComponent, RouterLink, MockRouterLink)
- .overrideDirective(AppComponent, RouterOutlet, MockRouterOutlet)
- .overrideProviders(AppComponent, [
- { provide: HeroService, useClass: MockHeroService},
- { provide: Router, useClass: MockRouter},
- ])
- .createAsync(AppComponent)
- .then(fix => {
- fixture = fix;
- comp = fixture.debugElement.componentInstance;
- });
- })));
+let comp: AppComponent;
+let fixture: ComponentFixture;
+
+describe('AppComponent & TestModule', () => {
+ // #docregion setup-stubs, setup-stubs-w-imports
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ declarations: [
+ AppComponent,
+ BannerComponent, WelcomeStubComponent,
+ RouterLinkStubDirective, RouterOutletStubComponent
+ ]
+ })
+
+ .compileComponents()
+ .then(() => {
+ fixture = TestBed.createComponent(AppComponent);
+ comp = fixture.componentInstance;
+ });
+ }));
+ // #enddocregion setup-stubs, setup-stubs-w-imports
+ tests();
+});
+
+//////// Testing w/ NO_ERRORS_SCHEMA //////
+describe('AppComponent & NO_ERRORS_SCHEMA', () => {
+ // #docregion setup-schemas
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AppComponent, RouterLinkStubDirective ],
+ schemas: [ NO_ERRORS_SCHEMA ]
+ })
+
+ .compileComponents()
+ .then(() => {
+ fixture = TestBed.createComponent(AppComponent);
+ comp = fixture.componentInstance;
+ });
+ }));
+ // #enddocregion setup-schemas
+ tests();
+});
+
+//////// Testing w/ real root module //////
+// Tricky because we are disabling the router and its configuration
+// Better to use RouterTestingModule
+import { AppModule } from './app.module';
+import { AppRoutingModule } from './app-routing.module';
+
+describe('AppComponent & AppModule', () => {
+
+ beforeEach( async(() => {
+
+ TestBed.configureTestingModule({
+ imports: [ AppModule ]
+ })
+
+ // Get rid of app's Router configuration otherwise many failures.
+ // Doing so removes Router declarations; add the Router stubs
+ .overrideModule(AppModule, {
+ remove: {
+ imports: [ AppRoutingModule ]
+ },
+ add: {
+ declarations: [ RouterLinkStubDirective, RouterOutletStubComponent ]
+ }
+ })
+
+ .compileComponents()
+
+ .then(() => {
+ fixture = TestBed.createComponent(AppComponent);
+ comp = fixture.componentInstance;
+ });
+ }));
+
+ tests();
+});
+
+function tests() {
+ let links: RouterLinkStubDirective[];
+ let linkDes: DebugElement[];
+
+ // #docregion test-setup
+ beforeEach(() => {
+ // trigger initial data binding
+ fixture.detectChanges();
+
+ // find DebugElements with an attached RouterLinkStubDirective
+ linkDes = fixture.debugElement
+ .queryAll(By.directive(RouterLinkStubDirective));
+
+ // get the attached link directive instances using the DebugElement injectors
+ links = linkDes
+ .map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective);
+ });
+ // #enddocregion test-setup
it('can instantiate it', () => {
expect(comp).not.toBeNull();
});
- it('can get title from template', () => {
- fixture.detectChanges();
- let titleEl = fixture.debugElement.query(By.css('h1')).nativeElement;
- expect(titleEl.textContent).toContain(comp.title);
- });
-
+ // #docregion tests
it('can get RouterLinks from template', () => {
- fixture.detectChanges();
-
- let links = fixture.debugElement
- .queryAll(By.directive(MockRouterLink))
- .map(de => de.injector.get(MockRouterLink) );
-
- expect(links.length).toEqual(2, 'should have 2 links');
- expect(links[0].routeParams[0]).toEqual('Dashboard', '1st link should go to Dashboard');
- expect(links[1].routeParams[0]).toEqual('Heroes', '1st link should go to Heroes');
-
- let result = links[1].onClick();
- expect(result).toEqual(false, 'click should prevent default browser behavior');
+ expect(links.length).toBe(3, 'should have 3 links');
+ expect(links[0].linkParams).toBe('/dashboard', '1st link should go to Dashboard');
+ expect(links[1].linkParams).toBe('/heroes', '1st link should go to Heroes');
});
it('can click Heroes link in template', () => {
+ const heroesLinkDe = linkDes[1];
+ const heroesLink = links[1];
+
+ expect(heroesLink.navigatedTo).toBeNull('link should not have navigated yet');
+
+ heroesLinkDe.triggerEventHandler('click', null);
fixture.detectChanges();
- // Heroes RouterLink DebugElement
- let heroesDe = fixture.debugElement
- .queryAll(By.directive(MockRouterLink))[1];
-
- expect(heroesDe).toBeDefined('should have a 2nd RouterLink');
-
- let link = heroesDe.injector.get(MockRouterLink);
-
- expect(link.navigatedTo).toBeNull('link should not have navigate yet');
-
- heroesDe.triggerEventHandler('click', null);
-
- fixture.detectChanges();
- expect(link.navigatedTo[0]).toEqual('Heroes');
-
+ expect(heroesLink.navigatedTo).toBe('/heroes');
});
-});
-
+ // #docregion tests
+}
diff --git a/public/docs/_examples/testing/ts/app/app.component.ts b/public/docs/_examples/testing/ts/app/app.component.ts
index f2da2da067..9b785144ab 100644
--- a/public/docs/_examples/testing/ts/app/app.component.ts
+++ b/public/docs/_examples/testing/ts/app/app.component.ts
@@ -1,53 +1,7 @@
-// #docplaster
// #docregion
import { Component } from '@angular/core';
-
-// Can't test with ROUTER_DIRECTIVES yet
-// import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
-
-import { RouteConfig, RouterLink,
- RouterOutlet, ROUTER_PROVIDERS } from '@angular/router-deprecated';
-
-import { DashboardComponent } from './dashboard.component';
-import { HeroesComponent } from './heroes.component';
-import { HeroDetailComponent } from './hero-detail.component';
-import { HeroService } from './hero.service';
-
-import { BAG_DIRECTIVES, BAG_PROVIDERS } from './bag';
-
@Component({
selector: 'my-app',
- template: `
- {{title}}
-
- Dashboard
- Heroes
-
-
-
- Bag-a-specs
-
- External Template Comp
-
- Comp With External Template Comp
-
- `,
- /*
-
- */
- styleUrls: ['app/app.component.css'],
- directives: [RouterLink, RouterOutlet, BAG_DIRECTIVES],
- providers: [
- ROUTER_PROVIDERS,
- HeroService,
- BAG_PROVIDERS
- ]
+ templateUrl: 'app/app.component.html'
})
-@RouteConfig([
- { path: '/dashboard', name: 'Dashboard', component: DashboardComponent, useAsDefault: true },
- { path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent },
- { path: '/heroes', name: 'Heroes', component: HeroesComponent }
-])
-export class AppComponent {
- title = 'Tour of Heroes';
-}
+export class AppComponent { }
diff --git a/public/docs/_examples/testing/ts/app/app.module.ts b/public/docs/_examples/testing/ts/app/app.module.ts
new file mode 100644
index 0000000000..d3c288ad11
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/app.module.ts
@@ -0,0 +1,29 @@
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+
+import { AppComponent } from './app.component';
+import { AppRoutingModule } from './app-routing.module';
+
+import { AboutComponent } from './about.component';
+import { BannerComponent } from './banner.component';
+import { HeroService,
+ UserService } from './model';
+import { TwainService } from './shared/twain.service';
+import { WelcomeComponent } from './welcome.component';
+
+
+import { DashboardModule } from './dashboard/dashboard.module';
+import { SharedModule } from './shared/shared.module';
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ DashboardModule,
+ AppRoutingModule,
+ SharedModule
+ ],
+ providers: [ HeroService, TwainService, UserService ],
+ declarations: [ AppComponent, AboutComponent, BannerComponent, WelcomeComponent ],
+ bootstrap: [ AppComponent ]
+})
+export class AppModule { }
diff --git a/public/docs/_examples/testing/ts/app/bad-tests.spec.ts b/public/docs/_examples/testing/ts/app/bad-tests.spec.ts
deleted file mode 100644
index d73882372c..0000000000
--- a/public/docs/_examples/testing/ts/app/bad-tests.spec.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
-/* tslint:disable:no-unused-variable */
-/**
- * Tests that show what goes wrong when the tests are incorrectly written or have a problem
- */
-import {
- BadTemplateUrlComp, ButtonComp,
- ChildChildComp, ChildComp, ChildWithChildComp,
- ExternalTemplateComp,
- FancyService, MockFancyService,
- InputComp,
- MyIfComp, MyIfChildComp, MyIfParentComp,
- MockChildComp, MockChildChildComp,
- ParentComp,
- TestProvidersComp, TestViewProvidersComp
-} from './bag';
-
-import { DebugElement } from '@angular/core';
-import { By } from '@angular/platform-browser';
-
-import {
- addProviders,
- async, inject
-} from '@angular/core/testing';
-
-import { ComponentFixture, TestComponentBuilder } from '@angular/core/testing';
-
-import { ViewMetadata } from '@angular/core';
-import { Observable } from 'rxjs/Rx';
-
-//////// SPECS /////////////
-
-xdescribe('async & inject testing errors', () => {
- let originalJasmineIt: any;
- let originalJasmineBeforeEach: any;
-
- let patchJasmineIt = () => {
- return new Promise((resolve, reject) => {
- originalJasmineIt = jasmine.getEnv().it;
- jasmine.getEnv().it = (description: string, fn: Function): jasmine.Spec => {
- let done = () => { resolve(); };
- (done).fail = (err: any) => { reject(err); };
- fn(done);
- return null;
- };
- });
- };
-
- let restoreJasmineIt = () => { jasmine.getEnv().it = originalJasmineIt; };
-
- let patchJasmineBeforeEach = () => {
- return new Promise((resolve, reject) => {
- originalJasmineBeforeEach = jasmine.getEnv().beforeEach;
- jasmine.getEnv().beforeEach = (fn: any): void => {
- let done = () => { resolve(); };
- (done).fail = (err: any) => { reject(err); };
- fn(done);
- return null;
- };
- });
- };
-
- let restoreJasmineBeforeEach =
- () => { jasmine.getEnv().beforeEach = originalJasmineBeforeEach; };
-
- const shouldNotSucceed =
- (done: DoneFn) => () => done.fail( 'Expected an error, but did not get one.');
-
- const shouldFail =
- (done: DoneFn, emsg: string) => (err: any) => { expect(err).toEqual(emsg); done(); };
-
- it('should fail when an asynchronous error is thrown', (done: DoneFn) => {
- let itPromise = patchJasmineIt();
-
- it('throws an async error',
- async(inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); })));
-
- itPromise.then(
- shouldNotSucceed(done),
- err => {
- expect(err).toEqual('bar');
- done();
- });
- restoreJasmineIt();
- });
-
- it('should fail when a returned promise is rejected', (done: DoneFn) => {
- let itPromise = patchJasmineIt();
-
- it('should fail with an error from a promise', async(() => {
- return Promise.reject('baz');
- }));
-
- itPromise.then(
- shouldNotSucceed(done),
- err => {
- expect(err).toEqual('Uncaught (in promise): baz');
- done();
- });
- restoreJasmineIt();
- });
-
- it('should fail when an error occurs inside inject', (done: DoneFn) => {
- let itPromise = patchJasmineIt();
-
- it('throws an error', inject([], () => { throw new Error('foo'); }));
-
- itPromise.then(
- shouldNotSucceed(done),
- shouldFail(done, 'foo')
- );
- restoreJasmineIt();
- });
-
- // TODO(juliemr): reenable this test when we are using a test zone and can capture this error.
- it('should fail when an asynchronous error is thrown', (done: DoneFn) => {
- let itPromise = patchJasmineIt();
-
- it('throws an async error',
- async(inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); })));
-
- itPromise.then(
- shouldNotSucceed(done),
- shouldFail(done, 'bar')
- );
- restoreJasmineIt();
- });
-
- it('should fail when XHR loading of a template fails', (done: DoneFn) => {
- let itPromise = patchJasmineIt();
-
- it('should fail with an error from a promise',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
- tcb.createAsync(BadTemplateUrlComp);
- })));
-
- itPromise.then(
- shouldNotSucceed(done),
- shouldFail(done, 'Uncaught (in promise): Failed to load non-existant.html')
- );
- restoreJasmineIt();
- }, 10000);
-
- describe('using addProviders', () => {
- addProviders([{ provide: FancyService, useValue: new FancyService() }]);
-
- beforeEach(
- inject([FancyService], (service: FancyService) => { expect(service.value).toEqual('real value'); }));
-
- describe('nested addProviders', () => {
-
- it('should fail when the injector has already been used', () => {
- patchJasmineBeforeEach();
- expect(() => {
- addProviders([{ provide: FancyService, useValue: new FancyService() }]);
- })
- .toThrowError('addProviders was called after the injector had been used ' +
- 'in a beforeEach or it block. This invalidates the test injector');
- restoreJasmineBeforeEach();
- });
- });
- });
-});
diff --git a/public/docs/_examples/testing/ts/app/bag.spec.ts b/public/docs/_examples/testing/ts/app/bag.spec.ts
deleted file mode 100644
index 7218e91f1b..0000000000
--- a/public/docs/_examples/testing/ts/app/bag.spec.ts
+++ /dev/null
@@ -1,460 +0,0 @@
-// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
-/* tslint:disable */
-import {
- ButtonComp,
- ChildChildComp, ChildComp, ChildWithChildComp,
- ExternalTemplateComp,
- FancyService, MockFancyService,
- InputComp,
- MyIfComp, MyIfChildComp, MyIfParentComp,
- MockChildComp, MockChildChildComp,
- ParentComp,
- TestProvidersComp, TestViewProvidersComp
-} from './bag';
-
-import { DebugElement } from '@angular/core';
-import { By } from '@angular/platform-browser';
-
-import {
- addProviders,
- inject, async,
- fakeAsync, tick, withProviders
-} from '@angular/core/testing';
-
-import { ComponentFixture, TestComponentBuilder } from '@angular/core/testing';
-
-import { ViewMetadata } from '@angular/core';
-
-import { Observable } from 'rxjs/Rx';
-
-//////// SPECS /////////////
-
-describe('using the async helper', () => {
- let actuallyDone = false;
-
- beforeEach(() => { actuallyDone = false; });
-
- afterEach(() => { expect(actuallyDone).toEqual(true); });
-
- it('should run normal test', () => { actuallyDone = true; });
-
- it('should run normal async test', (done: DoneFn) => {
- setTimeout(() => {
- actuallyDone = true;
- done();
- }, 0);
- });
-
- it('should run async test with task',
- async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
-
- it('should run async test with successful promise', async(() => {
- let p = new Promise(resolve => { setTimeout(resolve, 10); });
- p.then(() => { actuallyDone = true; });
- }));
-
- it('should run async test with failed promise', async(() => {
- let p = new Promise((resolve, reject) => { setTimeout(reject, 10); });
- p.catch(() => { actuallyDone = true; });
- }));
-
- xit('should run async test with successful Observable', async(() => {
- let source = Observable.of(true).delay(10);
- source.subscribe(
- val => {},
- err => fail(err),
- () => { actuallyDone = true; } // completed
- );
- }));
-});
-
-describe('using the test injector with the inject helper', () => {
-
- describe('setting up Providers with FancyService', () => {
- beforeEach(() => {
- addProviders([
- { provide: FancyService, useValue: new FancyService() }
- ]);
- });
-
- it('should use FancyService',
- inject([FancyService], (service: FancyService) => {
- expect(service.value).toEqual('real value');
- }));
-
- it('test should wait for FancyService.getAsyncValue',
- async(inject([FancyService], (service: FancyService) => {
- service.getAsyncValue().then(
- value => { expect(value).toEqual('async value'); });
- })));
-
- it('test should wait for FancyService.getTimeoutValue',
- async(inject([FancyService], (service: FancyService) => {
- service.getTimeoutValue().then(
- value => { expect(value).toEqual('timeout value'); });
- })));
-
- it('test should wait for FancyService.getObservableValue',
- async(inject([FancyService], (service: FancyService) => {
- service.getObservableValue().subscribe(
- value => { expect(value).toEqual('observable value'); }
- );
- })));
-
- xit('test should wait for FancyService.getObservableDelayValue',
- async(inject([FancyService], (service: FancyService) => {
- service.getObservableDelayValue().subscribe(
- value => { expect(value).toEqual('observable delay value'); }
- );
- })));
-
- it('should allow the use of fakeAsync (Experimental)',
- fakeAsync(inject([FancyService], (service: FancyService) => {
- let value: any;
- service.getAsyncValue().then((val: any) => value = val);
- tick(); // Trigger JS engine cycle until all promises resolve.
- expect(value).toEqual('async value');
- })));
-
- describe('using inner beforeEach to inject-and-modify FancyService', () => {
- beforeEach(inject([FancyService], (service: FancyService) => {
- service.value = 'value modified in beforeEach';
- }));
-
- it('should use modified providers',
- inject([FancyService], (service: FancyService) => {
- expect(service.value).toEqual('value modified in beforeEach');
- }));
- });
-
- describe('using async within beforeEach', () => {
- beforeEach(async(inject([FancyService], (service: FancyService) => {
- service.getAsyncValue().then(value => { service.value = value; });
- })));
-
- it('should use asynchronously modified value ... in synchronous test',
- inject([FancyService], (service: FancyService) => {
- expect(service.value).toEqual('async value'); }));
- });
- });
-
- describe('using `withProviders` for per-test provision', () => {
- it('should inject test-local FancyService for this test',
- // `withProviders`: set up providers at individual test level
- withProviders(() => [{ provide: FancyService, useValue: {value: 'fake value' }}])
-
- // now inject and test
- .inject([FancyService], (service: FancyService) => {
- expect(service.value).toEqual('fake value');
- }));
- });
-});
-
-describe('test component builder', function() {
- it('should instantiate a component with valid DOM',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.createAsync(ChildComp).then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent).toContain('Original Child');
- });
- })));
-
- it('should allow changing members of the component',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.createAsync(MyIfComp).then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent).toContain('MyIf()');
-
- fixture.debugElement.componentInstance.showMore = true;
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent).toContain('MyIf(More)');
- });
- })));
-
- it('should support clicking a button',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.createAsync(ButtonComp).then(fixture => {
-
- let comp = fixture.componentInstance;
- expect(comp.wasClicked).toEqual(false, 'wasClicked should be false at start');
-
- let btn = fixture.debugElement.query(By.css('button'));
- // let btn = fixture.debugElement.query(el => el.name === 'button'); // the hard way
-
- btn.triggerEventHandler('click', null);
- // btn.nativeElement.click(); // this often works too ... but not all the time!
- expect(comp.wasClicked).toEqual(true, 'wasClicked should be true after click');
- });
- })));
-
- it('should support entering text in input box (ngModel)',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
- let origName = 'John';
- let newName = 'Sally';
-
- tcb.createAsync(InputComp).then(fixture => {
-
- let comp = fixture.componentInstance;
- expect(comp.name).toEqual(origName, `At start name should be ${origName} `);
-
- let inputBox = fixture.debugElement.query(By.css('input')).nativeElement;
- fixture.detectChanges();
- expect(inputBox.value).toEqual(origName, `At start input box value should be ${origName} `);
-
- inputBox.value = newName;
- expect(comp.name).toEqual(origName,
- `Name should still be ${origName} after value change, before detectChanges`);
-
- fixture.detectChanges();
- expect(inputBox.value).toEqual(newName,
- `After value change and detectChanges, name should now be ${newName} `);
- });
- })));
-
- it('should override a template',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.overrideTemplate(MockChildComp, 'Mock ')
- .createAsync(MockChildComp)
- .then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent).toContain('Mock');
- });
- })));
-
- it('should override a view',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.overrideView(
- ChildComp,
- new ViewMetadata({template: 'Modified {{childBinding}} '})
- )
- .createAsync(ChildComp)
- .then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent).toContain('Modified Child');
-
- });
- })));
-
- it('should override component directives',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.overrideDirective(ParentComp, ChildComp, MockChildComp)
- .createAsync(ParentComp)
- .then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent).toContain('Parent(Mock)');
-
- });
- })));
-
-
- it('should override child component\'s directives',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.overrideDirective(ParentComp, ChildComp, ChildWithChildComp)
- .overrideDirective(ChildWithChildComp, ChildChildComp, MockChildChildComp)
- .createAsync(ParentComp)
- .then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent)
- .toContain('Parent(Original Child(ChildChild Mock))');
-
- });
- })));
-
- it('should override a provider',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.overrideProviders(
- TestProvidersComp,
- [{ provide: FancyService, useClass: MockFancyService }]
- )
- .createAsync(TestProvidersComp)
- .then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent)
- .toContain('injected value: mocked out value');
- });
- })));
-
- it('should override a viewProvider',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.overrideViewProviders(
- TestViewProvidersComp,
- [{ provide: FancyService, useClass: MockFancyService }]
- )
- .createAsync(TestViewProvidersComp)
- .then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent)
- .toContain('injected value: mocked out value');
- });
- })));
-
- it('should allow an external templateUrl',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.createAsync(ExternalTemplateComp)
- .then(fixture => {
- fixture.detectChanges();
- expect(fixture.nativeElement.textContent)
- .toContain('from external template\n');
- });
- })), 10000); // Long timeout because this test makes an actual XHR.
-
- describe('(lifecycle hooks w/ MyIfParentComp)', () => {
- let fixture: ComponentFixture;
- let parent: MyIfParentComp;
- let child: MyIfChildComp;
-
- /**
- * Get the MyIfChildComp from parent; fail w/ good message if cannot.
- */
- function getChild() {
-
- let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp
-
- // The Hard Way: requires detailed knowledge of the parent template
- try {
- childDe = fixture.debugElement.children[4].children[0];
- } catch (err) { /* we'll report the error */ }
-
- // DebugElement.queryAll: if we wanted all of many instances:
- childDe = fixture.debugElement
- .queryAll(function (de) { return de.componentInstance instanceof MyIfChildComp; })[0];
-
- // WE'LL USE THIS APPROACH !
- // DebugElement.query: find first instance (if any)
- childDe = fixture.debugElement
- .query(function (de) { return de.componentInstance instanceof MyIfChildComp; });
-
- if (childDe && childDe.componentInstance) {
- child = childDe.componentInstance;
- } else {
- fail('Unable to find MyIfChildComp within MyIfParentComp');
- }
-
- return child;
- }
-
- // Create MyIfParentComp TCB and component instance before each test (async beforeEach)
- beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
- tcb.createAsync(MyIfParentComp)
- .then(fix => {
- fixture = fix;
- parent = fixture.debugElement.componentInstance;
- });
- })));
-
- it('should instantiate parent component', () => {
- expect(parent).not.toBeNull('parent component should exist');
- });
-
- it('parent component OnInit should NOT be called before first detectChanges()', () => {
- expect(parent.ngOnInitCalled).toEqual(false);
- });
-
- it('parent component OnInit should be called after first detectChanges()', () => {
- fixture.detectChanges();
- expect(parent.ngOnInitCalled).toEqual(true);
- });
-
- it('child component should exist after OnInit', () => {
- fixture.detectChanges();
- getChild();
- expect(child instanceof MyIfChildComp).toEqual(true, 'should create child');
- });
-
- it('should have called child component\'s OnInit ', () => {
- fixture.detectChanges();
- getChild();
- expect(child.ngOnInitCalled).toEqual(true);
- });
-
- it('child component called OnChanges once', () => {
- fixture.detectChanges();
- getChild();
- expect(child.ngOnChangesCounter).toEqual(1);
- });
-
- it('changed parent value flows to child', () => {
- fixture.detectChanges();
- getChild();
-
- parent.parentValue = 'foo';
- fixture.detectChanges();
-
- expect(child.ngOnChangesCounter).toEqual(2,
- 'expected 2 changes: initial value and changed value');
- expect(child.childValue).toEqual('foo',
- 'childValue should eq changed parent value');
- });
-
- it('changed child value flows to parent', async(() => {
- fixture.detectChanges();
- getChild();
-
- child.childValue = 'bar';
-
- return new Promise(resolve => {
- // Wait one JS engine turn!
- setTimeout(() => resolve(), 0);
- }).then(() => {
- fixture.detectChanges();
-
- expect(child.ngOnChangesCounter).toEqual(2,
- 'expected 2 changes: initial value and changed value');
- expect(parent.parentValue).toEqual('bar',
- 'parentValue should eq changed parent value');
- });
-
- }));
-
- it('clicking "Close Child" triggers child OnDestroy', () => {
- fixture.detectChanges();
- getChild();
-
- let btn = fixture.debugElement.query(By.css('button'));
- btn.triggerEventHandler('click', null);
-
- fixture.detectChanges();
- expect(child.ngOnDestroyCalled).toEqual(true);
- });
-
- });
-});
-
-
-//////// Testing Framework Bugs? /////
-import { HeroService } from './hero.service';
-import { Component } from '@angular/core';
-
-@Component({
- selector: 'another-comp',
- template: `AnotherProvidersComp()`,
- providers: [FancyService] // <======= BOOM! if we comment out
- // Failed: 'undefined' is not an object (evaluating 'dm.providers.concat')
-})
-export class AnotherProvidersComp {
- constructor(
- private _heroService: HeroService
- ) { }
-}
-
-describe('tcb.overrideProviders', () => {
- it('Component must have at least one provider else crash',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.overrideProviders(
- AnotherProvidersComp,
- [{ provide: HeroService, useValue: {}} ]
- )
- .createAsync(AnotherProvidersComp);
- })));
-});
diff --git a/public/docs/_examples/testing/ts/app/bag.ts b/public/docs/_examples/testing/ts/app/bag.ts
deleted file mode 100644
index 26f47e8b3d..0000000000
--- a/public/docs/_examples/testing/ts/app/bag.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
-/* tslint:disable */
-import { Component, EventEmitter, Injectable, Input, Output, Optional,
- OnInit, OnChanges, OnDestroy, SimpleChange } from '@angular/core';
-
-import { Observable } from 'rxjs/Rx';
-
-////////// The App: Services and Components for the tests. //////////////
-
-////////// Services ///////////////
-
-@Injectable()
-export class FancyService {
- value: string = 'real value';
-
- getValue() { return this.value; }
-
- getAsyncValue() { return Promise.resolve('async value'); }
-
- getObservableValue() { return Observable.of('observable value'); }
-
- getTimeoutValue() {
- return new Promise((resolve, reject) => { setTimeout(() => {resolve('timeout value'); }, 10); });
- }
-
- getObservableDelayValue() { return Observable.of('observable delay value').delay(10); }
-}
-
-@Injectable()
-export class MockFancyService extends FancyService {
- value: string = 'mocked out value';
-}
-
-//////////// Components /////////////
-
-@Component({
- selector: 'button-comp',
- template: `Click me! `
-})
-export class ButtonComp {
- wasClicked = false;
- clicked() { this.wasClicked = true; }
-}
-
-@Component({
- selector: 'input-comp',
- template: ` `
-})
-export class InputComp {
- name = 'John';
-}
-
-@Component({
- selector: 'child-comp',
- template: `Original {{childBinding}} `
-})
-export class ChildComp {
- childBinding = 'Child';
-}
-
-
-@Component({
- selector: 'child-comp',
- template: `Mock `
-})
-export class MockChildComp { }
-
-
-@Component({
- selector: 'parent-comp',
- template: `Parent( )`,
- directives: [ChildComp]
-})
-export class ParentComp { }
-
-
-@Component({
- selector: 'my-if-comp',
- template: `MyIf(More )`
-})
-export class MyIfComp {
- showMore = false;
-}
-
-@Component({
- selector: 'child-child-comp',
- template: 'ChildChild '
-})
-export class ChildChildComp { }
-
-
-@Component({
- selector: 'child-comp',
- template: `Original {{childBinding}}( ) `,
- directives: [ChildChildComp]
-})
-export class ChildWithChildComp {
- childBinding = 'Child';
-}
-
-
-@Component({
- selector: 'child-child-comp',
- template: `ChildChild Mock `
-})
-export class MockChildChildComp { }
-
-
-@Component({
- selector: 'my-service-comp',
- template: `injected value: {{fancyService.value}}`,
- providers: [FancyService]
-})
-export class TestProvidersComp {
- constructor(private fancyService: FancyService) {}
-}
-
-
-@Component({
- selector: 'my-service-comp',
- template: `injected value: {{fancyService.value}}`,
- viewProviders: [FancyService]
-})
-export class TestViewProvidersComp {
- constructor(private fancyService: FancyService) {}
-}
-
-@Component({
- moduleId: module.id,
- selector: 'external-template-comp',
- templateUrl: 'bag-external-template.html'
-})
-export class ExternalTemplateComp {
- serviceValue: string;
-
- constructor(@Optional() private service: FancyService) { }
-
- ngOnInit() {
- if (this.service) { this.serviceValue = this.service.getValue(); }
- }
-}
-
-@Component({
- selector: 'comp-w-ext-comp',
- template: `
- comp-w-ext-comp
-
- `,
- directives: [ExternalTemplateComp]
-})
-export class CompWithCompWithExternalTemplate { }
-
-@Component({
- selector: 'bad-template-comp',
- templateUrl: 'non-existant.html'
-})
-export class BadTemplateUrlComp { }
-
-
-///////// MyIfChildComp ////////
-@Component({
- selector: 'my-if-child-comp',
-
- template: `
- MyIfChildComp
-
- Child value:
-
- Change log:
- {{i + 1}} - {{log}}
`
-})
-export class MyIfChildComp implements OnInit, OnChanges, OnDestroy {
- @Input() value = '';
- @Output() valueChange = new EventEmitter();
-
- get childValue() { return this.value; }
- set childValue(v: string) {
- if (this.value === v) { return; }
- this.value = v;
- this.valueChange.emit(v);
- }
-
- changeLog: string[] = [];
-
- ngOnInitCalled = false;
- ngOnChangesCounter = 0;
- ngOnDestroyCalled = false;
-
- ngOnInit() {
- this.ngOnInitCalled = true;
- this.changeLog.push('ngOnInit called');
- }
-
- ngOnDestroy() {
- this.ngOnDestroyCalled = true;
- this.changeLog.push('ngOnDestroy called');
- }
-
- ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
- for (let propName in changes) {
- this.ngOnChangesCounter += 1;
- let prop = changes[propName];
- let cur = JSON.stringify(prop.currentValue);
- let prev = JSON.stringify(prop.previousValue);
- this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
- }
- }
-}
-
-///////// MyIfParentComp ////////
-
-@Component({
- selector: 'my-if-parent-comp',
- template: `
- MyIfParentComp
- Parent value:
-
-
- {{toggleLabel}} Child
-
-
-
- `,
- directives: [MyIfChildComp]
-})
-export class MyIfParentComp implements OnInit {
- ngOnInitCalled = false;
- parentValue = 'Hello, World';
- showChild = false;
- toggleLabel = 'Unknown';
-
- ngOnInit() {
- this.ngOnInitCalled = true;
- this.clicked();
- }
-
- clicked() {
- this.showChild = !this.showChild;
- this.toggleLabel = this.showChild ? 'Close' : 'Show';
- }
-}
-
-export const BAG_PROVIDERS = [FancyService];
-
-export const BAG_DIRECTIVES = [
- ButtonComp,
- ChildChildComp, ChildComp, ChildWithChildComp,
- ExternalTemplateComp, CompWithCompWithExternalTemplate,
- InputComp,
- MyIfComp, MyIfChildComp, MyIfParentComp,
- MockChildComp, MockChildChildComp,
- ParentComp,
- TestProvidersComp, TestViewProvidersComp
-];
diff --git a/public/docs/_examples/testing/ts/app/bag/async-helper.spec.ts b/public/docs/_examples/testing/ts/app/bag/async-helper.spec.ts
new file mode 100644
index 0000000000..90ed17e92b
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/bag/async-helper.spec.ts
@@ -0,0 +1,56 @@
+import { async, fakeAsync, tick } from '@angular/core/testing';
+
+import { Observable } from 'rxjs/Observable';
+
+describe('Angular async helper', () => {
+ let actuallyDone = false;
+
+ beforeEach(() => { actuallyDone = false; });
+
+ afterEach(() => { expect(actuallyDone).toBe(true, 'actuallyDone should be true'); });
+
+ it('should run normal test', () => { actuallyDone = true; });
+
+ it('should run normal async test', (done: DoneFn) => {
+ setTimeout(() => {
+ actuallyDone = true;
+ done();
+ }, 0);
+ });
+
+ it('should run async test with task',
+ async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
+
+ it('should run async test with successful promise', async(() => {
+ const p = new Promise(resolve => { setTimeout(resolve, 10); });
+ p.then(() => { actuallyDone = true; });
+ }));
+
+ it('should run async test with failed promise', async(() => {
+ const p = new Promise((resolve, reject) => { setTimeout(reject, 10); });
+ p.catch(() => { actuallyDone = true; });
+ }));
+
+ // Fail message: Cannot use setInterval from within an async zone test
+ // See https://github.com/angular/angular/issues/10127
+ xit('should run async test with successful delayed Observable', async(() => {
+ const source = Observable.of(true).delay(10);
+ source.subscribe(
+ val => actuallyDone = true,
+ err => fail(err)
+ );
+ }));
+
+ // Fail message: Error: 1 periodic timer(s) still in the queue
+ // See https://github.com/angular/angular/issues/10127
+ xit('should run async test with successful delayed Observable', fakeAsync(() => {
+ const source = Observable.of(true).delay(10);
+ source.subscribe(
+ val => actuallyDone = true,
+ err => fail(err)
+ );
+
+ tick();
+ }));
+
+});
diff --git a/public/docs/_examples/testing/ts/app/bag-external-template.html b/public/docs/_examples/testing/ts/app/bag/bag-external-template.html
similarity index 100%
rename from public/docs/_examples/testing/ts/app/bag-external-template.html
rename to public/docs/_examples/testing/ts/app/bag/bag-external-template.html
diff --git a/public/docs/_examples/testing/ts/app/bag/bag-main.ts b/public/docs/_examples/testing/ts/app/bag/bag-main.ts
new file mode 100644
index 0000000000..27b78200ae
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/bag/bag-main.ts
@@ -0,0 +1,5 @@
+// main app entry point
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { BagModule } from './bag';
+
+platformBrowserDynamic().bootstrapModule(BagModule);
diff --git a/public/docs/_examples/testing/ts/app/bag/bag.no-testbed.spec.ts b/public/docs/_examples/testing/ts/app/bag/bag.no-testbed.spec.ts
new file mode 100644
index 0000000000..6bdbe86cd0
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/bag/bag.no-testbed.spec.ts
@@ -0,0 +1,130 @@
+// #docplaster
+import { DependentService, FancyService } from './bag';
+
+///////// Fakes /////////
+export class FakeFancyService extends FancyService {
+ value: string = 'faked value';
+}
+////////////////////////
+// #docregion FancyService
+// Straight Jasmine - no imports from Angular test libraries
+
+describe('FancyService without the TestBed', () => {
+ let service: FancyService;
+
+ beforeEach(() => { service = new FancyService(); });
+
+ it('#getValue should return real value', () => {
+ expect(service.getValue()).toBe('real value');
+ });
+
+ it('#getAsyncValue should return async value', done => {
+ service.getAsyncValue().then(value => {
+ expect(value).toBe('async value');
+ done();
+ });
+ });
+
+ // #docregion getTimeoutValue
+ it('#getTimeoutValue should return timeout value', done => {
+ service = new FancyService();
+ service.getTimeoutValue().then(value => {
+ expect(value).toBe('timeout value');
+ done();
+ });
+ });
+ // #enddocregion getTimeoutValue
+
+ it('#getObservableValue should return observable value', done => {
+ service.getObservableValue().subscribe(value => {
+ expect(value).toBe('observable value');
+ done();
+ });
+ });
+
+});
+// #enddocregion FancyService
+
+// DependentService requires injection of a FancyService
+// #docregion DependentService
+describe('DependentService without the TestBed', () => {
+ let service: DependentService;
+
+ it('#getValue should return real value by way of the real FancyService', () => {
+ service = new DependentService(new FancyService());
+ expect(service.getValue()).toBe('real value');
+ });
+
+ it('#getValue should return faked value by way of a fakeService', () => {
+ service = new DependentService(new FakeFancyService());
+ expect(service.getValue()).toBe('faked value');
+ });
+
+ it('#getValue should return faked value from a fake object', () => {
+ const fake = { getValue: () => 'fake value' };
+ service = new DependentService(fake as FancyService);
+ expect(service.getValue()).toBe('fake value');
+ });
+
+ it('#getValue should return stubbed value from a FancyService spy', () => {
+ const fancy = new FancyService();
+ const stubValue = 'stub value';
+ const spy = spyOn(fancy, 'getValue').and.returnValue(stubValue);
+ service = new DependentService(fancy);
+
+ expect(service.getValue()).toBe(stubValue, 'service returned stub value');
+ expect(spy.calls.count()).toBe(1, 'stubbed method was called once');
+ expect(spy.calls.mostRecent().returnValue).toBe(stubValue);
+ });
+});
+// #enddocregion DependentService
+
+// #docregion ReversePipe
+import { ReversePipe } from './bag';
+
+describe('ReversePipe', () => {
+ let pipe: ReversePipe;
+
+ beforeEach(() => { pipe = new ReversePipe(); });
+
+ it('transforms "abc" to "cba"', () => {
+ expect(pipe.transform('abc')).toBe('cba');
+ });
+
+ it('no change to palindrome: "able was I ere I saw elba"', () => {
+ const palindrome = 'able was I ere I saw elba';
+ expect(pipe.transform(palindrome)).toBe(palindrome);
+ });
+
+});
+// #enddocregion ReversePipe
+
+
+import { ButtonComponent } from './bag';
+// #docregion ButtonComp
+describe('ButtonComp', () => {
+ let comp: ButtonComponent;
+ beforeEach(() => comp = new ButtonComponent());
+
+ it('#isOn should be false initially', () => {
+ expect(comp.isOn).toBe(false);
+ });
+
+ it('#clicked() should set #isOn to true', () => {
+ comp.clicked();
+ expect(comp.isOn).toBe(true);
+ });
+
+ it('#clicked() should set #message to "is on"', () => {
+ comp.clicked();
+ expect(comp.message).toMatch(/is on/i);
+ });
+
+ it('#clicked() should toggle #isOn', () => {
+ comp.clicked();
+ expect(comp.isOn).toBe(true);
+ comp.clicked();
+ expect(comp.isOn).toBe(false);
+ });
+});
+// #enddocregion ButtonComp
diff --git a/public/docs/_examples/testing/ts/app/bag/bag.spec.ts b/public/docs/_examples/testing/ts/app/bag/bag.spec.ts
new file mode 100644
index 0000000000..1fede16bd7
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/bag/bag.spec.ts
@@ -0,0 +1,674 @@
+// #docplaster
+import {
+ BagModule,
+ BankAccountComponent, BankAccountParentComponent,
+ ButtonComponent,
+ Child1Component, Child2Component, Child3Component,
+ FancyService,
+ ExternalTemplateComponent,
+ InputComponent,
+ IoComponent, IoParentComponent,
+ MyIfComponent, MyIfChildComponent, MyIfParentComponent,
+ NeedsContentComponent, ParentComponent,
+ TestProvidersComponent, TestViewProvidersComponent,
+ ReversePipeComponent, ShellComponent
+} from './bag';
+
+import { By } from '@angular/platform-browser';
+import { Component,
+ DebugElement,
+ Injectable } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+
+// Forms symbols imported only for a specific test below
+import { NgModel, NgControl } from '@angular/forms';
+
+import { async, ComponentFixture, fakeAsync, inject, TestBed, tick
+} from '@angular/core/testing';
+
+import { addMatchers, newEvent } from '../../testing';
+
+beforeEach( addMatchers );
+
+//////// Service Tests /////////////
+// #docregion FancyService
+describe('use inject helper in beforeEach', () => {
+ let service: FancyService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({ providers: [FancyService] });
+
+ // `TestBed.get` returns the injectable or an
+ // alternative object (including null) if the service provider is not found.
+ // Of course it will be found in this case because we're providing it.
+ // #docregion testbed-get
+ service = TestBed.get(FancyService, null);
+ // #enddocregion testbed-get
+ });
+
+ it('should use FancyService', () => {
+ expect(service.getValue()).toBe('real value');
+ });
+
+ it('should use FancyService', () => {
+ expect(service.getValue()).toBe('real value');
+ });
+
+ it('test should wait for FancyService.getAsyncValue', async(() => {
+ service.getAsyncValue().then(
+ value => expect(value).toBe('async value')
+ );
+ }));
+
+ it('test should wait for FancyService.getTimeoutValue', async(() => {
+ service.getTimeoutValue().then(
+ value => expect(value).toBe('timeout value')
+ );
+ }));
+
+ it('test should wait for FancyService.getObservableValue', async(() => {
+ service.getObservableValue().subscribe(
+ value => expect(value).toBe('observable value')
+ );
+ }));
+
+ // #enddocregion FancyService
+ // See https://github.com/angular/angular/issues/10127
+ xit('test should wait for FancyService.getObservableDelayValue', async(() => {
+ service.getObservableDelayValue().subscribe(
+ value => expect(value).toBe('observable delay value')
+ );
+ }));
+ // #docregion FancyService
+ it('should allow the use of fakeAsync', fakeAsync(() => {
+ let value: any;
+ service.getAsyncValue().then((val: any) => value = val);
+ tick(); // Trigger JS engine cycle until all promises resolve.
+ expect(value).toBe('async value');
+ }));
+});
+// #enddocregion FancyService
+
+describe('use inject within `it`', () => {
+ // #docregion getTimeoutValue
+ beforeEach(() => {
+ TestBed.configureTestingModule({ providers: [FancyService] });
+ });
+
+ // #enddocregion getTimeoutValue
+
+ it('should use modified providers',
+ inject([FancyService], (service: FancyService) => {
+ service.setValue('value modified in beforeEach');
+ expect(service.getValue()).toBe('value modified in beforeEach');
+ })
+ );
+
+ // #docregion getTimeoutValue
+ it('test should wait for FancyService.getTimeoutValue',
+ async(inject([FancyService], (service: FancyService) => {
+
+ service.getTimeoutValue().then(
+ value => expect(value).toBe('timeout value')
+ );
+ })));
+ // #enddocregion getTimeoutValue
+});
+
+describe('using async(inject) within beforeEach', () => {
+ let serviceValue: string;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({ providers: [FancyService] });
+ });
+
+ beforeEach( async(inject([FancyService], (service: FancyService) => {
+ service.getAsyncValue().then(value => serviceValue = value);
+ })));
+
+ it('should use asynchronously modified value ... in synchronous test', () => {
+ expect(serviceValue).toBe('async value');
+ });
+});
+
+
+/////////// Component Tests //////////////////
+
+describe('TestBed Component Tests', () => {
+
+ beforeEach( async(() => {
+ TestBed
+ .configureTestingModule({
+ imports: [BagModule],
+ })
+ // Compile everything in BagModule
+ .compileComponents();
+ }));
+
+ it('should create a component with inline template', () => {
+ const fixture = TestBed.createComponent(Child1Component);
+ fixture.detectChanges();
+
+ expect(fixture).toHaveText('Child');
+ });
+
+ it('should create a component with external template', () => {
+ const fixture = TestBed.createComponent(ExternalTemplateComponent);
+ fixture.detectChanges();
+
+ expect(fixture).toHaveText('from external template');
+ });
+
+ it('should allow changing members of the component', () => {
+ const fixture = TestBed.createComponent(MyIfComponent);
+
+ fixture.detectChanges();
+ expect(fixture).toHaveText('MyIf()');
+
+ fixture.componentInstance.showMore = true;
+ fixture.detectChanges();
+ expect(fixture).toHaveText('MyIf(More)');
+ });
+
+ it('should create a nested component bound to inputs/outputs', () => {
+ const fixture = TestBed.createComponent(IoParentComponent);
+
+ fixture.detectChanges();
+ const heroes = fixture.debugElement.queryAll(By.css('.hero'));
+ expect(heroes.length).toBeGreaterThan(0, 'has heroes');
+
+ const comp = fixture.componentInstance;
+ const hero = comp.heroes[0];
+
+ heroes[0].triggerEventHandler('click', null);
+ fixture.detectChanges();
+
+ const selected = fixture.debugElement.query(By.css('p'));
+ expect(selected).toHaveText(hero.name);
+ });
+
+ it('can access the instance variable of an `*ngFor` row', () => {
+ const fixture = TestBed.createComponent(IoParentComponent);
+ const comp = fixture.componentInstance;
+
+ fixture.detectChanges();
+ const heroEl = fixture.debugElement.query(By.css('.hero')); // first hero
+
+ const ngForRow = heroEl.parent; // Angular's NgForRow wrapper element
+
+ // jasmine.any is instance-of-type test.
+ expect(ngForRow.componentInstance).toEqual(jasmine.any(IoComponent), 'component is IoComp');
+
+ const hero = ngForRow.context['$implicit']; // the hero object
+ expect(hero.name).toBe(comp.heroes[0].name, '1st hero\'s name');
+ });
+
+
+ // #docregion ButtonComp
+ it('should support clicking a button', () => {
+ const fixture = TestBed.createComponent(ButtonComponent);
+ const btn = fixture.debugElement.query(By.css('button'));
+ const span = fixture.debugElement.query(By.css('span')).nativeElement;
+
+ fixture.detectChanges();
+ expect(span.textContent).toMatch(/is off/i, 'before click');
+
+ btn.triggerEventHandler('click', null);
+ fixture.detectChanges();
+ expect(span.textContent).toMatch(/is on/i, 'after click');
+ });
+ // #enddocregion ButtonComp
+
+ // ngModel is async so we must wait for it with promise-based `whenStable`
+ it('should support entering text in input box (ngModel)', async(() => {
+ const expectedOrigName = 'John';
+ const expectedNewName = 'Sally';
+
+ const fixture = TestBed.createComponent(InputComponent);
+ fixture.detectChanges();
+
+ const comp = fixture.componentInstance;
+ const input = fixture.debugElement.query(By.css('input')).nativeElement;
+
+ expect(comp.name).toBe(expectedOrigName,
+ `At start name should be ${expectedOrigName} `);
+
+ // wait until ngModel binds comp.name to input box
+ fixture.whenStable().then(() => {
+ expect(input.value).toBe(expectedOrigName,
+ `After ngModel updates input box, input.value should be ${expectedOrigName} `);
+
+ // simulate user entering new name in input
+ input.value = expectedNewName;
+
+ // that change doesn't flow to the component immediately
+ expect(comp.name).toBe(expectedOrigName,
+ `comp.name should still be ${expectedOrigName} after value change, before binding happens`);
+
+ // dispatch a DOM event so that Angular learns of input value change.
+ // then wait while ngModel pushes input.box value to comp.name
+ input.dispatchEvent(newEvent('input'));
+ return fixture.whenStable();
+ })
+ .then(() => {
+ expect(comp.name).toBe(expectedNewName,
+ `After ngModel updates the model, comp.name should be ${expectedNewName} `);
+ });
+ }));
+
+ // fakeAsync version of ngModel input test enables sync test style
+ // synchronous `tick` replaces asynchronous promise-base `whenStable`
+ it('should support entering text in input box (ngModel) - fakeAsync', fakeAsync(() => {
+ const expectedOrigName = 'John';
+ const expectedNewName = 'Sally';
+
+ const fixture = TestBed.createComponent(InputComponent);
+ fixture.detectChanges();
+
+ const comp = fixture.componentInstance;
+ const input = fixture.debugElement.query(By.css('input')).nativeElement;
+
+ expect(comp.name).toBe(expectedOrigName,
+ `At start name should be ${expectedOrigName} `);
+
+ // wait until ngModel binds comp.name to input box
+ tick();
+ expect(input.value).toBe(expectedOrigName,
+ `After ngModel updates input box, input.value should be ${expectedOrigName} `);
+
+ // simulate user entering new name in input
+ input.value = expectedNewName;
+
+ // that change doesn't flow to the component immediately
+ expect(comp.name).toBe(expectedOrigName,
+ `comp.name should still be ${expectedOrigName} after value change, before binding happens`);
+
+ // dispatch a DOM event so that Angular learns of input value change.
+ // then wait a tick while ngModel pushes input.box value to comp.name
+ input.dispatchEvent(newEvent('input'));
+ tick();
+ expect(comp.name).toBe(expectedNewName,
+ `After ngModel updates the model, comp.name should be ${expectedNewName} `);
+ }));
+
+ // #docregion ReversePipeComp
+ it('ReversePipeComp should reverse the input text', fakeAsync(() => {
+ const inputText = 'the quick brown fox.';
+ const expectedText = '.xof nworb kciuq eht';
+
+ const fixture = TestBed.createComponent(ReversePipeComponent);
+ fixture.detectChanges();
+
+ const comp = fixture.componentInstance;
+ const input = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;
+ const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement;
+
+ // simulate user entering new name in input
+ input.value = inputText;
+
+ // dispatch a DOM event so that Angular learns of input value change.
+ // then wait a tick while ngModel pushes input.box value to comp.text
+ // and Angular updates the output span
+ input.dispatchEvent(newEvent('input'));
+ tick();
+ fixture.detectChanges();
+ expect(span.textContent).toBe(expectedText, 'output span');
+ expect(comp.text).toBe(inputText, 'component.text');
+ }));
+ // #enddocregion ReversePipeComp
+
+ // Use this technique to find attached directives of any kind
+ it('can examine attached directives and listeners', () => {
+ const fixture = TestBed.createComponent(InputComponent);
+ fixture.detectChanges();
+
+ const inputEl = fixture.debugElement.query(By.css('input'));
+
+ expect(inputEl.providerTokens).toContain(NgModel, 'NgModel directive');
+
+ const ngControl = inputEl.injector.get(NgControl);
+ expect(ngControl).toEqual(jasmine.any(NgControl), 'NgControl directive');
+
+ expect(inputEl.listeners.length).toBeGreaterThan(2, 'several listeners attached');
+ });
+
+ // #docregion debug-dom-renderer
+ it('DebugDomRender should set attributes, styles, classes, and properties', () => {
+ const fixture = TestBed.createComponent(BankAccountParentComponent);
+ fixture.detectChanges();
+ const comp = fixture.componentInstance;
+
+ // the only child is debugElement of the BankAccount component
+ const el = fixture.debugElement.children[0];
+ const childComp = el.componentInstance as BankAccountComponent;
+ expect(childComp).toEqual(jasmine.any(BankAccountComponent));
+
+ expect(el.context).toBe(comp, 'context is the parent component');
+
+ expect(el.attributes['account']).toBe(childComp.id, 'account attribute');
+ expect(el.attributes['bank']).toBe(childComp.bank, 'bank attribute');
+
+ expect(el.classes['closed']).toBe(true, 'closed class');
+ expect(el.classes['open']).toBe(false, 'open class');
+
+ expect(el.properties['customProperty']).toBe(true, 'customProperty');
+
+ expect(el.styles['color']).toBe(comp.color, 'color style');
+ expect(el.styles['width']).toBe(comp.width + 'px', 'width style');
+ });
+ // #enddocregion debug-dom-renderer
+});
+
+describe('TestBed Component Overrides:', () => {
+
+ it('should override ChildComp\'s template', () => {
+
+ const fixture = TestBed.configureTestingModule({
+ declarations: [Child1Component],
+ })
+ .overrideComponent(Child1Component, {
+ set: { template: 'Fake ' }
+ })
+ .createComponent(Child1Component);
+
+ fixture.detectChanges();
+ expect(fixture).toHaveText('Fake');
+ });
+
+ it('should override TestProvidersComp\'s FancyService provider', () => {
+ const fixture = TestBed.configureTestingModule({
+ declarations: [TestProvidersComponent],
+ })
+ .overrideComponent(TestProvidersComponent, {
+ remove: { providers: [FancyService]},
+ add: { providers: [{ provide: FancyService, useClass: FakeFancyService }] },
+
+ // Or replace them all (this component has only one provider)
+ // set: { providers: [{ provide: FancyService, useClass: FakeFancyService }] },
+ })
+ .createComponent(TestProvidersComponent);
+
+ fixture.detectChanges();
+ expect(fixture).toHaveText('injected value: faked value', 'text');
+
+ // Explore the providerTokens
+ const tokens = fixture.debugElement.providerTokens;
+ expect(tokens).toContain(fixture.componentInstance.constructor, 'component ctor');
+ expect(tokens).toContain(TestProvidersComponent, 'TestProvidersComp');
+ expect(tokens).toContain(FancyService, 'FancyService');
+ });
+
+ it('should override TestViewProvidersComp\'s FancyService viewProvider', () => {
+ const fixture = TestBed.configureTestingModule({
+ declarations: [TestViewProvidersComponent],
+ })
+ .overrideComponent(TestViewProvidersComponent, {
+ // remove: { viewProviders: [FancyService]},
+ // add: { viewProviders: [{ provide: FancyService, useClass: FakeFancyService }] },
+
+ // Or replace them all (this component has only one viewProvider)
+ set: { viewProviders: [{ provide: FancyService, useClass: FakeFancyService }] },
+ })
+ .createComponent(TestViewProvidersComponent);
+
+ fixture.detectChanges();
+ expect(fixture).toHaveText('injected value: faked value');
+ });
+
+ it('injected provider should not be same as component\'s provider', () => {
+
+ // TestComponent is parent of TestProvidersComponent
+ @Component({ template: ' ' })
+ class TestComponent {}
+
+ // 3 levels of FancyService provider: module, TestCompomponent, TestProvidersComponent
+ const fixture = TestBed.configureTestingModule({
+ declarations: [TestComponent, TestProvidersComponent],
+ providers: [FancyService]
+ })
+ .overrideComponent(TestComponent, {
+ set: { providers: [{ provide: FancyService, useValue: {} }] }
+ })
+ .overrideComponent(TestProvidersComponent, {
+ set: { providers: [{ provide: FancyService, useClass: FakeFancyService }] }
+ })
+ .createComponent(TestComponent);
+
+ let testBedProvider: FancyService;
+ let tcProvider: {};
+ let tpcProvider: FakeFancyService;
+
+ // `inject` uses TestBed's injector
+ inject([FancyService], (s: FancyService) => testBedProvider = s)();
+ tcProvider = fixture.debugElement.injector.get(FancyService);
+ tpcProvider = fixture.debugElement.children[0].injector.get(FancyService);
+
+ expect(testBedProvider).not.toBe(tcProvider, 'testBed/tc not same providers');
+ expect(testBedProvider).not.toBe(tpcProvider, 'testBed/tpc not same providers');
+
+ expect(testBedProvider instanceof FancyService).toBe(true, 'testBedProvider is FancyService');
+ expect(tcProvider).toEqual({}, 'tcProvider is {}');
+ expect(tpcProvider instanceof FakeFancyService).toBe(true, 'tpcProvider is FakeFancyService');
+ });
+
+ it('can access template local variables as references', () => {
+ const fixture = TestBed.configureTestingModule({
+ declarations: [ShellComponent, NeedsContentComponent, Child1Component, Child2Component, Child3Component],
+ })
+ .overrideComponent(ShellComponent, {
+ set: {
+ selector: 'test-shell',
+ template: `
+
+
+
+
+
+ !
+
+ `
+ }
+ })
+ .createComponent(ShellComponent);
+
+ fixture.detectChanges();
+
+ // NeedsContentComp is the child of ShellComp
+ const el = fixture.debugElement.children[0];
+ const comp = el.componentInstance;
+
+ expect(comp.children.toArray().length).toBe(4,
+ 'three different child components and an ElementRef with #content');
+
+ expect(el.references['nc']).toBe(comp, '#nc reference to component');
+
+ // #docregion custom-predicate
+ // Filter for DebugElements with a #content reference
+ const contentRefs = el.queryAll( de => de.references['content']);
+ // #enddocregion custom-predicate
+ expect(contentRefs.length).toBe(4, 'elements w/ a #content reference');
+ });
+
+});
+
+describe('Nested (one-deep) component override', () => {
+
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ParentComponent, FakeChildComponent]
+ })
+ .compileComponents();
+ }));
+
+ it('ParentComp should use Fake Child component', () => {
+ const fixture = TestBed.createComponent(ParentComponent);
+ fixture.detectChanges();
+ expect(fixture).toHaveText('Parent(Fake Child)');
+ });
+});
+
+describe('Nested (two-deep) component override', () => {
+
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ParentComponent, FakeChildWithGrandchildComponent, FakeGrandchildComponent]
+ })
+ .compileComponents();
+ }));
+
+ it('should use Fake Grandchild component', () => {
+ const fixture = TestBed.createComponent(ParentComponent);
+ fixture.detectChanges();
+ expect(fixture).toHaveText('Parent(Fake Child(Fake Grandchild))');
+ });
+});
+
+describe('Lifecycle hooks w/ MyIfParentComp', () => {
+ let fixture: ComponentFixture;
+ let parent: MyIfParentComponent;
+ let child: MyIfChildComponent;
+
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ imports: [FormsModule],
+ declarations: [MyIfChildComponent, MyIfParentComponent]
+ })
+ .compileComponents().then(() => {
+ fixture = TestBed.createComponent(MyIfParentComponent);
+ parent = fixture.componentInstance;
+ });
+ }));
+
+ it('should instantiate parent component', () => {
+ expect(parent).not.toBeNull('parent component should exist');
+ });
+
+ it('parent component OnInit should NOT be called before first detectChanges()', () => {
+ expect(parent.ngOnInitCalled).toBe(false);
+ });
+
+ it('parent component OnInit should be called after first detectChanges()', () => {
+ fixture.detectChanges();
+ expect(parent.ngOnInitCalled).toBe(true);
+ });
+
+ it('child component should exist after OnInit', () => {
+ fixture.detectChanges();
+ getChild();
+ expect(child instanceof MyIfChildComponent).toBe(true, 'should create child');
+ });
+
+ it('should have called child component\'s OnInit ', () => {
+ fixture.detectChanges();
+ getChild();
+ expect(child.ngOnInitCalled).toBe(true);
+ });
+
+ it('child component called OnChanges once', () => {
+ fixture.detectChanges();
+ getChild();
+ expect(child.ngOnChangesCounter).toBe(1);
+ });
+
+ it('changed parent value flows to child', () => {
+ fixture.detectChanges();
+ getChild();
+
+ parent.parentValue = 'foo';
+ fixture.detectChanges();
+
+ expect(child.ngOnChangesCounter).toBe(2,
+ 'expected 2 changes: initial value and changed value');
+ expect(child.childValue).toBe('foo',
+ 'childValue should eq changed parent value');
+ });
+
+ // must be async test to see child flow to parent
+ it('changed child value flows to parent', async(() => {
+ fixture.detectChanges();
+ getChild();
+
+ child.childValue = 'bar';
+
+ return new Promise(resolve => {
+ // Wait one JS engine turn!
+ setTimeout(() => resolve(), 0);
+ })
+ .then(() => {
+ fixture.detectChanges();
+
+ expect(child.ngOnChangesCounter).toBe(2,
+ 'expected 2 changes: initial value and changed value');
+ expect(parent.parentValue).toBe('bar',
+ 'parentValue should eq changed parent value');
+ });
+
+ }));
+
+ it('clicking "Close Child" triggers child OnDestroy', () => {
+ fixture.detectChanges();
+ getChild();
+
+ const btn = fixture.debugElement.query(By.css('button'));
+ btn.triggerEventHandler('click', null);
+
+ fixture.detectChanges();
+ expect(child.ngOnDestroyCalled).toBe(true);
+ });
+
+ ////// helpers ///
+ /**
+ * Get the MyIfChildComp from parent; fail w/ good message if cannot.
+ */
+ function getChild() {
+
+ let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp
+
+ // The Hard Way: requires detailed knowledge of the parent template
+ try {
+ childDe = fixture.debugElement.children[4].children[0];
+ } catch (err) { /* we'll report the error */ }
+
+ // DebugElement.queryAll: if we wanted all of many instances:
+ childDe = fixture.debugElement
+ .queryAll(function (de) { return de.componentInstance instanceof MyIfChildComponent; })[0];
+
+ // WE'LL USE THIS APPROACH !
+ // DebugElement.query: find first instance (if any)
+ childDe = fixture.debugElement
+ .query(function (de) { return de.componentInstance instanceof MyIfChildComponent; });
+
+ if (childDe && childDe.componentInstance) {
+ child = childDe.componentInstance;
+ } else {
+ fail('Unable to find MyIfChildComp within MyIfParentComp');
+ }
+
+ return child;
+ }
+});
+
+////////// Fakes ///////////
+
+@Component({
+ selector: 'child-1',
+ template: `Fake Child`
+})
+class FakeChildComponent { }
+
+@Component({
+ selector: 'child-1',
+ template: `Fake Child( )`
+})
+class FakeChildWithGrandchildComponent { }
+
+@Component({
+ selector: 'grandchild-1',
+ template: `Fake Grandchild`
+})
+class FakeGrandchildComponent { }
+
+@Injectable()
+class FakeFancyService extends FancyService {
+ value: string = 'faked value';
+}
diff --git a/public/docs/_examples/testing/ts/app/bag/bag.ts b/public/docs/_examples/testing/ts/app/bag/bag.ts
new file mode 100644
index 0000000000..cbe88f55f5
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/bag/bag.ts
@@ -0,0 +1,454 @@
+/* tslint:disable:forin */
+import { Component, ContentChildren, Directive, ElementRef, EventEmitter,
+ Injectable, Input, Output, Optional,
+ HostBinding, HostListener,
+ OnInit, OnChanges, OnDestroy,
+ Pipe, PipeTransform,
+ Renderer, SimpleChange } from '@angular/core';
+
+import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/observable/of';
+import 'rxjs/add/operator/delay';
+
+////////// The App: Services and Components for the tests. //////////////
+
+export class Hero {
+ name: string;
+}
+
+////////// Services ///////////////
+// #docregion FancyService
+@Injectable()
+export class FancyService {
+ protected value: string = 'real value';
+
+ getValue() { return this.value; }
+ setValue(value: string) { this.value = value; }
+
+ getAsyncValue() { return Promise.resolve('async value'); }
+
+ getObservableValue() { return Observable.of('observable value'); }
+
+ getTimeoutValue() {
+ return new Promise((resolve) => {
+ setTimeout(() => { resolve('timeout value'); }, 10);
+ });
+ }
+
+ getObservableDelayValue() {
+ return Observable.of('observable delay value').delay(10);
+ }
+}
+// #enddocregion FancyService
+
+// #docregion DependentService
+@Injectable()
+export class DependentService {
+ constructor(private dependentService: FancyService) { }
+ getValue() { return this.dependentService.getValue(); }
+}
+// #enddocregion DependentService
+
+/////////// Pipe ////////////////
+/*
+ * Reverse the input string.
+*/
+// #docregion ReversePipe
+@Pipe({ name: 'reverse' })
+export class ReversePipe implements PipeTransform {
+ transform(s: string) {
+ let r = '';
+ for (let i = s.length; i; ) { r += s[--i]; };
+ return r;
+ }
+}
+// #enddocregion ReversePipe
+
+//////////// Components /////////////
+@Component({
+ selector: 'bank-account',
+ template: `
+ Bank Name: {{bank}}
+ Account Id: {{id}}
+ `
+})
+export class BankAccountComponent {
+ @Input() bank: string;
+ @Input('account') id: string;
+
+ constructor(private renderer: Renderer, private el: ElementRef ) {
+ renderer.setElementProperty(el.nativeElement, 'customProperty', true);
+ }
+}
+
+/** A component with attributes, styles, classes, and property setting */
+@Component({
+ selector: 'bank-account-parent',
+ template: `
+
+
+ `
+})
+export class BankAccountParentComponent {
+ width = 200;
+ color = 'red';
+ isClosed = true;
+}
+
+// #docregion ButtonComp
+@Component({
+ selector: 'button-comp',
+ template: `
+ Click me!
+ {{message}} `
+})
+export class ButtonComponent {
+ isOn = false;
+ clicked() { this.isOn = !this.isOn; }
+ get message() { return `The light is ${this.isOn ? 'On' : 'Off'}`; }
+}
+// #enddocregion ButtonComp
+
+@Component({
+ selector: 'child-1',
+ template: `Child-1({{text}}) `
+})
+export class Child1Component {
+ @Input() text = 'Original';
+}
+
+@Component({
+ selector: 'child-2',
+ template: 'Child-2({{text}})
'
+})
+export class Child2Component {
+ @Input() text: string;
+}
+
+@Component({
+ selector: 'child-3',
+ template: 'Child-3({{text}})
'
+})
+export class Child3Component {
+ @Input() text: string;
+}
+
+@Component({
+ selector: 'input-comp',
+ template: ` `
+})
+export class InputComponent {
+ name = 'John';
+}
+
+/* Prefer this metadata syntax */
+// @Directive({
+// selector: 'input[value]',
+// host: {
+// '[value]': 'value',
+// '(input)': 'valueChange.next($event.target.value)'
+// },
+// inputs: ['value'],
+// outputs: ['valueChange']
+// })
+// export class InputValueBinderDirective {
+// value: any;
+// valueChange: EventEmitter = new EventEmitter();
+// }
+
+// As the style-guide recommends
+@Directive({ selector: 'input[value]' })
+export class InputValueBinderDirective {
+ @HostBinding()
+ @Input()
+ value: any;
+
+ @Output()
+ valueChange: EventEmitter = new EventEmitter();
+
+ @HostListener('input', ['$event.target.value'])
+ onInput(value: any) { this.valueChange.next(value); }
+}
+
+@Component({
+ selector: 'input-value-comp',
+ template: `
+ Name: {{name}}
+ `
+})
+export class InputValueBinderComponent {
+ name = 'Sally'; // initial value
+}
+
+@Component({
+ selector: 'parent-comp',
+ template: `Parent( )`
+})
+export class ParentComponent { }
+
+@Component({
+ selector: 'io-comp',
+ template: `Original {{hero.name}}
`
+})
+export class IoComponent {
+ @Input() hero: Hero;
+ @Output() selected = new EventEmitter();
+ click() { this.selected.emit(this.hero); }
+}
+
+@Component({
+ selector: 'io-parent-comp',
+ template: `
+ Click to select a hero
+ The selected hero is {{selectedHero.name}}
+
+
+ `
+})
+export class IoParentComponent {
+ heroes: Hero[] = [ {name: 'Bob'}, {name: 'Carol'}, {name: 'Ted'}, {name: 'Alice'} ];
+ selectedHero: Hero;
+ onSelect(hero: Hero) { this.selectedHero = hero; }
+}
+
+@Component({
+ selector: 'my-if-comp',
+ template: `MyIf(More )`
+})
+export class MyIfComponent {
+ showMore = false;
+}
+
+@Component({
+ selector: 'my-service-comp',
+ template: `injected value: {{fancyService.value}}`,
+ providers: [FancyService]
+})
+export class TestProvidersComponent {
+ constructor(private fancyService: FancyService) {}
+}
+
+
+@Component({
+ selector: 'my-service-comp',
+ template: `injected value: {{fancyService.value}}`,
+ viewProviders: [FancyService]
+})
+export class TestViewProvidersComponent {
+ constructor(private fancyService: FancyService) {}
+}
+
+@Component({
+ moduleId: module.id,
+ selector: 'external-template-comp',
+ templateUrl: 'bag-external-template.html'
+})
+export class ExternalTemplateComponent implements OnInit {
+ serviceValue: string;
+
+ constructor(@Optional() private service: FancyService) { }
+
+ ngOnInit() {
+ if (this.service) { this.serviceValue = this.service.getValue(); }
+ }
+}
+
+@Component({
+ selector: 'comp-w-ext-comp',
+ template: `
+ comp-w-ext-comp
+
+ `
+})
+export class InnerCompWithExternalTemplateComponent { }
+
+@Component({
+ selector: 'bad-template-comp',
+ templateUrl: 'non-existant.html'
+})
+export class BadTemplateUrlComponent { }
+
+
+
+@Component({selector: 'needs-content', template: ' '})
+export class NeedsContentComponent {
+ // children with #content local variable
+ @ContentChildren('content') children: any;
+}
+
+///////// MyIfChildComp ////////
+@Component({
+ selector: 'my-if-child-1',
+
+ template: `
+ MyIfChildComp
+
+ Child value:
+
+ Change log:
+ {{i + 1}} - {{log}}
`
+})
+export class MyIfChildComponent implements OnInit, OnChanges, OnDestroy {
+ @Input() value = '';
+ @Output() valueChange = new EventEmitter();
+
+ get childValue() { return this.value; }
+ set childValue(v: string) {
+ if (this.value === v) { return; }
+ this.value = v;
+ this.valueChange.emit(v);
+ }
+
+ changeLog: string[] = [];
+
+ ngOnInitCalled = false;
+ ngOnChangesCounter = 0;
+ ngOnDestroyCalled = false;
+
+ ngOnInit() {
+ this.ngOnInitCalled = true;
+ this.changeLog.push('ngOnInit called');
+ }
+
+ ngOnDestroy() {
+ this.ngOnDestroyCalled = true;
+ this.changeLog.push('ngOnDestroy called');
+ }
+
+ ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
+ for (let propName in changes) {
+ this.ngOnChangesCounter += 1;
+ let prop = changes[propName];
+ let cur = JSON.stringify(prop.currentValue);
+ let prev = JSON.stringify(prop.previousValue);
+ this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
+ }
+ }
+}
+
+///////// MyIfParentComp ////////
+
+@Component({
+ selector: 'my-if-parent-comp',
+ template: `
+ MyIfParentComp
+ Parent value:
+
+
+ {{toggleLabel}} Child
+
+
+
+ `
+})
+export class MyIfParentComponent implements OnInit {
+ ngOnInitCalled = false;
+ parentValue = 'Hello, World';
+ showChild = false;
+ toggleLabel = 'Unknown';
+
+ ngOnInit() {
+ this.ngOnInitCalled = true;
+ this.clicked();
+ }
+
+ clicked() {
+ this.showChild = !this.showChild;
+ this.toggleLabel = this.showChild ? 'Close' : 'Show';
+ }
+}
+
+
+@Component({
+ selector: 'reverse-pipe-comp',
+ template: `
+
+ {{text | reverse}}
+ `
+})
+export class ReversePipeComponent {
+ text = 'my dog has fleas.';
+}
+
+@Component({template: 'Replace Me
'})
+export class ShellComponent { }
+
+@Component({
+ selector: 'bag-comp',
+ template: `
+ Specs Bag
+
+
+ Input/Output Component
+
+
+ External Template Component
+
+
+ Component With External Template Component
+
+
+ Reverse Pipe
+
+
+ InputValueBinder Directive
+
+
+ Button Component
+
+
+ Needs Content
+
+
+
+
+
+ !
+
+ `
+})
+export class BagComponent { }
+//////// Aggregations ////////////
+
+export const bagDeclarations = [
+ BagComponent,
+ BankAccountComponent, BankAccountParentComponent,
+ ButtonComponent,
+ Child1Component, Child2Component, Child3Component,
+ ExternalTemplateComponent, InnerCompWithExternalTemplateComponent,
+ InputComponent,
+ InputValueBinderDirective, InputValueBinderComponent,
+ IoComponent, IoParentComponent,
+ MyIfComponent, MyIfChildComponent, MyIfParentComponent,
+ NeedsContentComponent, ParentComponent,
+ TestProvidersComponent, TestViewProvidersComponent,
+ ReversePipe, ReversePipeComponent, ShellComponent
+];
+
+export const bagProviders = [DependentService, FancyService];
+
+////////////////////
+////////////
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { FormsModule } from '@angular/forms';
+
+@NgModule({
+ imports: [BrowserModule, FormsModule],
+ declarations: bagDeclarations,
+ providers: bagProviders,
+ entryComponents: [BagComponent],
+ bootstrap: [BagComponent]
+})
+export class BagModule { }
+
diff --git a/public/docs/_examples/testing/ts/app/banner.component.spec.ts b/public/docs/_examples/testing/ts/app/banner.component.spec.ts
new file mode 100644
index 0000000000..c9af53a805
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/banner.component.spec.ts
@@ -0,0 +1,127 @@
+// #docplaster
+// #docregion
+// #docregion imports
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { BannerComponent } from './banner.component';
+// #enddocregion imports
+
+// #docregion setup
+let comp: BannerComponent;
+let fixture: ComponentFixture;
+let el: DebugElement;
+
+describe('BannerComponent', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [ BannerComponent ], // declare the test component
+ });
+
+ fixture = TestBed.createComponent(BannerComponent);
+
+ comp = fixture.componentInstance; // BannerComponent test instance
+
+ // get title DebugElement by element name
+ el = fixture.debugElement.query(By.css('h1'));
+ });
+// #enddocregion setup
+ // #docregion tests
+ it('should display original title', () => {
+ fixture.detectChanges(); // trigger data binding
+ expect(el.nativeElement.textContent).toContain(comp.title);
+ });
+
+ it('should display a different test title', () => {
+ comp.title = 'Test Title';
+ fixture.detectChanges(); // trigger data binding
+ expect(el.nativeElement.textContent).toContain('Test Title');
+ });
+ // #enddocregion tests
+ // #docregion test-w-o-detect-changes
+ it('no title in the DOM until manually call `detectChanges`', () => {
+ expect(el.nativeElement.textContent).toEqual('');
+ });
+ // #enddocregion test-w-o-detect-changes
+
+// #docregion setup
+});
+// #enddocregion setup
+
+///////// With AutoChangeDetect /////
+import { ComponentFixtureAutoDetect } from '@angular/core/testing';
+
+describe('BannerComponent with AutoChangeDetect', () => {
+
+ beforeEach(() => {
+ // #docregion auto-detect
+ fixture = TestBed.configureTestingModule({
+ declarations: [ BannerComponent ],
+ providers: [
+ { provide: ComponentFixtureAutoDetect,
+ useValue: true }
+ ]
+ })
+ // #enddocregion auto-detect
+ .createComponent(BannerComponent);
+
+ comp = fixture.componentInstance; // BannerComponent test instance
+
+ // find title DebugElement by element name
+ el = fixture.debugElement.query(By.css('h1'));
+ });
+
+ // #docregion auto-detect-tests
+ it('should display original title', () => {
+ // Hooray! No `fixture.detectChanges()` needed
+ expect(el.nativeElement.textContent).toContain(comp.title);
+ });
+
+ it('should still see original title after comp.title change', () => {
+ const oldTitle = comp.title;
+ comp.title = 'Test Title';
+ // Displayed title is old because Angular didn't hear the change :(
+ expect(el.nativeElement.textContent).toContain(oldTitle);
+ });
+
+ it('should display updated title after detectChanges', () => {
+ comp.title = 'Test Title';
+ fixture.detectChanges(); // detect changes explicitly
+ expect(el.nativeElement.textContent).toContain(comp.title);
+ });
+ // #enddocregion auto-detect-tests
+});
+
+
+describe('BannerComponent (simpified)', () => {
+ // #docregion simple-example-before-each
+ beforeEach(() => {
+
+ // refine the test module by declaring the test component
+ TestBed.configureTestingModule({
+ declarations: [ BannerComponent ],
+ });
+
+ // create component and test fixture
+ fixture = TestBed.createComponent(BannerComponent);
+
+ // get test component from the fixture
+ comp = fixture.componentInstance;
+ });
+ // #enddocregion simple-example-before-each
+
+ // #docregion simple-example-it
+ it('should display original title', () => {
+
+ // trigger data binding to update the view
+ fixture.detectChanges();
+
+ // find the title element in the DOM using a CSS selector
+ el = fixture.debugElement.query(By.css('h1'));
+
+ // confirm the element's content
+ expect(el.nativeElement.textContent).toContain(comp.title);
+ });
+ // #enddocregion simple-example-it
+});
diff --git a/public/docs/_examples/testing/ts/app/banner.component.ts b/public/docs/_examples/testing/ts/app/banner.component.ts
new file mode 100644
index 0000000000..c220c1482b
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/banner.component.ts
@@ -0,0 +1,11 @@
+// #docregion
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-banner',
+ template: '{{title}} '
+})
+export class BannerComponent {
+ title = 'Test Tour of Heroes';
+}
+
diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.html b/public/docs/_examples/testing/ts/app/dashboard.component.html
deleted file mode 100644
index 028eab6eb3..0000000000
--- a/public/docs/_examples/testing/ts/app/dashboard.component.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-Top Heroes
-
diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts b/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts
deleted file mode 100644
index 1b573c32f3..0000000000
--- a/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-/* tslint:disable:no-unused-variable */
-import { DashboardComponent } from './dashboard.component';
-
-import { By } from '@angular/platform-browser';
-
-import {
- addProviders,
- async, inject
-} from '@angular/core/testing';
-
-import { ComponentFixture, TestComponentBuilder } from '@angular/core/testing';
-
-import { Hero, HeroService, MockHeroService } from './mock-hero.service';
-import { Router, MockRouter } from './mock-router';
-
-describe('DashboardComponent', () => {
-
- //////// WITHOUT ANGULAR INVOLVED ///////
- describe('w/o Angular', () => {
- let comp: DashboardComponent;
- let mockHeroService: MockHeroService;
- let router: MockRouter;
-
- beforeEach(() => {
- router = new MockRouter();
- mockHeroService = new MockHeroService();
- comp = new DashboardComponent(router, mockHeroService);
- });
-
- it('should NOT have heroes before calling OnInit', () => {
- expect(comp.heroes.length).toEqual(0,
- 'should not have heroes before OnInit');
- });
-
- it('should NOT have heroes immediately after OnInit', () => {
- comp.ngOnInit(); // ngOnInit -> getHeroes
- expect(comp.heroes.length).toEqual(0,
- 'should not have heroes until service promise resolves');
- });
-
- it('should HAVE heroes after HeroService gets them', (done: DoneFn) => {
- comp.ngOnInit(); // ngOnInit -> getHeroes
- mockHeroService.lastPromise // the one from getHeroes
- .then(() => {
- // throw new Error('deliberate error'); // see it fail gracefully
- expect(comp.heroes.length).toBeGreaterThan(0,
- 'should have heroes after service promise resolves');
- })
- .then(done, done.fail);
- });
-
- it('should tell ROUTER to navigate by hero id', () => {
- let hero: Hero = {id: 42, name: 'Abbracadabra' };
- let spy = spyOn(router, 'navigate').and.callThrough();
-
- comp.gotoDetail(hero);
-
- let linkParams = spy.calls.mostRecent().args[0];
- expect(linkParams[0]).toEqual('HeroDetail', 'should nav to "HeroDetail"');
- expect(linkParams[1].id).toEqual(hero.id, 'should nav to fake hero\'s id');
- });
-
- });
-
-
- ////// WITH ANGULAR TEST INFRASTRUCTURE ///////
- describe('using TCB', () => {
- let comp: DashboardComponent;
- let mockHeroService: MockHeroService;
-
- beforeEach(() => {
- mockHeroService = new MockHeroService();
- addProviders([
- { provide: Router, useClass: MockRouter},
- { provide: MockRouter, useExisting: Router},
- { provide: HeroService, useValue: mockHeroService }
- ]);
- });
-
- it('can instantiate it',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
- tcb.createAsync(DashboardComponent);
- })));
-
- it('should NOT have heroes before OnInit',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
- tcb.createAsync(DashboardComponent).then(fixture => {
- comp = fixture.debugElement.componentInstance;
-
- expect(comp.heroes.length).toEqual(0,
- 'should not have heroes before OnInit');
- });
- })));
-
- it('should NOT have heroes immediately after OnInit',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
- tcb.createAsync(DashboardComponent).then(fixture => {
- comp = fixture.debugElement.componentInstance;
- fixture.detectChanges(); // runs initial lifecycle hooks
-
- expect(comp.heroes.length).toEqual(0,
- 'should not have heroes until service promise resolves');
- });
- })));
-
- it('should HAVE heroes after HeroService gets them',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.createAsync(DashboardComponent).then(fixture => {
- comp = fixture.debugElement.componentInstance;
- fixture.detectChanges(); // runs ngOnInit -> getHeroes
-
- mockHeroService.lastPromise // the one from getHeroes
- .then(() => {
- expect(comp.heroes.length).toBeGreaterThan(0,
- 'should have heroes after service promise resolves');
- });
-
- });
- })));
-
- it('should DISPLAY heroes after HeroService gets them',
- async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
-
- tcb.createAsync(DashboardComponent).then(fixture => {
- comp = fixture.debugElement.componentInstance;
- fixture.detectChanges(); // runs ngOnInit -> getHeroes
-
- mockHeroService.lastPromise // the one from getHeroes
- .then(() => {
-
- // Find and examine the displayed heroes
- fixture.detectChanges(); // update bindings
- let heroNames = fixture.debugElement.queryAll(By.css('h4'));
-
- expect(heroNames.length).toEqual(4, 'should display 4 heroes');
-
- // the 4th displayed hero should be the 5th mock hero
- expect(heroNames[3].nativeElement.textContent)
- .toContain(mockHeroService.mockHeroes[4].name);
- });
-
- });
- })));
-
- it('should tell ROUTER to navigate by hero id',
- async(inject([TestComponentBuilder, Router],
- (tcb: TestComponentBuilder, router: MockRouter) => {
-
- let spy = spyOn(router, 'navigate').and.callThrough();
-
- tcb.createAsync(DashboardComponent).then(fixture => {
- let hero: Hero = {id: 42, name: 'Abbracadabra' };
- comp = fixture.debugElement.componentInstance;
- comp.gotoDetail(hero);
-
- let linkParams = spy.calls.mostRecent().args[0];
- expect(linkParams[0]).toEqual('HeroDetail', 'should nav to "HeroDetail"');
- expect(linkParams[1].id).toEqual(hero.id, 'should nav to fake hero\'s id');
-
- });
- })));
- });
-});
diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.ts b/public/docs/_examples/testing/ts/app/dashboard.component.ts
deleted file mode 100644
index 69a9c5cce6..0000000000
--- a/public/docs/_examples/testing/ts/app/dashboard.component.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-// #docplaster
-// #docregion
-import { Component, OnInit } from '@angular/core';
-// #docregion import-router
-import { Router } from '@angular/router-deprecated';
-// #enddocregion import-router
-
-import { Hero } from './hero';
-import { HeroService } from './hero.service';
-
-@Component({
- selector: 'my-dashboard',
- // #docregion template-url
- templateUrl: 'app/dashboard.component.html',
- // #enddocregion template-url
- // #docregion css
- styleUrls: ['app/dashboard.component.css']
- // #enddocregion css
-})
-// #docregion component
-export class DashboardComponent implements OnInit {
-
- heroes: Hero[] = [];
-
-// #docregion ctor
- constructor(
- private _router: Router,
- private _heroService: HeroService) {
- }
-// #enddocregion ctor
-
- ngOnInit() {
- this._heroService.getHeroes()
- .then(heroes => this.heroes = heroes.slice(1, 5));
- }
-
- // #docregion goto-detail
- gotoDetail(hero: Hero) {
- let link = ['HeroDetail', { id: hero.id }];
- this._router.navigate(link);
- }
- // #enddocregion goto-detail
-}
-// #enddocregion
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.css b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.css
new file mode 100644
index 0000000000..eb54d181d8
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.css
@@ -0,0 +1,28 @@
+.hero {
+ padding: 20px;
+ position: relative;
+ text-align: center;
+ color: #eee;
+ max-height: 120px;
+ min-width: 120px;
+ background-color: #607D8B;
+ border-radius: 2px;
+}
+
+.hero:hover {
+ background-color: #EEE;
+ cursor: pointer;
+ color: #607d8b;
+}
+
+@media (max-width: 600px) {
+ .hero {
+ font-size: 10px;
+ max-height: 75px; }
+}
+
+@media (max-width: 1024px) {
+ .hero {
+ min-width: 60px;
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.html b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.html
new file mode 100644
index 0000000000..ff49bd17a5
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.html
@@ -0,0 +1,4 @@
+
+
+ {{hero.name | uppercase}}
+
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.spec.ts b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.spec.ts
new file mode 100644
index 0000000000..86e0a88d2e
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.spec.ts
@@ -0,0 +1,113 @@
+import { async, ComponentFixture, TestBed
+} from '@angular/core/testing';
+
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { addMatchers } from '../../testing';
+
+import { Hero } from '../model/hero';
+import { DashboardHeroComponent } from './dashboard-hero.component';
+
+beforeEach( addMatchers );
+
+describe('DashboardHeroComponent when tested directly', () => {
+
+ let comp: DashboardHeroComponent;
+ let expectedHero: Hero;
+ let fixture: ComponentFixture;
+ let heroEl: DebugElement;
+
+ // #docregion setup, compile-components
+ // asynch beforeEach
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DashboardHeroComponent ],
+ })
+ .compileComponents(); // compile template and css
+ }));
+ // #enddocregion compile-components
+
+ // synchronous beforeEach
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DashboardHeroComponent);
+ comp = fixture.componentInstance;
+ heroEl = fixture.debugElement.query(By.css('.hero')); // find hero element
+
+ // pretend that it was wired to something that supplied a hero
+ expectedHero = new Hero(42, 'Test Name');
+ comp.hero = expectedHero;
+ fixture.detectChanges(); // trigger initial data binding
+ });
+ // #enddocregion setup
+
+ // #docregion name-test
+ it('should display hero name', () => {
+ const expectedPipedName = expectedHero.name.toUpperCase();
+ expect(heroEl.nativeElement.textContent).toContain(expectedPipedName);
+ });
+ // #enddocregion name-test
+
+ // #docregion click-test
+ it('should raise selected event when clicked', () => {
+ let selectedHero: Hero;
+ comp.selected.subscribe((hero: Hero) => selectedHero = hero);
+
+ heroEl.triggerEventHandler('click', null);
+ expect(selectedHero).toBe(expectedHero);
+ });
+ // #enddocregion click-test
+});
+
+//////////////////
+
+describe('DashboardHeroComponent when inside a test host', () => {
+ let testHost: TestHostComponent;
+ let fixture: ComponentFixture;
+ let heroEl: DebugElement;
+
+ // #docregion test-host-setup
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DashboardHeroComponent, TestHostComponent ], // declare both
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ // create TestHosComponent instead of DashboardHeroComponent
+ fixture = TestBed.createComponent(TestHostComponent);
+ testHost = fixture.componentInstance;
+ heroEl = fixture.debugElement.query(By.css('.hero')); // find hero
+ fixture.detectChanges(); // trigger initial data binding
+ });
+ // #enddocregion test-host-setup
+
+ // #docregion test-host-tests
+ it('should display hero name', () => {
+ const expectedPipedName = testHost.hero.name.toUpperCase();
+ expect(heroEl.nativeElement.textContent).toContain(expectedPipedName);
+ });
+
+ it('should raise selected event when clicked', () => {
+ heroEl.triggerEventHandler('click', null);
+ // selected hero should be the same data bound hero
+ expect(testHost.selectedHero).toBe(testHost.hero);
+ });
+ // #enddocregion test-host-tests
+});
+
+////// Test Host Component //////
+import { Component } from '@angular/core';
+
+// #docregion test-host
+@Component({
+ template: `
+
+ `
+})
+class TestHostComponent {
+ hero = new Hero(42, 'Test Name');
+ selectedHero: Hero;
+ onSelected(hero: Hero) { this.selectedHero = hero; }
+}
+// #enddocregion test-host
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.ts b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.ts
new file mode 100644
index 0000000000..3d8ee8a177
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard-hero.component.ts
@@ -0,0 +1,17 @@
+// #docregion
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { Hero } from '../model';
+
+// #docregion component
+@Component({
+ selector: 'dashboard-hero',
+ templateUrl: 'app/dashboard/dashboard-hero.component.html',
+ styleUrls: ['app/dashboard/dashboard-hero.component.css']
+})
+export class DashboardHeroComponent {
+ @Input() hero: Hero;
+ @Output() selected = new EventEmitter();
+ click() { this.selected.next(this.hero); }
+}
+// #enddocregion component
diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.css b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.css
similarity index 54%
rename from public/docs/_examples/testing/ts/app/dashboard.component.css
rename to public/docs/_examples/testing/ts/app/dashboard/dashboard.component.css
index ce6e963a5f..98130b61c6 100644
--- a/public/docs/_examples/testing/ts/app/dashboard.component.css
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.css
@@ -1,5 +1,3 @@
-/* #docplaster */
-/* #docregion */
[class*='col-'] {
float: left;
}
@@ -24,40 +22,14 @@ h3 {
.col-1-4 {
width: 25%;
}
-.module {
- padding: 20px;
- text-align: center;
- color: #eee;
- max-height: 120px;
- min-width: 120px;
- background-color: #607D8B;
- border-radius: 2px;
-}
-h4 {
- position: relative;
-}
-.module:hover {
- background-color: #EEE;
- cursor: pointer;
- color: #607d8b;
-}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
padding-right: 20px;
}
-@media (max-width: 600px) {
- .module {
- font-size: 10px;
- max-height: 75px; }
-}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
- .module {
- min-width: 60px;
- }
}
-/* #enddocregion */
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.html b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.html
new file mode 100644
index 0000000000..b26e16b828
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.html
@@ -0,0 +1,9 @@
+{{title}}
+
+
+
+
+
+
+
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.no-testbed.spec.ts b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.no-testbed.spec.ts
new file mode 100644
index 0000000000..125e5193b7
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.no-testbed.spec.ts
@@ -0,0 +1,57 @@
+import { Router } from '@angular/router';
+
+import { DashboardComponent } from './dashboard.component';
+import { Hero } from '../model';
+
+import { addMatchers } from '../../testing';
+import { FakeHeroService } from '../model/testing';
+
+class FakeRouter {
+ navigateByUrl(url: string) { return url; }
+}
+
+describe('DashboardComponent: w/o Angular TestBed', () => {
+ let comp: DashboardComponent;
+ let heroService: FakeHeroService;
+ let router: Router;
+
+ beforeEach(() => {
+ addMatchers();
+ router = new FakeRouter() as any as Router;
+ heroService = new FakeHeroService();
+ comp = new DashboardComponent(router, heroService);
+ });
+
+ it('should NOT have heroes before calling OnInit', () => {
+ expect(comp.heroes.length).toBe(0,
+ 'should not have heroes before OnInit');
+ });
+
+ it('should NOT have heroes immediately after OnInit', () => {
+ comp.ngOnInit(); // ngOnInit -> getHeroes
+ expect(comp.heroes.length).toBe(0,
+ 'should not have heroes until service promise resolves');
+ });
+
+ it('should HAVE heroes after HeroService gets them', (done: DoneFn) => {
+ comp.ngOnInit(); // ngOnInit -> getHeroes
+ heroService.lastPromise // the one from getHeroes
+ .then(() => {
+ // throw new Error('deliberate error'); // see it fail gracefully
+ expect(comp.heroes.length).toBeGreaterThan(0,
+ 'should have heroes after service promise resolves');
+ })
+ .then(done, done.fail);
+ });
+
+ it('should tell ROUTER to navigate by hero id', () => {
+ const hero = new Hero(42, 'Abbracadabra');
+ const spy = spyOn(router, 'navigateByUrl');
+
+ comp.gotoDetail(hero);
+
+ const navArgs = spy.calls.mostRecent().args[0];
+ expect(navArgs).toBe('/heroes/42', 'should nav to HeroDetail for Hero 42');
+ });
+
+});
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.spec.ts b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.spec.ts
new file mode 100644
index 0000000000..f783899143
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.spec.ts
@@ -0,0 +1,147 @@
+// #docplaster
+import { async, inject, ComponentFixture, TestBed
+} from '@angular/core/testing';
+
+import { addMatchers } from '../../testing';
+import { HeroService } from '../model';
+import { FakeHeroService } from '../model/testing';
+
+import { By } from '@angular/platform-browser';
+import { Router } from '@angular/router';
+
+import { DashboardComponent } from './dashboard.component';
+import { DashboardModule } from './dashboard.module';
+
+// #docregion router-stub
+class RouterStub {
+ navigateByUrl(url: string) { return url; }
+}
+// #enddocregion router-stub
+
+beforeEach ( addMatchers );
+
+let comp: DashboardComponent;
+let fixture: ComponentFixture;
+
+//////// Deep ////////////////
+
+describe('DashboardComponent (deep)', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [ DashboardModule ]
+ });
+ });
+
+ compileAndCreate();
+
+ tests(clickForDeep);
+
+ function clickForDeep() {
+ // get first DebugElement
+ const heroEl = fixture.debugElement.query(By.css('.hero'));
+ heroEl.triggerEventHandler('click', null);
+ }
+});
+
+//////// Shallow ////////////////
+
+import { NO_ERRORS_SCHEMA } from '@angular/core';
+
+describe('DashboardComponent (shallow)', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DashboardComponent ],
+ schemas: [NO_ERRORS_SCHEMA]
+ });
+ });
+
+ compileAndCreate();
+
+ tests(clickForShallow);
+
+ function clickForShallow() {
+ // get first
DebugElement
+ const heroEl = fixture.debugElement.query(By.css('dashboard-hero'));
+ heroEl.triggerEventHandler('selected', comp.heroes[0]);
+ }
+});
+
+/** Add TestBed providers, compile, and create DashboardComponent */
+function compileAndCreate() {
+ // #docregion compile-and-create-body
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ providers: [
+ { provide: HeroService, useClass: FakeHeroService },
+ { provide: Router, useClass: RouterStub }
+ ]
+ })
+ .compileComponents().then(() => {
+ fixture = TestBed.createComponent(DashboardComponent);
+ comp = fixture.componentInstance;
+ });
+ // #enddocregion compile-and-create-body
+ }));
+}
+
+/**
+ * The (almost) same tests for both.
+ * Only change: the way that the first hero is clicked
+ */
+function tests(heroClick: Function) {
+
+ it('should NOT have heroes before ngOnInit', () => {
+ expect(comp.heroes.length).toBe(0,
+ 'should not have heroes before ngOnInit');
+ });
+
+ it('should NOT have heroes immediately after ngOnInit', () => {
+ fixture.detectChanges(); // runs initial lifecycle hooks
+
+ expect(comp.heroes.length).toBe(0,
+ 'should not have heroes until service promise resolves');
+ });
+
+ describe('after get dashboard heroes', () => {
+
+ // Trigger component so it gets heroes and binds to them
+ beforeEach( async(() => {
+ fixture.detectChanges(); // runs ngOnInit -> getHeroes
+ fixture.whenStable() // No need for the `lastPromise` hack!
+ .then(() => fixture.detectChanges()); // bind to heroes
+ }));
+
+ it('should HAVE heroes', () => {
+ expect(comp.heroes.length).toBeGreaterThan(0,
+ 'should have heroes after service promise resolves');
+ });
+
+ it('should DISPLAY heroes', () => {
+ // Find and examine the displayed heroes
+ // Look for them in the DOM by css class
+ const heroes = fixture.debugElement.queryAll(By.css('dashboard-hero'));
+ expect(heroes.length).toBe(4, 'should display 4 heroes');
+ });
+
+ // #docregion navigate-test, inject
+ it('should tell ROUTER to navigate when hero clicked',
+ inject([Router], (router: Router) => { // ...
+ // #enddocregion inject
+
+ const spy = spyOn(router, 'navigateByUrl');
+
+ heroClick(); // trigger click on first inner
+
+ // args passed to router.navigateByUrl()
+ const navArgs = spy.calls.first().args[0];
+
+ // expecting to navigate to id of the component's first hero
+ const id = comp.heroes[0].id;
+ expect(navArgs).toBe('/heroes/' + id,
+ 'should nav to HeroDetail for first hero');
+ // #docregion inject
+ }));
+ // #enddocregion navigate-test, inject
+ });
+}
+
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.ts b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.ts
new file mode 100644
index 0000000000..bc2b707906
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard.component.ts
@@ -0,0 +1,40 @@
+// #docregion
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { Hero, HeroService } from '../model';
+
+@Component({
+ selector: 'app-dashboard',
+ templateUrl: 'app/dashboard/dashboard.component.html',
+ styleUrls: ['app/dashboard/dashboard.component.css']
+})
+export class DashboardComponent implements OnInit {
+
+ heroes: Hero[] = [];
+
+ // #docregion ctor
+ constructor(
+ private router: Router,
+ private heroService: HeroService) {
+ }
+ // #enddocregion ctor
+
+ ngOnInit() {
+ this.heroService.getHeroes()
+ .then(heroes => this.heroes = heroes.slice(1, 5));
+ }
+
+ // #docregion goto-detail
+ gotoDetail(hero: Hero) {
+ let url = `/heroes/${hero.id}`;
+ this.router.navigateByUrl(url);
+ }
+ // #enddocregion goto-detail
+
+ get title() {
+ let cnt = this.heroes.length;
+ return cnt === 0 ? 'No Heroes' :
+ cnt === 1 ? 'Top Hero' : `Top ${cnt} Heroes`;
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/dashboard/dashboard.module.ts b/public/docs/_examples/testing/ts/app/dashboard/dashboard.module.ts
new file mode 100644
index 0000000000..8a70c851a0
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/dashboard/dashboard.module.ts
@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+
+import { SharedModule } from '../shared/shared.module';
+
+import { DashboardComponent } from './dashboard.component';
+import { DashboardHeroComponent } from './dashboard-hero.component';
+
+const routes: Routes = [
+ { path: 'dashboard', component: DashboardComponent },
+];
+
+@NgModule({
+ imports: [
+ SharedModule,
+ RouterModule.forChild(routes)
+ ],
+ declarations: [ DashboardComponent, DashboardHeroComponent ]
+})
+export class DashboardModule { }
diff --git a/public/docs/_examples/testing/ts/app/hero-detail.component.html b/public/docs/_examples/testing/ts/app/hero-detail.component.html
deleted file mode 100644
index cf96fc2169..0000000000
--- a/public/docs/_examples/testing/ts/app/hero-detail.component.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
{{hero.name}} details!
-
- id: {{hero.id}}
-
- name:
-
-
-
-
Back
-
-
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/app/hero-detail.component.ts b/public/docs/_examples/testing/ts/app/hero-detail.component.ts
deleted file mode 100644
index 3fcbf071e0..0000000000
--- a/public/docs/_examples/testing/ts/app/hero-detail.component.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/* tslint:disable */
-// #docplaster
-// #docregion
-// #docregion v2
-// #docregion import-oninit
-import { Component, OnInit } from '@angular/core';
-// #enddocregion import-oninit
-// #docregion import-route-params
-import { RouteParams } from '@angular/router-deprecated';
-// #enddocregion import-route-params
-
-import { Hero } from './hero';
-// #docregion import-hero-service
-import { HeroService } from './hero.service';
-// #enddocregion import-hero-service
-
-// #docregion extract-template
-@Component({
- selector: 'my-hero-detail',
- // #docregion template-url
- templateUrl: 'app/hero-detail.component.html',
- // #enddocregion template-url
-// #enddocregion v2
- styleUrls: ['app/hero-detail.component.css'],
- inputs: ['hero']
-// #docregion v2
-})
-// #enddocregion extract-template
-// #docregion implement
-export class HeroDetailComponent implements OnInit {
-// #enddocregion implement
- hero: Hero;
-
-// #docregion ctor
- constructor(
- private _heroService: HeroService,
- private _routeParams: RouteParams) {
- }
-// #enddocregion ctor
-
-// #docregion ng-oninit
- ngOnInit() {
- // #docregion get-id
- let id = +this._routeParams.get('id');
- // #enddocregion get-id
- this._heroService.getHero(id)
- .then(hero => this.hero = hero);
- }
-// #enddocregion ng-oninit
-
-// #docregion go-back
- goBack() {
- window.history.back();
- }
-// #enddocregion go-back
-}
-// #enddocregion v2
-// #enddocregion
diff --git a/public/docs/_examples/testing/ts/app/hero.service.ts b/public/docs/_examples/testing/ts/app/hero.service.ts
deleted file mode 100644
index e9473e4038..0000000000
--- a/public/docs/_examples/testing/ts/app/hero.service.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// #docplaster
-// #docregion
-import { Hero } from './hero';
-import { HEROES } from './mock-heroes';
-import { Injectable } from '@angular/core';
-
-@Injectable()
-export class HeroService {
- getHeroes() {
- return Promise.resolve(HEROES);
- }
-
- // See the "Take it slow" appendix
- getHeroesSlowly() {
- return new Promise
(resolve =>
- setTimeout(() => resolve(HEROES), 2000) // 2 seconds
- );
- }
-
- // #docregion get-hero
- getHero(id: number) {
- return Promise.resolve(HEROES).then(
- heroes => heroes.find(hero => hero.id === id)
- );
- }
- // #enddocregion get-hero
-}
-// #enddocregion
diff --git a/public/docs/_examples/testing/ts/app/hero.spec.ts b/public/docs/_examples/testing/ts/app/hero.spec.ts
deleted file mode 100644
index 78a73ad6b0..0000000000
--- a/public/docs/_examples/testing/ts/app/hero.spec.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-// #docregion
-// #docplaster
-// #docregion base-hero-spec
-import { Hero } from './hero';
-
-describe('Hero', () => {
-
- it('has name', () => {
- let hero: Hero = {id: 1, name: 'Super Cat'};
- expect(hero.name).toEqual('Super Cat');
- });
-
- it('has id', () => {
- let hero: Hero = {id: 1, name: 'Super Cat'};
- expect(hero.id).toEqual(1);
- });
- // #enddocregion base-hero-spec
-
-
- /* more tests we could run
-
- it('can clone itself', () => {
- let hero = new Hero(1, 'Super Cat');
- let clone = hero.clone();
- expect(hero).toEqual(clone);
- });
-
- it('has expected generated id when id not given in the constructor', () => {
- Hero.setNextId(100); // reset the `nextId` seed
- let hero = new Hero(null, 'Cool Kitty');
- expect(hero.id).toEqual(100);
- });
-
- it('has expected generated id when id=0 in the constructor', () => {
- Hero.setNextId(100);
- let hero = new Hero(0, 'Cool Kitty');
- expect(hero.id).toEqual(100);
- })
-
- it('increments generated id for each new Hero w/o an id', () => {
- Hero.setNextId(100);
- let hero1 = new Hero(0, 'Cool Kitty');
- let hero2 = new Hero(null, 'Hip Cat');
- expect(hero2.id).toEqual(101);
- });
-
- */
- // #docregion base-hero-spec
-});
-// #enddocregion base-hero-spec
diff --git a/public/docs/_examples/testing/ts/app/hero.ts b/public/docs/_examples/testing/ts/app/hero.ts
deleted file mode 100644
index 8f7cc205c8..0000000000
--- a/public/docs/_examples/testing/ts/app/hero.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// #docregion
-export class Hero {
- id: number;
- name: string;
-}
diff --git a/public/docs/_examples/testing/ts/app/hero-detail.component.css b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.css
similarity index 93%
rename from public/docs/_examples/testing/ts/app/hero-detail.component.css
rename to public/docs/_examples/testing/ts/app/hero/hero-detail.component.css
index ab2437efd8..f6139ba274 100644
--- a/public/docs/_examples/testing/ts/app/hero-detail.component.css
+++ b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.css
@@ -1,4 +1,3 @@
-/* #docregion */
label {
display: inline-block;
width: 3em;
@@ -25,6 +24,6 @@ button:hover {
}
button:disabled {
background-color: #eee;
- color: #ccc;
+ color: #ccc;
cursor: auto;
}
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-detail.component.html b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.html
new file mode 100644
index 0000000000..7e86a668f6
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.html
@@ -0,0 +1,12 @@
+
+
+
{{hero.name | titlecase}} Details
+
+ id: {{hero.id}}
+
+ name:
+
+
+
Save
+
Cancel
+
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-detail.component.no-testbed.spec.ts b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.no-testbed.spec.ts
new file mode 100644
index 0000000000..a6c1af98d7
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.no-testbed.spec.ts
@@ -0,0 +1,58 @@
+import { HeroDetailComponent } from './hero-detail.component';
+import { Hero } from '../model';
+
+import { ActivatedRouteStub } from '../../testing';
+
+////////// Tests ////////////////////
+
+describe('HeroDetailComponent - no TestBed', () => {
+ let activatedRoute: ActivatedRouteStub;
+ let comp: HeroDetailComponent;
+ let expectedHero: Hero;
+ let hds: any;
+ let router: any;
+
+ beforeEach( done => {
+ expectedHero = new Hero(42, 'Bubba');
+ activatedRoute = new ActivatedRouteStub();
+ activatedRoute.testParams = { id: expectedHero.id };
+
+ router = jasmine.createSpyObj('router', ['navigate']);
+
+ hds = jasmine.createSpyObj('HeroDetailService', ['getHero', 'saveHero']);
+ hds.getHero.and.returnValue(Promise.resolve(expectedHero));
+ hds.saveHero.and.returnValue(Promise.resolve(expectedHero));
+
+ comp = new HeroDetailComponent(hds, activatedRoute, router);
+ comp.ngOnInit();
+
+ // OnInit calls HDS.getHero; wait for it to get the fake hero
+ hds.getHero.calls.first().returnValue.then(done);
+ });
+
+ it('should expose the hero retrieved from the service', () => {
+ expect(comp.hero).toBe(expectedHero);
+ });
+
+ it('should navigate when click cancel', () => {
+ comp.cancel();
+ expect(router.navigate.calls.any()).toBe(true, 'router.navigate called');
+ });
+
+ it('should save when click save', () => {
+ comp.save();
+ expect(hds.saveHero.calls.any()).toBe(true, 'HeroDetailService.save called');
+ expect(router.navigate.calls.any()).toBe(false, 'router.navigate not called yet');
+ });
+
+ it('should navigate when click save resolves', done => {
+ comp.save();
+ // waits for async save to complete before navigating
+ hds.saveHero.calls.first().returnValue
+ .then(() => {
+ expect(router.navigate.calls.any()).toBe(true, 'router.navigate called');
+ done();
+ });
+ });
+
+});
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-detail.component.spec.ts b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.spec.ts
new file mode 100644
index 0000000000..272d69f579
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.spec.ts
@@ -0,0 +1,205 @@
+// #docplaster
+import {
+ async, ComponentFixture, fakeAsync, inject, TestBed, tick
+} from '@angular/core/testing';
+
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import {
+ addMatchers, newEvent,
+ ActivatedRoute, ActivatedRouteStub, Router, RouterStub
+} from '../../testing';
+
+import { HEROES, FakeHeroService } from '../model/testing';
+
+import { HeroModule } from './hero.module';
+import { HeroDetailComponent } from './hero-detail.component';
+import { HeroDetailService } from './hero-detail.service';
+import { Hero, HeroService } from '../model';
+
+////// Testing Vars //////
+let activatedRoute: ActivatedRouteStub;
+let comp: HeroDetailComponent;
+let fixture: ComponentFixture;
+let page: Page;
+
+////////// Tests ////////////////////
+
+describe('HeroDetailComponent', () => {
+
+ beforeEach( async(() => {
+ addMatchers();
+ activatedRoute = new ActivatedRouteStub();
+
+ TestBed.configureTestingModule({
+ imports: [ HeroModule ],
+
+ // DON'T RE-DECLARE because already declared in HeroModule
+ // declarations: [HeroDetailComponent, TitleCasePipe], // No!
+
+ providers: [
+ { provide: ActivatedRoute, useValue: activatedRoute },
+ { provide: HeroService, useClass: FakeHeroService },
+ { provide: Router, useClass: RouterStub},
+ ]
+ })
+ .compileComponents();
+ }));
+
+ // #docregion route-good-id
+ describe('when navigate to hero id=' + HEROES[0].id, () => {
+ let expectedHero: Hero;
+
+ beforeEach( async(() => {
+ expectedHero = HEROES[0];
+ activatedRoute.testParams = { id: expectedHero.id };
+ createComponent();
+ }));
+
+ // #docregion selected-tests
+ it('should display that hero\'s name', () => {
+ expect(page.nameDisplay.textContent).toBe(expectedHero.name);
+ });
+ // #enddocregion route-good-id
+
+ it('should navigate when click cancel', () => {
+ page.cancelBtn.triggerEventHandler('click', null);
+ expect(page.navSpy.calls.any()).toBe(true, 'router.navigate called');
+ });
+
+ it('should save when click save but not navigate immediately', () => {
+ page.saveBtn.triggerEventHandler('click', null);
+ expect(page.saveSpy.calls.any()).toBe(true, 'HeroDetailService.save called');
+ expect(page.navSpy.calls.any()).toBe(false, 'router.navigate not called');
+ });
+
+ it('should navigate when click save and save resolves', fakeAsync(() => {
+ page.saveBtn.triggerEventHandler('click', null);
+ tick(); // wait for async save to "complete" before navigating
+ expect(page.navSpy.calls.any()).toBe(true, 'router.navigate called');
+ }));
+
+ // #docregion title-case-pipe
+ it('should convert hero name to Title Case', fakeAsync(() => {
+ const inputName = 'quick BROWN fox';
+ const titleCaseName = 'Quick Brown Fox';
+
+ // simulate user entering new name into the input box
+ page.nameInput.value = inputName;
+
+ // dispatch a DOM event so that Angular learns of input value change.
+ page.nameInput.dispatchEvent(newEvent('input'));
+
+ // detectChanges() makes [(ngModel)] push input value to component property
+ // and Angular updates the output span through the title pipe
+ fixture.detectChanges();
+
+ expect(page.nameDisplay.textContent).toBe(titleCaseName);
+ }));
+ // #enddocregion title-case-pipe
+ // #enddocregion selected-tests
+ // #docregion route-good-id
+ });
+ // #enddocregion route-good-id
+
+ // #docregion route-no-id
+ describe('when navigate with no hero id', () => {
+ beforeEach( async( createComponent ));
+
+ it('should have hero.id === 0', () => {
+ expect(comp.hero.id).toBe(0);
+ });
+
+ it('should display empty hero name', () => {
+ expect(page.nameDisplay.textContent).toBe('');
+ });
+ });
+ // #enddocregion route-no-id
+
+ // #docregion route-bad-id
+ describe('when navigate to non-existant hero id', () => {
+ beforeEach( async(() => {
+ activatedRoute.testParams = { id: 99999 };
+ createComponent();
+ }));
+
+ it('should try to navigate back to hero list', () => {
+ expect(page.gotoSpy.calls.any()).toBe(true, 'comp.gotoList called');
+ expect(page.navSpy.calls.any()).toBe(true, 'router.navigate called');
+ });
+ });
+ // #enddocregion route-bad-id
+
+ ///////////////////////////
+
+ // Why we must use `fixture.debugElement.injector` in `Page()`
+ it('cannot use `inject` to get component\'s provided service', () => {
+ let service: HeroDetailService;
+ fixture = TestBed.createComponent(HeroDetailComponent);
+ expect(
+ // Throws because `inject` only has access to TestBed's injector
+ // which is an ancestor of the component's injector
+ inject([HeroDetailService], (hds: HeroDetailService) => service = hds )
+ )
+ .toThrowError(/No provider for HeroDetailService/);
+
+ // get `HeroDetailService` with component's own injector
+ service = fixture.debugElement.injector.get(HeroDetailService);
+ expect(service).toBeDefined('debugElement.injector');
+ });
+});
+
+/////////// Helpers /////
+
+// #docregion create-component
+/** Create the HeroDetailComponent, initialize it, set test variables */
+function createComponent() {
+ fixture = TestBed.createComponent(HeroDetailComponent);
+ comp = fixture.componentInstance;
+ page = new Page();
+
+ // 1st change detection triggers ngOnInit which gets a hero
+ fixture.detectChanges();
+ return fixture.whenStable().then(() => {
+ // 2nd change detection displays the async-fetched hero
+ fixture.detectChanges();
+ page.addPageElements();
+ });
+}
+// #enddocregion create-component
+
+// #docregion page
+class Page {
+ gotoSpy: jasmine.Spy;
+ navSpy: jasmine.Spy;
+ saveSpy: jasmine.Spy;
+
+ saveBtn: DebugElement;
+ cancelBtn: DebugElement;
+ nameDisplay: HTMLElement;
+ nameInput: HTMLInputElement;
+
+ constructor() {
+ // Use component's injector to see the services it injected.
+ const compInjector = fixture.debugElement.injector;
+ const hds = compInjector.get(HeroDetailService);
+ const router = compInjector.get(Router);
+ this.gotoSpy = spyOn(comp, 'gotoList').and.callThrough();
+ this.saveSpy = spyOn(hds, 'saveHero').and.callThrough();
+ this.navSpy = spyOn(router, 'navigate');
+ }
+
+ /** Add page elements after hero arrives */
+ addPageElements() {
+ if (comp.hero) {
+ // have a hero so these elements are now in the DOM
+ const buttons = fixture.debugElement.queryAll(By.css('button'));
+ this.saveBtn = buttons[0];
+ this.cancelBtn = buttons[1];
+ this.nameDisplay = fixture.debugElement.query(By.css('span')).nativeElement;
+ this.nameInput = fixture.debugElement.query(By.css('input')).nativeElement;
+ }
+ }
+}
+// #enddocregion page
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-detail.component.ts b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.ts
new file mode 100644
index 0000000000..1cbf5389b9
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-detail.component.ts
@@ -0,0 +1,53 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import 'rxjs/add/operator/pluck';
+
+import { Hero } from '../model';
+import { HeroDetailService } from './hero-detail.service';
+
+@Component({
+ selector: 'app-hero-detail',
+ templateUrl: 'app/hero/hero-detail.component.html',
+ styleUrls: ['app/hero/hero-detail.component.css'],
+ providers: [ HeroDetailService ]
+})
+export class HeroDetailComponent implements OnInit {
+ @Input() hero: Hero;
+
+ // #docregion ctor
+ constructor(
+ private heroDetailService: HeroDetailService,
+ private route: ActivatedRoute,
+ private router: Router) {
+ }
+ // #enddocregion ctor
+
+ // #docregion ng-on-init
+ ngOnInit(): void {
+ // get hero when `id` param changes
+ this.route.params.pluck('id')
+ .forEach(id => this.getHero(id))
+ .catch(() => this.hero = new Hero()); // no id; should edit new hero
+ }
+ // #enddocregion ng-on-init
+
+ private getHero(id: string): void {
+ this.heroDetailService.getHero(id).then(hero => {
+ if (hero) {
+ this.hero = hero;
+ } else {
+ this.gotoList(); // id not found; navigate to list
+ }
+ });
+ }
+
+ save(): void {
+ this.heroDetailService.saveHero(this.hero).then(() => this.gotoList());
+ }
+
+ cancel() { this.gotoList(); }
+
+ gotoList() {
+ this.router.navigate(['../'], {relativeTo: this.route});
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-detail.service.ts b/public/docs/_examples/testing/ts/app/hero/hero-detail.service.ts
new file mode 100644
index 0000000000..970cb1b98b
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-detail.service.ts
@@ -0,0 +1,21 @@
+import { Injectable } from '@angular/core';
+
+import { Hero, HeroService } from '../model';
+
+@Injectable()
+export class HeroDetailService {
+ constructor(private heroService: HeroService) { }
+
+ getHero(id: number | string): Promise {
+ if (typeof id === 'string') {
+ id = parseInt(id as string, 10);
+ }
+ return this.heroService.getHero(id).then(hero => {
+ return hero ? Object.assign({}, hero) : null; // clone or null
+ });
+ }
+
+ saveHero(hero: Hero) {
+ return this.heroService.updateHero(hero);
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/heroes.component.css b/public/docs/_examples/testing/ts/app/hero/hero-list.component.css
similarity index 100%
rename from public/docs/_examples/testing/ts/app/heroes.component.css
rename to public/docs/_examples/testing/ts/app/hero/hero-list.component.css
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-list.component.html b/public/docs/_examples/testing/ts/app/hero/hero-list.component.html
new file mode 100644
index 0000000000..cd37301fd6
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-list.component.html
@@ -0,0 +1,8 @@
+My Heroes
+
+
+ {{hero.id}} {{hero.name}}
+
+
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-list.component.spec.ts b/public/docs/_examples/testing/ts/app/hero/hero-list.component.spec.ts
new file mode 100644
index 0000000000..dbf9d37d71
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-list.component.spec.ts
@@ -0,0 +1,139 @@
+import { async, ComponentFixture, fakeAsync, TestBed, tick
+} from '@angular/core/testing';
+
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { addMatchers, newEvent, Router, RouterStub
+} from '../../testing';
+
+import { HEROES, FakeHeroService } from '../model/testing';
+
+import { HeroModule } from './hero.module';
+import { HeroListComponent } from './hero-list.component';
+import { HighlightDirective } from '../shared/highlight.directive';
+import { HeroService } from '../model';
+
+let comp: HeroListComponent;
+let fixture: ComponentFixture;
+let page: Page;
+
+/////// Tests //////
+
+describe('HeroListComponent', () => {
+
+ beforeEach( async(() => {
+ addMatchers();
+ TestBed.configureTestingModule({
+ imports: [HeroModule],
+ providers: [
+ { provide: HeroService, useClass: FakeHeroService },
+ { provide: Router, useClass: RouterStub}
+ ]
+ })
+ .compileComponents()
+ .then(createComponent);
+ }));
+
+ it('should display heroes', () => {
+ expect(page.heroRows.length).toBeGreaterThan(0);
+ });
+
+ it('1st hero should match 1st test hero', () => {
+ const expectedHero = HEROES[0];
+ const actualHero = page.heroRows[0].textContent;
+ expect(actualHero).toContain(expectedHero.id, 'hero.id');
+ expect(actualHero).toContain(expectedHero.name, 'hero.name');
+ });
+
+ it('should select hero on click', fakeAsync(() => {
+ const expectedHero = HEROES[1];
+ const li = page.heroRows[1];
+ li.dispatchEvent(newEvent('click'));
+ tick();
+ // `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
+ expect(comp.selectedHero).toEqual(expectedHero);
+ }));
+
+ it('should navigate to selected hero detail on click', fakeAsync(() => {
+ const expectedHero = HEROES[1];
+ const li = page.heroRows[1];
+ li.dispatchEvent(newEvent('click'));
+ tick();
+
+ // should have navigated
+ expect(page.navSpy.calls.any()).toBe(true, 'navigate called');
+
+ // composed hero detail will be URL like 'heroes/42'
+ // expect link array with the route path and hero id
+ // first argument to router.navigate is link array
+ const navArgs = page.navSpy.calls.first().args[0];
+ expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
+ expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
+
+ }));
+
+ it('should find `HighlightDirective` with `By.directive', () => {
+ // #docregion by
+ // Can find DebugElement either by css selector or by directive
+ const h2 = fixture.debugElement.query(By.css('h2'));
+ const directive = fixture.debugElement.query(By.directive(HighlightDirective));
+ // #enddocregion by
+ expect(h2).toBe(directive);
+ });
+
+ it('should color header with `HighlightDirective`', () => {
+ const h2 = page.highlightDe.nativeElement as HTMLElement;
+ const bgColor = h2.style.backgroundColor;
+
+ // different browsers report color values differently
+ const isExpectedColor = bgColor === 'gold' || bgColor === 'rgb(255, 215, 0)';
+ expect(isExpectedColor).toBe(true, 'backgroundColor');
+ });
+
+ it('the `HighlightDirective` is among the element\'s providers', () => {
+ expect(page.highlightDe.providerTokens).toContain(HighlightDirective, 'HighlightDirective');
+ });
+});
+
+/////////// Helpers /////
+
+/** Create the component and set the `page` test variables */
+function createComponent() {
+ fixture = TestBed.createComponent(HeroListComponent);
+ comp = fixture.componentInstance;
+
+ // change detection triggers ngOnInit which gets a hero
+ fixture.detectChanges();
+
+ return fixture.whenStable().then(() => {
+ // got the heroes and updated component
+ // change detection updates the view
+ fixture.detectChanges();
+ page = new Page();
+ });
+}
+
+class Page {
+ /** Hero line elements */
+ heroRows: HTMLLIElement[];
+
+ /** Highlighted element */
+ highlightDe: DebugElement;
+
+ /** Spy on router navigate method */
+ navSpy: jasmine.Spy;
+
+ constructor() {
+ this.heroRows = fixture.debugElement.queryAll(By.css('li')).map(de => de.nativeElement);
+
+ // Find the first element with an attached HighlightDirective
+ this.highlightDe = fixture.debugElement.query(By.directive(HighlightDirective));
+
+ // Get the component's injected router and spy on it
+ const router = fixture.debugElement.injector.get(Router);
+ this.navSpy = spyOn(router, 'navigate');
+ };
+}
+
+
diff --git a/public/docs/_examples/testing/ts/app/hero/hero-list.component.ts b/public/docs/_examples/testing/ts/app/hero/hero-list.component.ts
new file mode 100644
index 0000000000..625c402581
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero-list.component.ts
@@ -0,0 +1,27 @@
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { Hero, HeroService } from '../model';
+
+@Component({
+ selector: 'app-heroes',
+ templateUrl: 'app/hero/hero-list.component.html',
+ styleUrls: ['app/hero/hero-list.component.css']
+})
+export class HeroListComponent implements OnInit {
+ heroes: Promise;
+ selectedHero: Hero;
+
+ constructor(
+ private router: Router,
+ private heroService: HeroService) { }
+
+ ngOnInit() {
+ this.heroes = this.heroService.getHeroes();
+ }
+
+ onSelect(hero: Hero) {
+ this.selectedHero = hero;
+ this.router.navigate(['../heroes', this.selectedHero.id ]);
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/hero/hero.module.ts b/public/docs/_examples/testing/ts/app/hero/hero.module.ts
new file mode 100644
index 0000000000..541d49103f
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero.module.ts
@@ -0,0 +1,9 @@
+import { NgModule } from '@angular/core';
+import { SharedModule } from '../shared/shared.module';
+import { routedComponents, routing } from './hero.routing';
+
+@NgModule({
+ imports: [ SharedModule, routing ],
+ declarations: [ routedComponents ]
+})
+export class HeroModule { }
diff --git a/public/docs/_examples/testing/ts/app/hero/hero.routing.ts b/public/docs/_examples/testing/ts/app/hero/hero.routing.ts
new file mode 100644
index 0000000000..9530bc3953
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/hero/hero.routing.ts
@@ -0,0 +1,12 @@
+import { RouterModule, Routes } from '@angular/router';
+
+import { HeroListComponent } from './hero-list.component';
+import { HeroDetailComponent } from './hero-detail.component';
+
+const routes: Routes = [
+ { path: '', component: HeroListComponent },
+ { path: ':id', component: HeroDetailComponent }
+];
+
+export const routedComponents = [HeroDetailComponent, HeroListComponent];
+export const routing = RouterModule.forChild(routes);
diff --git a/public/docs/_examples/testing/ts/app/heroes.component.html b/public/docs/_examples/testing/ts/app/heroes.component.html
deleted file mode 100644
index cce1853d30..0000000000
--- a/public/docs/_examples/testing/ts/app/heroes.component.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-My Heroes
-
-
- {{hero.id}} {{hero.name}}
-
-
-
-
-
-
- {{selectedHero.name | uppercase}} is my hero
-
-
- View Details
-
-
-
diff --git a/public/docs/_examples/testing/ts/app/heroes.component.ts b/public/docs/_examples/testing/ts/app/heroes.component.ts
deleted file mode 100644
index 1e2651f256..0000000000
--- a/public/docs/_examples/testing/ts/app/heroes.component.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-// #docplaster
-// #docregion
-import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router-deprecated';
-
-import { Hero } from './hero';
-import { HeroDetailComponent } from './hero-detail.component';
-import { HeroService } from './hero.service';
-
-// #docregion metadata
-// #docregion heroes-component-renaming
-@Component({
- selector: 'my-heroes',
-// #enddocregion heroes-component-renaming
- templateUrl: 'app/heroes.component.html',
- styleUrls: ['app/heroes.component.css'],
- directives: [HeroDetailComponent]
-// #docregion heroes-component-renaming
-})
-// #enddocregion heroes-component-renaming
-// #enddocregion metadata
-// #docregion class
-// #docregion heroes-component-renaming
-export class HeroesComponent implements OnInit {
-// #enddocregion heroes-component-renaming
- heroes: Hero[];
- selectedHero: Hero;
-
- constructor(
- private _router: Router,
- private _heroService: HeroService) { }
-
- getHeroes() {
- this._heroService.getHeroes().then(heroes => this.heroes = heroes);
- }
-
- ngOnInit() {
- this.getHeroes();
- }
-
- onSelect(hero: Hero) { this.selectedHero = hero; }
-
- gotoDetail() {
- this._router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
- }
-// #docregion heroes-component-renaming
-}
-// #enddocregion heroes-component-renaming
-// #enddocregion class
-// #enddocregion
diff --git a/public/docs/_examples/testing/ts/app/main.ts b/public/docs/_examples/testing/ts/app/main.ts
index 5f185788a3..2c89d35a81 100644
--- a/public/docs/_examples/testing/ts/app/main.ts
+++ b/public/docs/_examples/testing/ts/app/main.ts
@@ -1,5 +1,5 @@
-import { bootstrap } from '@angular/platform-browser-dynamic';
-import { AppComponent } from './app.component';
-
-bootstrap(AppComponent);
+// main app entry point
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { AppModule } from './app.module';
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/public/docs/_examples/testing/ts/app/mock-hero.service.ts b/public/docs/_examples/testing/ts/app/mock-hero.service.ts
deleted file mode 100644
index b1538be366..0000000000
--- a/public/docs/_examples/testing/ts/app/mock-hero.service.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { HEROES } from './mock-heroes';
-import { Hero } from './hero';
-import { HeroService } from './hero.service';
-
-export { Hero } from './hero';
-export { HeroService } from './hero.service';
-
-export class MockHeroService implements HeroService {
-
- mockHeroes = HEROES.slice();
- lastPromise: Promise; // so we can spy on promise calls
-
- getHero(id: number) {
- return this.lastPromise = Promise.resolve(this.mockHeroes[0]);
- }
-
- getHeroes() {
- return this.lastPromise = Promise.resolve(this.mockHeroes);
- }
-
- getHeroesSlowly() { return this.getHeroes(); }
-}
diff --git a/public/docs/_examples/testing/ts/app/mock-heroes.ts b/public/docs/_examples/testing/ts/app/mock-heroes.ts
deleted file mode 100644
index ddd36d7868..0000000000
--- a/public/docs/_examples/testing/ts/app/mock-heroes.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// #docregion
-import { Hero } from './hero';
-
-export var HEROES: Hero[] = [
- {id: 11, name: 'Mr. Nice'},
- {id: 12, name: 'Narco'},
- {id: 13, name: 'Bombasto'},
- {id: 14, name: 'Celeritas'},
- {id: 15, name: 'Magneta'},
- {id: 16, name: 'RubberMan'},
- {id: 17, name: 'Dynama'},
- {id: 18, name: 'Dr IQ'},
- {id: 19, name: 'Magma'},
- {id: 20, name: 'Tornado'}
-];
-// #enddocregion
diff --git a/public/docs/_examples/testing/ts/app/mock-router.ts b/public/docs/_examples/testing/ts/app/mock-router.ts
deleted file mode 100644
index a49763f7cf..0000000000
--- a/public/docs/_examples/testing/ts/app/mock-router.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-/* tslint:disable */
-export * from '@angular/router-deprecated';
-
-import { Directive, DynamicComponentLoader, ViewContainerRef,
- Injectable, Optional, Input } from '@angular/core';
-
-import { ComponentInstruction, Instruction,
- Router, RouterOutlet} from '@angular/router-deprecated';
-
-let _resolveToTrue = Promise.resolve(true);
-
-const NOT_IMPLEMENTED = (what: string) => {
- throw new Error (`"${what}" is not implemented`);
-};
-
-
-@Directive({
- selector: '[routerLink]',
- host: {
- '(click)': 'onClick()',
- '[attr.href]': 'visibleHref',
- '[class.router-link-active]': 'isRouteActive'
- }
-})
-export class MockRouterLink {
-
- isRouteActive = false;
- visibleHref: string; // the url displayed on the anchor element.
-
- @Input('routerLink') routeParams: any[];
- @Input() target: string;
- navigatedTo: any[] = null;
-
- constructor(public router: Router) { }
-
- onClick() {
- this.navigatedTo = null;
-
- // If no target, or if target is _self, prevent default browser behavior
- if (!this.target || typeof this.target !== 'string' || this.target === '_self') {
- this.navigatedTo = this.routeParams;
- return false;
- }
- return true;
- }
-}
-
-@Directive({selector: 'router-outlet'})
-export class MockRouterOutlet extends RouterOutlet {
- name: string = null;
-
- constructor(
- _viewContainerRef: ViewContainerRef,
- @Optional() _loader: DynamicComponentLoader,
- _parentRouter: Router,
- nameAttr: string) {
- super(_viewContainerRef, _loader, _parentRouter, nameAttr);
- if (nameAttr) {
- this.name = nameAttr;
- }
- }
-
- /**
- * Called by the Router to instantiate a new component during the commit phase of a navigation.
- * This method in turn is responsible for calling the `routerOnActivate` hook of its child.
- */
- activate(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('activate'); return _resolveToTrue; }
-
- /**
- * Called by the {@link Router} during the commit phase of a navigation when an outlet
- * reuses a component between different routes.
- * This method in turn is responsible for calling the `routerOnReuse` hook of its child.
- */
- reuse(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('reuse'); return _resolveToTrue; }
-
- /**
- * Called by the {@link Router} when an outlet disposes of a component's contents.
- * This method in turn is responsible for calling the `routerOnDeactivate` hook of its child.
- */
- deactivate(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('deactivate'); return _resolveToTrue; }
-
- /**
- * Called by the {@link Router} during recognition phase of a navigation.
- *
- * If this resolves to `false`, the given navigation is cancelled.
- *
- * This method delegates to the child component's `routerCanDeactivate` hook if it exists,
- * and otherwise resolves to true.
- */
- routerCanDeactivate(nextInstruction: ComponentInstruction): Promise {
- NOT_IMPLEMENTED('routerCanDeactivate'); return _resolveToTrue;
- }
-
- /**
- * Called by the {@link Router} during recognition phase of a navigation.
- *
- * If the new child component has a different Type than the existing child component,
- * this will resolve to `false`. You can't reuse an old component when the new component
- * is of a different Type.
- *
- * Otherwise, this method delegates to the child component's `routerCanReuse` hook if it exists,
- * or resolves to true if the hook is not present.
- */
- routerCanReuse(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('routerCanReuse'); return _resolveToTrue; }
-
-}
-
-@Injectable()
-export class MockRouter extends Router {
-
- mockIsRouteActive = false;
- mockRecognizedInstruction: Instruction;
- outlet: RouterOutlet = null;
-
- constructor() {
- super(null, null, null, null);
- }
-
- auxRouter(hostComponent: any): Router { return new MockChildRouter(this, hostComponent); }
- childRouter(hostComponent: any): Router { return new MockChildRouter(this, hostComponent); }
-
- commit(instruction: Instruction, _skipLocationChange = false): Promise {
- NOT_IMPLEMENTED('commit'); return _resolveToTrue;
- }
-
- deactivate(instruction: Instruction, _skipLocationChange = false): Promise {
- NOT_IMPLEMENTED('deactivate'); return _resolveToTrue;
- }
-
- /**
- * Generate an `Instruction` based on the provided Route Link DSL.
- */
- generate(linkParams: any[]): Instruction {
- NOT_IMPLEMENTED('generate'); return null;
- }
-
- isRouteActive(instruction: Instruction): boolean { return this.mockIsRouteActive; }
-
- /**
- * Navigate based on the provided Route Link DSL. It's preferred to navigate with this method
- * over `navigateByUrl`.
- *
- * ### Usage
- *
- * This method takes an array representing the Route Link DSL:
- * ```
- * ['./MyCmp', {param: 3}]
- * ```
- * See the {@link RouterLink} directive for more.
- */
- navigate(linkParams: any[]): Promise {
- return Promise.resolve(linkParams);
- }
-
- /**
- * Navigate to a URL. Returns a promise that resolves when navigation is complete.
- * It's preferred to navigate with `navigate` instead of this method, since URLs are more brittle.
- *
- * If the given URL begins with a `/`, router will navigate absolutely.
- * If the given URL does not begin with `/`, the router will navigate relative to this component.
- */
- navigateByUrl(url: string, _skipLocationChange = false): Promise {
- return Promise.resolve(url);
- }
-
-
- /**
- * Navigate via the provided instruction. Returns a promise that resolves when navigation is
- * complete.
- */
- navigateByInstruction(instruction: Instruction, _skipLocationChange = false): Promise {
- return Promise.resolve(instruction);
- }
-
- /**
- * Subscribe to URL updates from the router
- */
- subscribe(onNext: (v: any) => void, onError?: (v: any) => void) {
- return {onNext, onError};
- }
-
- /**
- * Given a URL, returns an instruction representing the component graph
- */
- recognize(url: string): Promise {
- return Promise.resolve(this.mockRecognizedInstruction);
- }
-
- registerPrimaryOutlet(outlet: RouterOutlet): Promise {
- this.outlet = outlet;
- return super.registerPrimaryOutlet(outlet);
- }
-
- unregisterPrimaryOutlet(outlet: RouterOutlet) {
- super.unregisterPrimaryOutlet(outlet);
- this.outlet = null;
- }
-}
-
-class MockChildRouter extends MockRouter {
- constructor(parent: MockRouter, hostComponent: any) {
- super();
- this.parent = parent;
- }
-
-
- navigateByUrl(url: string, _skipLocationChange = false): Promise {
- // Delegate navigation to the root router
- return this.parent.navigateByUrl(url, _skipLocationChange);
- }
-
- navigateByInstruction(instruction: Instruction, _skipLocationChange = false):
- Promise {
- // Delegate navigation to the root router
- return this.parent.navigateByInstruction(instruction, _skipLocationChange);
- }
-}
diff --git a/public/docs/_examples/testing/ts/app/model/hero.service.ts b/public/docs/_examples/testing/ts/app/model/hero.service.ts
new file mode 100644
index 0000000000..7f2931a7f6
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/hero.service.ts
@@ -0,0 +1,29 @@
+import { Injectable } from '@angular/core';
+
+import { Hero } from './hero';
+import { HEROES } from './test-heroes';
+
+@Injectable()
+/** Dummy HeroService that pretends to be real */
+export class HeroService {
+ getHeroes() {
+ return Promise.resolve(HEROES);
+ }
+
+ getHero(id: number | string): Promise {
+ if (typeof id === 'string') {
+ id = parseInt(id as string, 10);
+ }
+ return this.getHeroes().then(
+ heroes => heroes.find(hero => hero.id === id)
+ );
+ }
+
+ updateHero(hero: Hero): Promise {
+ return this.getHero(hero.id).then(h => {
+ return h ?
+ Object.assign(h, hero) :
+ Promise.reject(`Hero ${hero.id} not found`) as any as Promise;
+ });
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/model/hero.spec.ts b/public/docs/_examples/testing/ts/app/model/hero.spec.ts
new file mode 100644
index 0000000000..e8acf913f2
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/hero.spec.ts
@@ -0,0 +1,20 @@
+// #docregion
+import { Hero } from './hero';
+
+describe('Hero', () => {
+ it('has name', () => {
+ const hero = new Hero(1, 'Super Cat');
+ expect(hero.name).toBe('Super Cat');
+ });
+
+ it('has id', () => {
+ const hero = new Hero(1, 'Super Cat');
+ expect(hero.id).toBe(1);
+ });
+
+ it('can clone itself', () => {
+ const hero = new Hero(1, 'Super Cat');
+ const clone = hero.clone();
+ expect(hero).toEqual(clone);
+ });
+});
diff --git a/public/docs/_examples/testing/ts/app/model/hero.ts b/public/docs/_examples/testing/ts/app/model/hero.ts
new file mode 100644
index 0000000000..6a98f0dfdc
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/hero.ts
@@ -0,0 +1,4 @@
+export class Hero {
+ constructor(public id = 0, public name = '') { }
+ clone() { return new Hero(this.id, this.name); }
+}
diff --git a/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts b/public/docs/_examples/testing/ts/app/model/http-hero.service.spec.ts
similarity index 67%
rename from public/docs/_examples/testing/ts/app/http-hero.service.spec.ts
rename to public/docs/_examples/testing/ts/app/model/http-hero.service.spec.ts
index 375efde560..c16b421274 100644
--- a/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts
+++ b/public/docs/_examples/testing/ts/app/model/http-hero.service.spec.ts
@@ -1,59 +1,54 @@
-/* tslint:disable:no-unused-variable */
import {
- addProviders,
- async, inject, withProviders
+ async, inject, TestBed
} from '@angular/core/testing';
-import { TestComponentBuilder } from '@angular/core/testing';
-
import {
MockBackend,
- MockConnection } from '@angular/http/testing';
+ MockConnection
+} from '@angular/http/testing';
import {
- Http, HTTP_PROVIDERS,
- ConnectionBackend, XHRBackend,
- Request, RequestMethod, BaseRequestOptions, RequestOptions,
- Response, ResponseOptions,
- URLSearchParams
+ HttpModule, Http, XHRBackend, Response, ResponseOptions
} from '@angular/http';
-// Add all operators to Observable
-import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/observable/of';
-import { Hero } from './hero';
-import { HeroService } from './http-hero.service';
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/operator/do';
+import 'rxjs/add/operator/toPromise';
-type HeroData = {id: string, name: string}
+import { Hero } from './hero';
+import { HttpHeroService as HeroService } from './http-hero.service';
const makeHeroData = () => [
- { id: '1', name: 'Windstorm' },
- { id: '2', name: 'Bombasto' },
- { id: '3', name: 'Magneta' },
- { id: '4', name: 'Tornado' }
-];
+ { id: 1, name: 'Windstorm' },
+ { id: 2, name: 'Bombasto' },
+ { id: 3, name: 'Magneta' },
+ { id: 4, name: 'Tornado' }
+] as Hero[];
-// HeroService expects response data like {data: {the-data}}
-const makeResponseData = (data: {}) => {return { data }; };
-
-//////// SPECS /////////////
+//////// Tests /////////////
describe('Http-HeroService (mockBackend)', () => {
- beforeEach(() => {
- addProviders([
- HTTP_PROVIDERS,
- { provide: XHRBackend, useClass: MockBackend }
- ]);
- });
+ beforeEach( async(() => {
+ TestBed.configureTestingModule({
+ imports: [ HttpModule ],
+ providers: [
+ HeroService,
+ { provide: XHRBackend, useClass: MockBackend }
+ ]
+ })
+ .compileComponents();
+ }));
it('can instantiate service when inject service',
- withProviders(() => [HeroService])
- .inject([HeroService], (service: HeroService) => {
- expect(service instanceof HeroService).toBe(true);
+ inject([HeroService], (service: HeroService) => {
+ expect(service instanceof HeroService).toBe(true);
}));
+
it('can instantiate service with "new"', inject([Http], (http: Http) => {
expect(http).not.toBeNull('http should be provided');
let service = new HeroService(http);
@@ -69,10 +64,9 @@ describe('Http-HeroService (mockBackend)', () => {
describe('when getHeroes', () => {
let backend: MockBackend;
let service: HeroService;
- let fakeHeroes: HeroData[];
+ let fakeHeroes: Hero[];
let response: Response;
-
beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => {
backend = be;
service = new HeroService(http);
@@ -87,7 +81,7 @@ describe('Http-HeroService (mockBackend)', () => {
service.getHeroes().toPromise()
// .then(() => Promise.reject('deliberate'))
.then(heroes => {
- expect(heroes.length).toEqual(fakeHeroes.length,
+ expect(heroes.length).toBe(fakeHeroes.length,
'should have expected no. of heroes');
});
})));
@@ -97,7 +91,7 @@ describe('Http-HeroService (mockBackend)', () => {
service.getHeroes()
.do(heroes => {
- expect(heroes.length).toEqual(fakeHeroes.length,
+ expect(heroes.length).toBe(fakeHeroes.length,
'should have expected no. of heroes');
})
.toPromise();
@@ -110,7 +104,7 @@ describe('Http-HeroService (mockBackend)', () => {
service.getHeroes()
.do(heroes => {
- expect(heroes.length).toEqual(0, 'should have no heroes');
+ expect(heroes.length).toBe(0, 'should have no heroes');
})
.toPromise();
})));
diff --git a/public/docs/_examples/testing/ts/app/http-hero.service.ts b/public/docs/_examples/testing/ts/app/model/http-hero.service.ts
similarity index 68%
rename from public/docs/_examples/testing/ts/app/http-hero.service.ts
rename to public/docs/_examples/testing/ts/app/model/http-hero.service.ts
index bfde5bfdc8..a5fe46b801 100644
--- a/public/docs/_examples/testing/ts/app/http-hero.service.ts
+++ b/public/docs/_examples/testing/ts/app/model/http-hero.service.ts
@@ -4,10 +4,16 @@ import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Headers, RequestOptions } from '@angular/http';
import { Hero } from './hero';
+
import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/observable/throw';
+
+import 'rxjs/add/operator/do';
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/operator/map';
@Injectable()
-export class HeroService {
+export class HttpHeroService {
private _heroesUrl = 'app/heroes'; // URL to web api
constructor (private http: Http) {}
@@ -19,6 +25,12 @@ export class HeroService {
.catch(this.handleError);
}
+ getHero(id: number | string) {
+ return this.http
+ .get('app/heroes/?id=${id}')
+ .map((r: Response) => r.json().data as Hero[]);
+ }
+
addHero (name: string): Observable {
let body = JSON.stringify({ name });
let headers = new Headers({ 'Content-Type': 'application/json' });
@@ -29,6 +41,16 @@ export class HeroService {
.catch(this.handleError);
}
+ updateHero (hero: Hero): Observable {
+ let body = JSON.stringify(hero);
+ let headers = new Headers({ 'Content-Type': 'application/json' });
+ let options = new RequestOptions({ headers: headers });
+
+ return this.http.put(this._heroesUrl, body, options)
+ .map(this.extractData)
+ .catch(this.handleError);
+ }
+
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
diff --git a/public/docs/_examples/testing/ts/app/model/index.ts b/public/docs/_examples/testing/ts/app/model/index.ts
new file mode 100644
index 0000000000..227004d5be
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/index.ts
@@ -0,0 +1,7 @@
+// Model barrel
+export * from './hero';
+export * from './hero.service';
+export * from './http-hero.service';
+export * from './test-heroes';
+
+export * from './user.service';
diff --git a/public/docs/_examples/testing/ts/app/model/test-heroes.ts b/public/docs/_examples/testing/ts/app/model/test-heroes.ts
new file mode 100644
index 0000000000..d40ce5d564
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/test-heroes.ts
@@ -0,0 +1,11 @@
+// #docregion
+import { Hero } from './hero';
+
+export var HEROES: Hero[] = [
+ new Hero(11, 'Mr. Nice'),
+ new Hero(12, 'Narco'),
+ new Hero(13, 'Bombasto'),
+ new Hero(14, 'Celeritas'),
+ new Hero(15, 'Magneta'),
+ new Hero(16, 'RubberMan')
+];
diff --git a/public/docs/_examples/testing/ts/app/model/testing/fake-hero.service.ts b/public/docs/_examples/testing/ts/app/model/testing/fake-hero.service.ts
new file mode 100644
index 0000000000..79a865cc44
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/testing/fake-hero.service.ts
@@ -0,0 +1,41 @@
+// re-export for tester convenience
+export { Hero } from '../hero';
+export { HeroService } from '../hero.service';
+
+import { Hero } from '../hero';
+import { HeroService } from '../hero.service';
+
+export var HEROES: Hero[] = [
+ new Hero(41, 'Bob'),
+ new Hero(42, 'Carol'),
+ new Hero(43, 'Ted'),
+ new Hero(44, 'Alice'),
+ new Hero(45, 'Speedy'),
+ new Hero(46, 'Stealthy')
+];
+
+export class FakeHeroService implements HeroService {
+
+ heroes = HEROES.map(h => h.clone());
+ lastPromise: Promise; // remember so we can spy on promise calls
+
+ getHero(id: number | string) {
+ if (typeof id === 'string') {
+ id = parseInt(id as string, 10);
+ }
+ let hero = this.heroes.find(h => h.id === id);
+ return this.lastPromise = Promise.resolve(hero);
+ }
+
+ getHeroes() {
+ return this.lastPromise = Promise.resolve(this.heroes);
+ }
+
+ updateHero(hero: Hero): Promise {
+ return this.lastPromise = this.getHero(hero.id).then(h => {
+ return h ?
+ Object.assign(h, hero) :
+ Promise.reject(`Hero ${hero.id} not found`) as any as Promise;
+ });
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/model/testing/index.ts b/public/docs/_examples/testing/ts/app/model/testing/index.ts
new file mode 100644
index 0000000000..6da76e67db
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/testing/index.ts
@@ -0,0 +1 @@
+export * from './fake-hero.service';
diff --git a/public/docs/_examples/testing/ts/app/model/user.service.ts b/public/docs/_examples/testing/ts/app/model/user.service.ts
new file mode 100644
index 0000000000..280efefeec
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/model/user.service.ts
@@ -0,0 +1,7 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class UserService {
+ isLoggedIn = true;
+ user = {name: 'Sam Spade'};
+}
diff --git a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.1.ts b/public/docs/_examples/testing/ts/app/my-uppercase.pipe.1.ts
deleted file mode 100644
index 94b5bc45ce..0000000000
--- a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.1.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-// #docregion
-import { Pipe, PipeTransform } from '@angular/core';
-
-@Pipe({ name: 'my-uppercase' })
-export class MyUppercasePipe implements PipeTransform {
- transform(value: string) {
- return value;
- }
-}
diff --git a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.spec.ts b/public/docs/_examples/testing/ts/app/my-uppercase.pipe.spec.ts
deleted file mode 100644
index 731b2ed965..0000000000
--- a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.spec.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-// #docregion
-// #docplaster
-// #docregion base-pipe-spec
-import { MyUppercasePipe } from './my-uppercase.pipe';
-
-describe('MyUppercasePipe', () => {
- let pipe: MyUppercasePipe;
-
- beforeEach(() => {
- pipe = new MyUppercasePipe();
- });
-
- // #docregion expectations
- it('transforms "abc" to "ABC"', () => {
- expect(pipe.transform('abc')).toEqual('ABC');
- });
-
- it('transforms "abc def" to "ABC DEF"', () => {
- expect(pipe.transform('abc def')).toEqual('ABC DEF');
- });
-
- it('leaves "ABC DEF" unchanged', () => {
- expect(pipe.transform('ABC DEF')).toEqual('ABC DEF');
- });
- // #enddocregion expectations
- // #enddocregion base-pipe-spec
-
- /* more tests we could run
-
- it('transforms "abc-def" to "Abc-def"', () => {
- expect(pipe.transform('abc-def')).toEqual('Abc-def');
- });
-
- it('transforms " abc def" to " Abc Def" (preserves spaces) ', () => {
- expect(pipe.transform(' abc def')).toEqual(' Abc Def');
- });
-
- */
- // #docregion base-pipe-spec
-});
-// #enddocregion base-pipe-spec
diff --git a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.ts b/public/docs/_examples/testing/ts/app/my-uppercase.pipe.ts
deleted file mode 100644
index 6584f92ef6..0000000000
--- a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// #docregion
-// #docregion depends-on-angular
-import { Pipe, PipeTransform } from '@angular/core';
-// #enddocregion depends-on-angular
-
-@Pipe({ name: 'my-uppercase' })
-export class MyUppercasePipe implements PipeTransform {
- // #docregion uppercase
- transform(value: string) {
- return value.toUpperCase();
- }
- // #enddocregion uppercase
-}
diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.spec.ts.not-yet
deleted file mode 100644
index 80c210be5d..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.spec.ts.not-yet
+++ /dev/null
@@ -1,218 +0,0 @@
-///// Boiler Plate ////
-import {bind, By, Component, Directive, EventEmitter, FORM_DIRECTIVES} from 'angular2/angular2';
-
-// Angular 2 Test Bed
-import {
-beforeEachProviders, inject, injectAsync, RootTestComponent as RTC,
-beforeEach, ddescribe, xdescribe, describe, expect, iit, it, xit // Jasmine wrappers
-} from 'angular2/testing';
-
-import {dispatchEvent, DoneFn, injectTcb, tick} from '../test-helpers/test-helpers';
-
-///// Testing this component ////
-import {HeroDetailComponent} from './hero-detail.component';
-import {Hero} from './hero';
-
-describe('HeroDetailComponent', () => {
-
- /////////// Component Tests without DOM interaction /////////////
- describe('(No DOM)', () => {
- it('can be created', () => {
- let hdc = new HeroDetailComponent();
- expect(hdc instanceof HeroDetailComponent).toEqual(true); // proof of life
- });
-
- it('onDelete method should raise delete event', (done: DoneFn) => {
- let hdc = new HeroDetailComponent();
-
- // Listen for the HeroComponent.delete EventEmitter's event
- hdc.delete.toRx().subscribe(() => {
- console.log('HeroComponent.delete event raised');
- done(); // it must have worked
- }, (error: any) => { fail(error); done() });
-
- hdc.onDelete();
- });
-
- // Disable until toPromise() works again
- xit('onDelete method should raise delete event (w/ promise)', (done: DoneFn) => {
-
- let hdc = new HeroDetailComponent();
-
- // Listen for the HeroComponent.delete EventEmitter's event
- let p = hdc.delete.toRx()
- .toPromise()
- .then(() => {
- console.log('HeroComponent.delete event raised in promise');
- })
- .then(done, done.fail);
-
- hdc.delete.toRx()
- .subscribe(() => {
- console.log('HeroComponent.delete event raised in subscription')
- });
-
- hdc.onDelete();
-
- // toPromise() does not fulfill until emitter is completed by `return()`
- hdc.delete.return();
- });
-
- it('onUpdate method should modify hero', () => {
- let hdc = new HeroDetailComponent();
- hdc.hero = new Hero(42, 'Cat Woman');
- let origNameLength = hdc.hero.name.length;
-
- hdc.onUpdate();
- expect(hdc.hero.name.length).toBeGreaterThan(origNameLength);
- });
- });
-
-
- /////////// Component tests that check the DOM /////////////
- describe('(DOM)', () => {
- // Disable until toPromise() works again
- xit('Delete button should raise delete event', injectTcb(tcb => {
-
- // We only care about the button
- let template = 'Delete ';
-
- return tcb
- .overrideTemplate(HeroDetailComponent, template)
- .createAsync(HeroDetailComponent)
- .then((rootTC: RTC) => {
- let hdc: HeroDetailComponent = rootTC.debugElement.componentInstance;
-
- // // USE PROMISE WRAPPING AN OBSERVABLE UNTIL can get `toPromise` working again
- // let p = new Promise((resolve) => {
- // // Listen for the HeroComponent.delete EventEmitter's event with observable
- // hdc.delete.toRx().subscribe((hero: Hero) => {
- // console.log('Observable heard HeroComponent.delete event raised');
- // resolve(hero);
- // });
- // })
-
- //Listen for the HeroComponent.delete EventEmitter's event with promise
- let p = > hdc.delete.toRx().toPromise()
- .then((hero:Hero) => {
- console.log('Promise heard HeroComponent.delete event raised');
- });
-
- // trigger the 'click' event on the HeroDetailComponent delete button
- let el = rootTC.debugElement.query(By.css('button'));
- el.triggerEventHandler('click', null);
-
- // toPromise() does not fulfill until emitter is completed by `return()`
- hdc.delete.return();
-
- return p;
- });
-
- }));
-
- it('Update button should modify hero', injectTcb(tcb => {
-
- let template =
- `
- Update
-
-
`
-
- return tcb
- .overrideTemplate(HeroDetailComponent, template)
- .createAsync(HeroDetailComponent)
- .then((rootTC: RTC) => {
-
- let hdc: HeroDetailComponent = rootTC.debugElement.componentInstance;
- hdc.hero = new Hero(42, 'Cat Woman');
- let origNameLength = hdc.hero.name.length;
-
- // trigger the 'click' event on the HeroDetailComponent update button
- rootTC.debugElement.query(By.css('#update'))
- .triggerEventHandler('click', null);
-
- expect(hdc.hero.name.length).toBeGreaterThan(origNameLength);
- });
- }));
-
- it('Entering hero name in textbox changes hero', injectTcb(tcb => {
-
- let hdc: HeroDetailComponent
- let template = ` `
-
- return tcb
- .overrideTemplate(HeroDetailComponent, template)
- .createAsync(HeroDetailComponent)
- .then((rootTC: RTC) => {
-
- hdc = rootTC.debugElement.componentInstance;
-
- hdc.hero = new Hero(42, 'Cat Woman');
- rootTC.detectChanges();
-
- // get the HTML element and change its value in the DOM
- var input = rootTC.debugElement.query(By.css('input')).nativeElement;
- input.value = "Dog Man"
- dispatchEvent(input, 'change'); // event triggers Ng to update model
-
- rootTC.detectChanges();
- // model update hasn't happened yet, despite `detectChanges`
- expect(hdc.hero.name).toEqual('Cat Woman');
-
- })
- .then(tick) // must wait a tick for the model update
- .then(() => {
- expect(hdc.hero.name).toEqual('Dog Man');
- });
- }));
-
- // Simulates ...
- // 1. change a hero
- // 2. select a different hero
- // 3 re-select the first hero
- // 4. confirm that the change is preserved in HTML
- // Reveals 2-way binding bug in alpha-36, fixed in pull #3715 for alpha-37
-
- it('toggling heroes after modifying name preserves the change on screen', injectTcb(tcb => {
-
- let hdc: HeroDetailComponent;
- let hero1 = new Hero(1, 'Cat Woman');
- let hero2 = new Hero(2, 'Goat Boy');
- let input: HTMLInputElement;
- let rootTC: RTC;
- let template = `{{hero.id}} - `
-
- return tcb
- .overrideTemplate(HeroDetailComponent, template)
- .createAsync(HeroDetailComponent)
- .then((rtc: RTC) => {
- rootTC = rtc;
- hdc = rootTC.debugElement.componentInstance;
-
- hdc.hero = hero1; // start with hero1
- rootTC.detectChanges();
-
- // get the HTML element and change its value in the DOM
- input = rootTC.debugElement.query(By.css('input')).nativeElement;
- input.value = "Dog Man"
- dispatchEvent(input, 'change'); // event triggers Ng to update model
- })
- .then(tick) // must wait a tick for the model update
- .then(() => {
- expect(hdc.hero.name).toEqual('Dog Man');
-
- hdc.hero = hero2 // switch to hero2
- rootTC.detectChanges();
-
- hdc.hero = hero1 // switch back to hero1
- rootTC.detectChanges();
-
- // model value will be the same changed value (of course)
- expect(hdc.hero.name).toEqual('Dog Man');
-
- // the view should reflect the same changed value
- expect(input.value).toEqual('Dog Man');
- });
- }));
- });
-});
diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.wrapped-tests.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.wrapped-tests.spec.ts.not-yet
deleted file mode 100644
index 319ac93ebf..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.wrapped-tests.spec.ts.not-yet
+++ /dev/null
@@ -1,144 +0,0 @@
-///// Boiler Plate ////
-import {bind, Component, Directive, EventEmitter, FORM_DIRECTIVES, View} from 'angular2/angular2';
-
-// Angular 2 Test Bed
-import {
- beforeEachProviders, By, DebugElement, RootTestComponent as RTC,
- beforeEach, ddescribe, xdescribe, describe, expect, iit, it, xit // Jasmine wrappers
-} from 'angular2/testing';
-
-import {injectAsync, injectTcb} from '../test-helpers/test-helpers';
-
-///// Testing this component ////
-import {HeroDetailComponent} from './hero-detail.component';
-import {Hero} from './hero';
-
-describe('HeroDetailComponent', () => {
-
- it('can be created', () => {
- let hc = new HeroDetailComponent()
- expect(hc instanceof HeroDetailComponent).toEqual(true); // proof of life
- });
-
- it('parent "currentHero" flows down to HeroDetailComponent', injectTcb( tcb => {
- return tcb
- .createAsync(TestWrapper)
- .then((rootTC:RTC) => {
- let hc:HeroDetailComponent = rootTC.componentViewChildren[0].componentInstance;
- let hw:TestWrapper = rootTC.componentInstance;
-
- rootTC.detectChanges(); // trigger view binding
-
- expect(hw.currentHero).toBe(hc.hero);
- });
- }));
-
- it('delete button should raise delete event for parent component', injectTcb( tcb => {
-
- return tcb
- //.overrideTemplate(HeroDetailComponent, 'Delete ')
- .overrideDirective(TestWrapper, HeroDetailComponent, mockHDC)
- .createAsync(TestWrapper)
- .then((rootTC:RTC) => {
-
- let hw:TestWrapper = rootTC.componentInstance;
- let hdcElement = rootTC.componentViewChildren[0];
- let hdc:HeroDetailComponent = hdcElement.componentInstance;
-
- rootTC.detectChanges(); // trigger view binding
-
- // We can watch the HeroComponent.delete EventEmitter's event
- let subscription = hdc.delete.toRx().subscribe(() => {
- console.log('HeroComponent.delete event raised');
- subscription.dispose();
- });
-
- // We can EITHER invoke HeroComponent delete button handler OR
- // trigger the 'click' event on the delete HeroComponent button
- // BUT DON'T DO BOTH
-
- // Trigger event
- // FRAGILE because assumes precise knowledge of HeroComponent template
- hdcElement
- .query(By.css('#delete'))
- .triggerEventHandler('click', {});
-
- hw.testCallback = () => {
- // if wrapper.onDelete is called, HeroComponent.delete event must have been raised
- //console.log('HeroWrapper.onDelete called');
- expect(true).toEqual(true);
- }
- // hc.onDelete();
- });
- }), 500); // needs some time for event to complete; 100ms is not long enough
-
- it('update button should modify hero', injectTcb( tcb => {
-
- return tcb
- .createAsync(TestWrapper)
- .then((rootTC:RTC) => {
-
- let hc:HeroDetailComponent = rootTC.componentViewChildren[0].componentInstance;
- let hw:TestWrapper = rootTC.componentInstance;
- let origNameLength = hw.currentHero.name.length;
-
- rootTC.detectChanges(); // trigger view binding
-
- // We can EITHER invoke HeroComponent update button handler OR
- // trigger the 'click' event on the HeroComponent update button
- // BUT DON'T DO BOTH
-
- // Trigger event
- // FRAGILE because assumes precise knowledge of HeroComponent template
- rootTC.componentViewChildren[0]
- .componentViewChildren[2]
- .triggerEventHandler('click', {});
-
- // hc.onUpdate(); // Invoke button handler
- expect(hw.currentHero.name.length).toBeGreaterThan(origNameLength);
- });
- }));
-
-});
-
-///// Test Components ////////
-
-// TestWrapper is a convenient way to communicate w/ HeroDetailComponent in a test
-@Component({selector: 'hero-wrapper'})
-@View({
- template: ` `,
- directives: [HeroDetailComponent]
-})
-class TestWrapper {
- currentHero = new Hero(42, 'Cat Woman');
- userName = 'Sally';
- testCallback() {} // monkey-punched in a test
- onDelete() { this.testCallback(); }
-}
-
-@View({
- template: `
-
-
{{hero.name}} | {{userName}}
-
Delete
-
Update
-
{{hero.id}}
-
-
`,
- directives: [FORM_DIRECTIVES]
-})
-class mockHDC //extends HeroDetailComponent { }
-{
- hero: Hero;
-
- delete = new EventEmitter();
-
- onDelete() { this.delete.next(this.hero) }
-
- onUpdate() {
- if (this.hero) {
- this.hero.name += 'x';
- }
- }
- userName: string;
-}
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero.service.ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero.service.ng.spec.ts.not-yet
deleted file mode 100644
index a3e4c0c6a4..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/hero.service.ng.spec.ts.not-yet
+++ /dev/null
@@ -1,198 +0,0 @@
-// Test a service when Angular DI is in play
-
-// Angular 2 Test Bed
-import {
- beforeEach, xdescribe, describe, it, xit, // Jasmine wrappers
- beforeEachProviders, inject, injectAsync,
-} from 'angular2/testing';
-
-import {bind} from 'angular2/core';
-
-// Service related imports
-import {HeroService} from './hero.service';
-import {BackendService} from './backend.service';
-import {Hero} from './hero';
-
-////// tests ////////////
-
-describe('HeroService (with angular DI)', () => {
-
- beforeEachProviders(() => [HeroService]);
-
- describe('creation', () => {
-
- beforeEachProviders( () => [bind(BackendService).toValue(null)] );
-
- it('can instantiate the service',
- inject([HeroService], (service: HeroService) => {
- expect(service).toBeDefined();
- }));
-
- it('service.heroes is empty',
- inject([HeroService], (service: HeroService) => {
- expect(service.heroes.length).toEqual(0);
- }));
- });
-
- describe('#refresh', () => {
-
- describe('when backend provides data', () => {
-
- beforeEach(() => {
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3,'Baz')];
- });
-
- beforeEachProviders(() =>
- [bind(BackendService).toClass(HappyBackendService)]
- );
-
- it('refresh promise returns expected # of heroes when fulfilled',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh().then(heroes =>
- expect(heroes.length).toEqual(heroData.length)
- );
- }));
-
- it('service.heroes has expected # of heroes when fulfilled',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh().then(() =>
- expect(service.heroes.length).toEqual(heroData.length)
- );
- }));
-
- it('service.heroes remains empty until fulfilled',
- inject([HeroService], (service: HeroService) => {
-
- service.refresh();
-
- // executed before refresh completes
- expect(service.heroes.length).toEqual(0);
- }));
-
- it('service.heroes remains empty when the server returns no data',
- injectAsync([HeroService], (service: HeroService) => {
-
- heroData = []; // simulate no heroes from the backend
-
- return service.refresh().then(() =>
- expect(service.heroes.length).toEqual(0)
- );
- }));
-
- it('resets service.heroes w/ original data after re-refresh',
- injectAsync([HeroService], (service: HeroService) => {
-
- let firstHeroes: Hero[];
- let changedName = 'Gerry Mander';
-
- return service.refresh().then(heroes => {
- firstHeroes = heroes; // remember array reference
-
- // Changes to cache! Should disappear after refresh
- service.heroes[0].name = changedName;
- service.heroes.push(new Hero(33, 'Hercules'));
- return service.refresh()
- })
- .then(() => {
- expect(firstHeroes).toBe(service.heroes); // same object
- expect(service.heroes.length).toEqual(heroData.length); // no Hercules
- expect(service.heroes[0].name).not.toEqual(changedName); // reverted name change
- });
- }));
-
- it('clears service.heroes while waiting for re-refresh',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh().then(() => {
- service.refresh();
- expect(service.heroes.length).toEqual(0);
- });
- }));
- // the paranoid will verify not only that the array lengths are the same
- // but also that the contents are the same.
- it('service.heroes has expected heroes when fulfilled (paranoia)',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh().then(() => {
- expect(service.heroes.length).toEqual(heroData.length);
- service.heroes.forEach(h =>
- expect(heroData.some(
- // hero instances are not the same objects but
- // each hero in result matches an original hero by value
- hd => hd.name === h.name && hd.id === h.id)
- )
- );
- });
- }));
-
- });
-
- describe('when backend throws an error', () => {
-
- beforeEachProviders(() =>
- [bind(BackendService).toClass(FailingBackendService)]
- );
-
- it('returns failed promise with the server error',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh()
- .then(() => fail('refresh should have failed'))
- .catch(err => expect(err).toBe(testError));
- }));
-
- it('resets heroes array to empty',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh()
- .then(() => fail('refresh should have failed'))
- .catch(err => expect(service.heroes.length).toEqual(0))
- }));
- });
-
- describe('when backend throws an error (spy version)', () => {
-
- beforeEachProviders(() => [BackendService]);
-
- beforeEach(inject([BackendService], (backend: BackendService) =>
- spyOn(backend, 'fetchAllHeroesAsync').and.callFake(() => Promise.reject(testError)
- )));
-
- it('returns failed promise with the server error',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh()
- .then(() => fail('refresh should have failed'))
- .catch(err => expect(err).toBe(testError));
- }));
-
- it('resets heroes array to empty',
- injectAsync([HeroService], (service: HeroService) => {
-
- return service.refresh()
- .then(() => fail('refresh should have failed'))
- .catch(err => expect(service.heroes.length).toEqual(0))
- }));
- });
-
- });
-});
-///////// test helpers /////////
-var service: HeroService;
-var heroData: Hero[];
-
-class HappyBackendService {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync = () =>
- Promise.resolve(heroData.map(h => h.clone()));
-}
-
-var testError = 'BackendService.fetchAllHeroesAsync failed on purpose';
-
-class FailingBackendService {
- // return a promise that fails as quickly as possible
- fetchAllHeroesAsync = () =>
- Promise.reject(testError);
-}
diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.1.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.1.spec.ts.not-yet
deleted file mode 100644
index 89cbc597f8..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.1.spec.ts.not-yet
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Dev Guide steps to hero.service.no-ng.spec
- * Try it with unit-tests-4.html
- */
-
-// The phase of hero-service-spec
-// when we're outlining what we want to test
-describe('HeroService (test plan)', () => {
-
- describe('creation', () => {
- xit('can instantiate the service');
- xit('service.heroes is empty');
- });
-
- describe('#refresh', () => {
-
- describe('when server provides heroes', () => {
- xit('refresh promise returns expected # of heroes when fulfilled');
- xit('service.heroes has expected # of heroes when fulfilled');
- xit('service.heroes remains empty until fulfilled');
- xit('service.heroes remains empty when the server returns no data');
- xit('resets service.heroes w/ original data after re-refresh');
- xit('clears service.heroes while waiting for re-refresh');
- });
-
- describe('when the server fails', () => {
- xit('returns failed promise with the server error');
- xit('clears service.heroes');
- });
-
- });
-
-});
-
-import {HeroService} from './hero.service';
-
-describe('HeroService (beginning tests - 1)', () => {
-
- describe('creation', () => {
- it('can instantiate the service', () => {
- let service = new HeroService(null);
- expect(service).toBeDefined();
- });
-
- it('heroes is empty', () => {
- let service = new HeroService(null);
- expect(service.heroes.length).toEqual(0);
- });
-
- });
-
-});
-
-import {BackendService} from './backend.service';
-import {Hero} from './hero';
-
-xdescribe('HeroService (beginning tests - 2 [dont run])', () => {
- let heroData:Hero[];
-
- // No good!
- it('refresh promise returns expected # of heroes when fulfilled', () => {
- let service = new HeroService(null);
- service.refresh().then(heroes => {
- expect(heroes.length).toBeGreaterThan(0); // don’t know how many to expect yet
- });
- });
-
- // better ... but not async!
- it('refresh promise returns expected # of heroes when fulfilled', () => {
-
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
-
- let backend = {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync: () => Promise.resolve(heroData)
- };
-
- let service = new HeroService(backend);
- service.refresh().then(heroes => {
- expect(heroes.length).toEqual(heroData.length); // is it?
- expect(heroes.length).not.toEqual(heroData.length); // or is it not?
- console.log('** inside callback **');
- });
-
- console.log('** end of test **');
- });
-
- // better ... but forgot to call done!
- it('refresh promise returns expected # of heroes when fulfilled', done => {
-
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
-
- let backend = {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync: () => Promise.resolve(heroData)
- };
-
- let service = new HeroService(backend);
- service.refresh().then(heroes => {
- expect(heroes.length).toEqual(heroData.length); // is it?
- expect(heroes.length).not.toEqual(heroData.length); // or is it not?
- console.log('** inside callback **');
- });
-
- console.log('** end of test **');
- });
-});
-
-describe('HeroService (beginning tests - 3 [async])', () => {
-
- let heroData:Hero[];
- // Now it's proper async!
- it('refresh promise returns expected # of heroes when fulfilled', done => {
-
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
-
- let backend = {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync: () => Promise.resolve(heroData)
- };
-
- let service = new HeroService(backend);
- service.refresh().then(heroes => {
- expect(heroes.length).toEqual(heroData.length); // is it?
- //expect(heroes.length).not.toEqual(heroData.length); // or is it not?
- console.log('** inside callback **');
- done();
- });
-
- console.log('** end of test **');
- });
-
- // Final before catch
- it('refresh promise returns expected # of heroes when fulfilled', done => {
-
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
-
- let backend = {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync: () => Promise.resolve(heroData)
- };
-
- let service = new HeroService(backend);
- service.refresh().then(heroes => {
- expect(heroes.length).toEqual(heroData.length);
- })
- .then(done);
- });
-
- // Final before beforeEach refactoring
- it('refresh promise returns expected # of heroes when fulfilled', done => {
-
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
-
- let backend = {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync: () => Promise.resolve(heroData)
- };
-
- let service = new HeroService(backend);
- service.refresh().then(heroes => {
- expect(heroes.length).toEqual(heroData.length);
- })
- .then(done, done.fail);
- });
-
- it('service.heroes remains empty until fulfilled', () => {
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
-
- let backend = {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync: () => Promise.resolve(heroData)
- };
-
- let service = new HeroService(backend);
- service.refresh();
-
- // executed before refresh completes
- expect(service.heroes.length).toEqual(0);
- });
-});
-
-
-describe('HeroService (beginning tests - 4 [beforeEach])', () => {
- let heroData:Hero[];
- let service:HeroService; // local to describe so tests can see it
-
- // before beforEach refactoring
- beforeEach(() => {
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3,'Baz')];
-
- let backend = {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync: () => Promise.resolve(heroData)
- };
-
- service = new HeroService(backend);
- });
-
- it('refresh promise returns expected # of heroes when fulfilled', done => {
- service.refresh().then(heroes =>
- expect(heroes.length).toEqual(heroData.length)
- )
- .then(done, done.fail);
- });
-
- it('service.heroes remains empty until fulfilled', () => {
- service.refresh();
-
- // executed before refresh completes
- expect(service.heroes.length).toEqual(0);
- });
-
-});
-
-describe('HeroService (beginning tests - 5 [refactored beforeEach])', () => {
-
- describe('when backend provides data', () => {
- beforeEach(() => {
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3,'Baz')];
- service = new HeroService(new HappyBackendService());
- });
-
- it('refresh promise returns expected # of heroes when fulfilled', done => {
- service.refresh().then(() =>
- expect(service.heroes.length).toEqual(heroData.length)
- )
- .then(done, done.fail);
- });
-
- it('service.heroes remains empty until fulfilled', () => {
- service.refresh();
-
- // executed before refresh completes
- expect(service.heroes.length).toEqual(0);
- });
- });
-
-});
-
-
-///////// test helpers /////////
-var service: HeroService;
-var heroData: Hero[];
-
-class HappyBackendService {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync = () =>
- Promise.resolve(heroData.map(h => h.clone()));
-}
diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.spec.ts.not-yet
deleted file mode 100644
index c2deb56c7c..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.spec.ts.not-yet
+++ /dev/null
@@ -1,150 +0,0 @@
-// Test a service without referencing Angular (no Angular DI)
-import {HeroService} from './hero.service';
-import {BackendService} from './backend.service';
-import {Hero} from './hero';
-
-////// tests ////////////
-
-describe('HeroService (no-angular)', () => {
-
- describe('creation', () => {
- it('can instantiate the service', () => {
- let service = new HeroService(null);
- expect(service).toBeDefined();
- });
-
- it('service.heroes is empty', () => {
- let service = new HeroService(null);
- expect(service.heroes.length).toEqual(0);
- });
- });
-
- describe('#refresh', () => {
-
- describe('when backend provides data', () => {
-
- beforeEach(() => {
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
- service = new HeroService(new HappyBackendService());
- });
-
-
- it('refresh promise returns expected # of heroes when fulfilled', done => {
- service.refresh().then(heroes =>
- expect(heroes.length).toEqual(heroData.length)
- )
- .then(done, done.fail);
- });
-
- it('service.heroes has expected # of heroes when fulfilled', done => {
- service.refresh().then(() =>
- expect(service.heroes.length).toEqual(heroData.length)
- )
- .then(done, done.fail);
- });
-
- it('service.heroes remains empty until fulfilled', () => {
- service.refresh();
-
- // executed before refresh completes
- expect(service.heroes.length).toEqual(0);
- });
-
- it('service.heroes remains empty when the server returns no data', done => {
- heroData = []; // simulate no heroes from the backend
-
- service.refresh().then(() =>
- expect(service.heroes.length).toEqual(0)
- )
- .then(done, done.fail);
- });
-
- it('resets service.heroes w/ original data after re-refresh', done => {
- let firstHeroes: Hero[];
- let changedName = 'Gerry Mander';
-
- service.refresh().then(() => {
- firstHeroes = service.heroes; // remember array reference
-
- // Changes to cache! Should disappear after refresh
- service.heroes[0].name = changedName;
- service.heroes.push(new Hero(33, 'Hercules'));
- return service.refresh()
- })
- .then(() => {
- expect(firstHeroes).toBe(service.heroes); // same array
- expect(service.heroes.length).toEqual(heroData.length); // no Hercules
- expect(service.heroes[0].name).not.toEqual(changedName); // reverted name change
- })
- .then(done, done.fail);
- });
-
- it('clears service.heroes while waiting for re-refresh', done => {
- service.refresh().then(() => {
- service.refresh();
- expect(service.heroes.length).toEqual(0);
- })
- .then(done, done.fail);
- });
-
- // the paranoid will verify not only that the array lengths are the same
- // but also that the contents are the same.
- it('service.heroes has expected heroes when fulfilled (paranoia)', done => {
- service.refresh().then(() => {
- expect(service.heroes.length).toEqual(heroData.length);
- service.heroes.forEach(h =>
- expect(heroData.some(
- // hero instances are not the same objects but
- // each hero in result matches an original hero by value
- hd => hd.name === h.name && hd.id === h.id)
- )
- );
- })
- .then(done, done.fail);
- });
-
- });
-
- describe('when backend throws an error', () => {
-
- beforeEach(() => {
- service = new HeroService(new FailingBackendService());
- });
-
- it('returns failed promise with the server error', done => {
- service.refresh()
- .then(() => fail('refresh should have failed'))
- .catch(err => expect(err).toEqual(testError))
- .then(done, done.fail);
- });
-
- it('clears service.heroes', done => {
- service.refresh()
- .then(() => fail('refresh should have failed'))
- .catch(err => expect(service.heroes.length).toEqual(0))
- .then(done, done.fail);
- });
-
- });
- });
-});
-
-///////// test helpers /////////
-
-var service: HeroService;
-var heroData: Hero[];
-
-class HappyBackendService {
- // return a promise for fake heroes that resolves as quickly as possible
- fetchAllHeroesAsync = () =>
- Promise.resolve(heroData.map(h => h.clone()));
-}
-
-var testError = 'BackendService.fetchAllHeroesAsync failed on purpose';
-
-class FailingBackendService {
- // return a promise that fails as quickly as possible
- // force-cast it to because of TS typing bug.
- fetchAllHeroesAsync = () =>
- >Promise.reject(testError);
-}
diff --git a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/heroes.component.ng.spec.ts.not-yet
deleted file mode 100644
index 489745ca2b..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.ng.spec.ts.not-yet
+++ /dev/null
@@ -1,276 +0,0 @@
-///// Angular 2 Test Bed ////
-import {bind, By} from 'angular2/angular2';
-
-import {
- beforeEach, xdescribe, describe, it, xit, // Jasmine wrappers
- beforeEachProviders,
- injectAsync,
- RootTestComponent as RTC,
- TestComponentBuilder as TCB
-} from 'angular2/testing';
-
-import {
- expectSelectedHtml,
- expectViewChildHtml,
- expectViewChildClass,
- injectTcb, tick} from '../test-helpers/test-helpers';
-
-///// Testing this component ////
-import {HeroesComponent} from './heroes.component';
-import {Hero} from './hero';
-import {HeroService} from './hero.service';
-import {User} from './user';
-
-let hc: HeroesComponent;
-let heroData: Hero[]; // fresh heroes for each test
-let mockUser: User;
-let service: HeroService;
-
-// get the promise from the refresh spy;
-// casting required because of inadequate d.ts for Jasmine
-let refreshPromise = () => (service.refresh).calls.mostRecent().returnValue;
-
-describe('HeroesComponent (with Angular)', () => {
-
- beforeEach(() => {
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
- mockUser = new User();
- });
-
- // Set up DI bindings required by component (and its nested components?)
- // else hangs silently forever
- beforeEachProviders(() => [
- bind(HeroService).toClass(HappyHeroService),
- bind(User).toValue(mockUser)
- ]);
-
- // test-lib bug? first test fails unless this no-op test runs first
- it('ignore this test', () => expect(true).toEqual(true)); // hack
-
- it('can be created and has userName', injectTcb((tcb:TCB) => {
- let template = '';
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then((rootTC: RTC) => {
- hc = rootTC.debugElement.componentInstance;
- expect(hc).toBeDefined();// proof of life
- expect(hc.userName).toEqual(mockUser.name);
- });
- }));
-
- it('binds view to userName', injectTcb((tcb:TCB) => {
- let template = `{{userName}}'s Heroes `;
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then((rootTC: RTC) => {
- hc = rootTC.debugElement.componentInstance;
-
- rootTC.detectChanges(); // trigger component property binding
- expectSelectedHtml(rootTC, 'h1').toMatch(hc.userName);
- expectViewChildHtml(rootTC).toMatch(hc.userName);
- });
- }));
-
- describe('#onInit', () => {
- let template = '';
-
- it('HeroService.refresh not called immediately',
- injectTcb([HeroService], (tcb:TCB, heroService:HeroService) => {
-
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then(() => {
- let spy = heroService.refresh;
- expect(spy.calls.count()).toEqual(0);
- });
- }));
-
- it('onInit calls HeroService.refresh',
- injectTcb([HeroService], (tcb:TCB, heroService:HeroService) => {
-
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then((rootTC: RTC) => {
- hc = rootTC.debugElement.componentInstance;
- let spy = heroService.refresh;
- hc.ngOnInit(); // Angular framework calls when it creates the component
- expect(spy.calls.count()).toEqual(1);
- });
- }));
-
- it('onInit is called after the test calls detectChanges', injectTcb((tcb:TCB) => {
-
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then((rootTC: RTC) => {
- hc = rootTC.debugElement.componentInstance;
- let spy = spyOn(hc, 'onInit').and.callThrough();
-
- expect(spy.calls.count()).toEqual(0);
- rootTC.detectChanges();
- expect(spy.calls.count()).toEqual(1);
- });
- }));
- })
-
- describe('#heroes', () => {
- // focus on the part of the template that displays heroe names
- let template =
- '';
-
- it('binds view to heroes', injectTcb((tcb:TCB) => {
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then((rootTC: RTC) => {
- // trigger {{heroes}} binding
- rootTC.detectChanges();
-
- // hc.heroes is still empty; need a JS cycle to get the data
- return rootTC;
- })
- .then((rootTC: RTC) => {
- hc = rootTC.debugElement.componentInstance;
- // now heroes are available for binding
- expect(hc.heroes.length).toEqual(heroData.length);
-
- rootTC.detectChanges(); // trigger component property binding
-
- // confirm hero list is displayed by looking for a known hero
- expect(rootTC.debugElement.nativeElement.innerHTML).toMatch(heroData[0].name);
- });
- }));
-
- // ... add more tests of component behavior affecting the heroes list
-
- });
-
- describe('#onSelected', () => {
-
- it('no hero is selected by default', injectHC(hc => {
- expect(hc.currentHero).not.toBeDefined();
- }));
-
- it('sets the "currentHero"', injectHC(hc => {
- hc.onSelect(heroData[1]); // select the second hero
- expect(hc.currentHero).toEqual(heroData[1]);
- }));
-
- it('no hero is selected after onRefresh() called', injectHC(hc => {
- hc.onSelect(heroData[1]); // select the second hero
- hc.onRefresh();
- expect(hc.currentHero).not.toBeDefined();
- }));
-
- // TODO: Remove `withNgClass=true` ONCE BUG IS FIXED
- xit('the view of the "currentHero" has the "selected" class (NG2 BUG)', injectHC((hc, rootTC) => {
- hc.onSelect(heroData[1]); // select the second hero
-
- rootTC.detectChanges();
-
- // The 3rd ViewChild is 2nd hero; the 1st is for the template
- expectViewChildClass(rootTC, 2).toMatch('selected');
- }, true /* true == include ngClass */));
-
- it('the view of a non-selected hero does NOT have the "selected" class', injectHC((hc, rootTC) => {
- hc.onSelect(heroData[1]); // select the second hero
- rootTC.detectChanges();
- // The 4th ViewChild is 3rd hero; the 1st is for the template
- expectViewChildClass(rootTC, 4).not.toMatch('selected');
- }));
-
- });
-
- // Most #onDelete tests not re-implemented because
- // writing those tests w/in Angular adds little value and
- // is far more painful than writing them to run outside Angular
- // Only bother with the one test that checks the DOM
- describe('#onDeleted', () => {
- let template =
- '';
-
- it('the list view does not contain the "deleted" currentHero', injectTcb((tcb:TCB) => {
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then((rootTC: RTC) => {
- hc = rootTC.debugElement.componentInstance;
- // trigger {{heroes}} binding
- rootTC.detectChanges();
- return rootTC; // wait for heroes to arrive
- })
- .then((rootTC: RTC) => {
- hc.currentHero = heroData[1];
- hc.onDelete()
- rootTC.detectChanges(); // trigger component property binding
-
- // confirm hero list is not displayed by looking for removed hero
- expect(rootTC.debugElement.nativeElement.innerHTML).not.toMatch(heroData[1].name);
- });
- }));
- });
-});
-
-////// Helpers //////
-
-class HappyHeroService {
-
- constructor() {
- spyOn(this, 'refresh').and.callThrough();
- }
-
- heroes: Hero[];
-
- refresh() {
- this.heroes = [];
- // updates cached heroes after one JavaScript cycle
- return new Promise((resolve, reject) => {
- this.heroes.push(...heroData);
- resolve(this.heroes);
- });
- }
-}
-
-
-// The same setup for every test in the #onSelected suite
-// TODO: Remove `withNgClass` and always include in template ONCE BUG IS FIXED
-function injectHC(testFn: (hc: HeroesComponent, rootTC?: RTC) => void, withNgClass:boolean = false) {
-
- // This is the bad boy: [ngClass]="getSelectedClass(hero)"
- let ngClass = withNgClass ? '[ngClass]="getSelectedClass(hero)"' : '';
-
- // focus on the part of the template that displays heroes
- let template =
- `
- ({{hero.id}}) {{hero.name}}
- `;
-
- return injectTcb((tcb:TCB) => {
- let hc: HeroesComponent;
-
- return tcb
- .overrideTemplate(HeroesComponent, template)
- .createAsync(HeroesComponent)
- .then((rootTC:RTC) => {
- hc = rootTC.debugElement.componentInstance;
- rootTC.detectChanges();// trigger {{heroes}} binding
- return rootTC;
- })
- .then((rootTC:RTC) => { // wait a tick until heroes are fetched
-console.error("WAS THIS FIXED??");
- // CRASHING HERE IF TEMPLATE HAS '[ngClass]="getSelectedClass(hero)"'
- // WITH EXCEPTION:
- // "Expression 'getSelectedClass(hero) in null' has changed after it was checked."
-
- rootTC.detectChanges(); // show the list
- testFn(hc, rootTC);
- });
- })
-}
diff --git a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.no-ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/heroes.component.no-ng.spec.ts.not-yet
deleted file mode 100644
index b1c1f2cff8..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.no-ng.spec.ts.not-yet
+++ /dev/null
@@ -1,229 +0,0 @@
-import {HeroesComponent} from './heroes.component';
-import {Hero} from './hero';
-import {HeroService} from './hero.service';
-import {User} from './user';
-
-describe('HeroesComponent (Test Plan)', () => {
- xit('can be created');
- xit('has expected userName');
-
- describe('#onInit', () => {
- xit('HeroService.refresh not called immediately');
- xit('onInit calls HeroService.refresh');
- });
-
- describe('#heroes', () => {
- xit('lacks heroes when created');
- xit('has heroes after cache loaded');
- xit('restores heroes after refresh called again');
-
- xit('binds view to heroes');
- });
-
- describe('#onSelected', () => {
- xit('no hero is selected by default');
- xit('sets the "currentHero"');
- xit('no hero is selected after onRefresh() called');
-
- xit('the view of the "currentHero" has the "selected" class (NG2 BUG)');
- xit('the view of a non-selected hero does NOT have the "selected" class');
- });
-
- describe('#onDelete', () => {
- xit('removes the supplied hero (only) from the list');
- xit('removes the currentHero from the list if no hero argument');
- xit('is harmless if no supplied or current hero');
- xit('is harmless if hero not in list');
- xit('is harmless if the list is empty');
- xit('the new currentHero is the one after the removed hero');
- xit('the new currentHero is the one before the removed hero if none after');
-
- xit('the list view does not contain the "deleted" currentHero');
- });
-});
-
-let hc:HeroesComponent;
-let heroData: Hero[]; // fresh heroes for each test
-let mockUser: User;
-let service: HeroService;
-
-// get the promise from the refresh spy;
-// casting required because of inadequate d.ts for Jasmine
-let refreshPromise = () => (service.refresh).calls.mostRecent().returnValue;
-
-describe('HeroesComponent (no Angular)', () => {
-
- beforeEach(()=> {
- heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')];
- mockUser = new User();
- });
-
- beforeEach(()=> {
- service = new HappyHeroService();
- hc = new HeroesComponent(service, mockUser)
- });
-
- it('can be created', () => {
- expect(hc instanceof HeroesComponent).toEqual(true); // proof of life
- });
-
- it('has expected userName', () => {
- expect(hc.userName).toEqual(mockUser.name);
- });
-
- describe('#onInit', () => {
- it('HeroService.refresh not called immediately', () => {
- let spy = service.refresh;
- expect(spy.calls.count()).toEqual(0);
- });
-
- it('onInit calls HeroService.refresh', () => {
- let spy = service.refresh;
- hc.ngOnInit(); // Angular framework calls when it creates the component
- expect(spy.calls.count()).toEqual(1);
- });
- })
-
- describe('#heroes', () => {
-
- it('lacks heroes when created', () => {
- let heroes = hc.heroes;
- expect(heroes.length).toEqual(0); // not filled yet
- });
-
- it('has heroes after cache loaded', done => {
- hc.ngOnInit(); // Angular framework calls when it creates the component
-
- refreshPromise().then(() => {
- let heroes = hc.heroes; // now the component has heroes to show
- expect(heroes.length).toEqual(heroData.length);
- })
- .then(done, done.fail);
- });
-
- it('restores heroes after refresh called again', done => {
- hc.ngOnInit(); // component initialization triggers service
- let heroes: Hero[];
-
- refreshPromise().then(() => {
- heroes = hc.heroes; // now the component has heroes to show
- heroes[0].name = 'Wotan';
- heroes.push(new Hero(33, 'Thor'));
- hc.onRefresh();
- })
- .then(() => {
- heroes = hc.heroes; // get it again (don't reuse old array!)
- expect(heroes[0]).not.toEqual('Wotan'); // change reversed
- expect(heroes.length).toEqual(heroData.length); // orig num of heroes
- })
- .then(done, done.fail);
- });
- });
-
- describe('#onSelected', () => {
-
- it('no hero is selected by default', () => {
- expect(hc.currentHero).not.toBeDefined();
- });
-
- it('sets the "currentHero"', () => {
- hc.onSelect(heroData[1]); // select the second hero
- expect(hc.currentHero).toEqual(heroData[1]);
- });
-
- it('no hero is selected after onRefresh() called', () => {
- hc.onSelect(heroData[1]); // select the second hero
- hc.onRefresh();
- expect(hc.currentHero).not.toBeDefined();
- });
- });
-
-
- describe('#onDelete', () => {
-
- // Load the heroes asynchronously before each test
- // Getting the async out of the way in the beforeEach
- // means tests can be synchronous
- // Note: could have cheated and simply plugged hc.heroes with fake data
- // that trick would fail if we reimplemented hc.heroes as a readonly property
- beforeEach(done => {
- hc.ngOnInit(); // Angular framework calls when it creates the component
- refreshPromise().then(done, done.fail);
- });
-
- it('removes the supplied hero (only) from the list', () => {
- hc.currentHero = heroData[1];
- let hero = heroData[2];
- hc.onDelete(hero);
-
- expect(hc.heroes).not.toContain(hero);
- expect(hc.heroes).toContain(heroData[1]); // left current in place
- expect(hc.heroes.length).toEqual(heroData.length - 1);
- });
-
- it('removes the currentHero from the list if no hero argument', () => {
- hc.currentHero = heroData[1];
- hc.onDelete();
- expect(hc.heroes).not.toContain(heroData[1]);
- });
-
- it('is harmless if no supplied or current hero', () => {
- hc.currentHero = null;
- hc.onDelete();
- expect(hc.heroes.length).toEqual(heroData.length);
- });
-
- it('is harmless if hero not in list', () => {
- let hero = heroData[1].clone(); // object reference matters, not id
- hc.onDelete(hero);
- expect(hc.heroes.length).toEqual(heroData.length);
- });
-
- // must go async to get hc to clear its heroes list
- it('is harmless if the list is empty', done => {
- let hero = heroData[1];
- heroData = [];
- hc.onRefresh();
- refreshPromise().then(() => {
- hc.onDelete(hero); // shouldn't fail
- })
- .then(done, done.fail);
- });
-
- it('the new currentHero is the one after the removed hero', () => {
- hc.currentHero = heroData[1];
- let expectedCurrent = heroData[2];
- hc.onDelete();
- expect(hc.currentHero).toBe(expectedCurrent);
- });
-
- it('the new currentHero is the one before the removed hero if none after', () => {
- hc.currentHero = heroData[heroData.length - 1]; // last hero
- let expectedCurrent = heroData[heroData.length - 2]; // penultimate hero
- hc.onDelete();
- expect(hc.currentHero).toBe(expectedCurrent);
- });
- });
-
-});
-
-
-////// Helpers //////
-
-class HappyHeroService {
-
- constructor() {
- spyOn(this, 'refresh').and.callThrough();
- }
-
- heroes: Hero[];
-
- refresh() {
- this.heroes = [];
- // updates cached heroes after one JavaScript cycle
- return new Promise((resolve, reject) => {
- this.heroes.push(...heroData);
- resolve(this.heroes);
- });
- }
-}
diff --git a/public/docs/_examples/testing/ts/app/old-specs/user.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/user.spec.ts.not-yet
deleted file mode 100644
index f65ac89a5e..0000000000
--- a/public/docs/_examples/testing/ts/app/old-specs/user.spec.ts.not-yet
+++ /dev/null
@@ -1,18 +0,0 @@
-import {User} from './user';
-
-describe('User', () => {
- let user:User;
-
- beforeEach(() => {
- user = new User();
- });
-
- it('has id === 42', () => {
- expect(user.id).toEqual(42);
- });
-
- it('has an email address', () => {
- expect(user.email.length).toBeGreaterThan(0);
- });
-
-});
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/app/shared/highlight.directive.spec.ts b/public/docs/_examples/testing/ts/app/shared/highlight.directive.spec.ts
new file mode 100644
index 0000000000..6c219ab808
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/highlight.directive.spec.ts
@@ -0,0 +1,100 @@
+import { Component, DebugElement } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { HighlightDirective } from './highlight.directive';
+import { newEvent } from '../../testing';
+
+// #docregion test-component
+@Component({
+ template: `
+ Something Yellow
+ The Default (Gray)
+ No Highlight
+ `
+})
+class TestComponent { }
+// #enddocregion test-component
+
+describe('HighlightDirective', () => {
+
+ let fixture: ComponentFixture;
+ let des: DebugElement[]; // the three elements w/ the directive
+ let bareH2: DebugElement; // the w/o the directive
+
+ // #docregion selected-tests
+ beforeEach(() => {
+ fixture = TestBed.configureTestingModule({
+ declarations: [ HighlightDirective, TestComponent ]
+ })
+ .createComponent(TestComponent);
+
+ fixture.detectChanges(); // initial binding
+
+ // all elements with an attached HighlightDirective
+ des = fixture.debugElement.queryAll(By.directive(HighlightDirective));
+
+ // the h2 without the HighlightDirective
+ bareH2 = fixture.debugElement.query(By.css('h2:not([highlight])'));
+ });
+
+ // color tests
+ it('should have three highlighted elements', () => {
+ expect(des.length).toBe(3);
+ });
+
+ it('should color 1st background "yellow"', () => {
+ expect(des[0].styles['backgroundColor']).toBe('yellow');
+ });
+
+ it('should color 2nd background w/ default color', () => {
+ const dir = des[1].injector.get(HighlightDirective) as HighlightDirective;
+ expect(des[1].styles['backgroundColor']).toBe(dir.defaultColor);
+ });
+
+ it('should bind background to value color', () => {
+ // easier to work with nativeElement
+ const input = des[2].nativeElement as HTMLInputElement;
+ expect(input.style.backgroundColor).toBe('cyan', 'initial backgroundColor');
+
+ // dispatch a DOM event so that Angular responds to the input value change.
+ input.value = 'green';
+ input.dispatchEvent(newEvent('input'));
+ fixture.detectChanges();
+
+ expect(input.style.backgroundColor).toBe('green', 'changed backgroundColor');
+ });
+
+ // customProperty tests
+ it('all highlighted elements should have a true customProperty', () => {
+ const allTrue = des.map(de => !!de.properties['customProperty']).every(v => v === true);
+ expect(allTrue).toBe(true);
+ });
+
+ it('bare should not have a customProperty', () => {
+ expect(bareH2.properties['customProperty']).toBeUndefined();
+ });
+ // #enddocregion selected-tests
+
+ // injected directive
+ // attached HighlightDirective can be injected
+ it('can inject `HighlightDirective` in 1st ', () => {
+ const dir = des[0].injector.get(HighlightDirective);
+ expect(dir).toBeTruthy();
+ });
+
+ it('cannot inject `HighlightDirective` in 3rd ', () => {
+ const dir = bareH2.injector.get(HighlightDirective, null);
+ expect(dir).toBe(null);
+ });
+
+ // DebugElement.providerTokens
+ // attached HighlightDirective should be listed in the providerTokens
+ it('should have `HighlightDirective` in 1st providerTokens', () => {
+ expect(des[0].providerTokens).toContain(HighlightDirective);
+ });
+
+ it('should not have `HighlightDirective` in 3rd providerTokens', () => {
+ expect(bareH2.providerTokens).not.toContain(HighlightDirective);
+ });
+});
diff --git a/public/docs/_examples/testing/ts/app/shared/highlight.directive.ts b/public/docs/_examples/testing/ts/app/shared/highlight.directive.ts
new file mode 100644
index 0000000000..4a45c8d5aa
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/highlight.directive.ts
@@ -0,0 +1,22 @@
+// #docregion
+import { Directive, ElementRef, Input, OnChanges, Renderer } from '@angular/core';
+
+@Directive({ selector: '[highlight]' })
+/** Set backgroundColor for the attached element to highlight color
+ * and set the element's customProperty to true */
+export class HighlightDirective implements OnChanges {
+
+ defaultColor = 'rgb(211, 211, 211)'; // lightgray
+
+ @Input('highlight') bgColor: string;
+
+ constructor(private renderer: Renderer, private el: ElementRef) {
+ renderer.setElementProperty(el.nativeElement, 'customProperty', true);
+ }
+
+ ngOnChanges() {
+ this.renderer.setElementStyle(
+ this.el.nativeElement, 'backgroundColor',
+ this.bgColor || this.defaultColor );
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/shared/shared.module.ts b/public/docs/_examples/testing/ts/app/shared/shared.module.ts
new file mode 100644
index 0000000000..17c41c0410
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/shared.module.ts
@@ -0,0 +1,15 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { HighlightDirective } from './highlight.directive';
+import { TitleCasePipe } from './title-case.pipe';
+import { TwainComponent } from './twain.component';
+
+@NgModule({
+ imports: [ CommonModule ],
+ exports: [ CommonModule, FormsModule,
+ HighlightDirective, TitleCasePipe, TwainComponent ],
+ declarations: [ HighlightDirective, TitleCasePipe, TwainComponent ]
+})
+export class SharedModule { }
diff --git a/public/docs/_examples/testing/ts/app/shared/title-case.pipe.spec.ts b/public/docs/_examples/testing/ts/app/shared/title-case.pipe.spec.ts
new file mode 100644
index 0000000000..7481537c10
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/title-case.pipe.spec.ts
@@ -0,0 +1,33 @@
+// #docplaster
+// #docregion
+import { TitleCasePipe } from './title-case.pipe';
+
+// #docregion excerpt
+describe('TitleCasePipe', () => {
+ // This pipe is a pure function so no need for BeforeEach
+ let pipe = new TitleCasePipe();
+
+ it('transforms "abc" to "Abc"', () => {
+ expect(pipe.transform('abc')).toBe('Abc');
+ });
+
+ it('transforms "abc def" to "Abc Def"', () => {
+ expect(pipe.transform('abc def')).toBe('Abc Def');
+ });
+
+ // ... more tests ...
+// #enddocregion excerpt
+ it('leaves "Abc Def" unchanged', () => {
+ expect(pipe.transform('Abc Def')).toBe('Abc Def');
+ });
+
+ it('transforms "abc-def" to "Abc-def"', () => {
+ expect(pipe.transform('abc-def')).toBe('Abc-def');
+ });
+
+ it('transforms " abc def" to " Abc Def" (preserves spaces) ', () => {
+ expect(pipe.transform(' abc def')).toBe(' Abc Def');
+ });
+// #docregion excerpt
+});
+// #enddocregion excerpt
diff --git a/public/docs/_examples/testing/ts/app/shared/title-case.pipe.ts b/public/docs/_examples/testing/ts/app/shared/title-case.pipe.ts
new file mode 100644
index 0000000000..df2567778d
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/title-case.pipe.ts
@@ -0,0 +1,11 @@
+// #docregion
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({name: 'titlecase', pure: false})
+/** Transform to Title Case: uppercase the first letter of the words in a string.*/
+export class TitleCasePipe implements PipeTransform {
+ transform(input: string): string {
+ return input.length === 0 ? '' :
+ input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() ));
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/shared/twain.component.spec.ts b/public/docs/_examples/testing/ts/app/shared/twain.component.spec.ts
new file mode 100644
index 0000000000..767e1ec2ca
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/twain.component.spec.ts
@@ -0,0 +1,92 @@
+// #docplaster
+import { async, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { TwainService } from './twain.service';
+import { TwainComponent } from './twain.component';
+
+describe('TwainComponent', () => {
+
+ let comp: TwainComponent;
+ let fixture: ComponentFixture;
+
+ let spy: jasmine.Spy;
+ let twainEl: DebugElement; // the element with the Twain quote
+ let twainService: TwainService; // the actually injected service
+
+ const testQuote = 'Test Quote';
+
+ // #docregion setup
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [ TwainComponent ],
+ providers: [ TwainService ],
+ });
+
+ fixture = TestBed.createComponent(TwainComponent);
+ comp = fixture.componentInstance;
+
+ // TwainService actually injected into the component
+ twainService = fixture.debugElement.injector.get(TwainService);
+
+ // Setup spy on the `getQuote` method
+ // #docregion spy
+ spy = spyOn(twainService, 'getQuote')
+ .and.returnValue(Promise.resolve(testQuote));
+ // #enddocregion spy
+
+ // Get the Twain quote element by CSS selector (e.g., by class name)
+ twainEl = fixture.debugElement.query(By.css('.twain'));
+ });
+ // #enddocregion setup
+
+ // #docregion tests
+ function getQuote() { return twainEl.nativeElement.textContent; }
+
+ it('should not show quote before OnInit', () => {
+ expect(getQuote()).toBe('', 'nothing displayed');
+ expect(spy.calls.any()).toBe(false, 'getQuote not yet called');
+ });
+
+ it('should still not show quote after component initialized', () => {
+ fixture.detectChanges(); // trigger data binding
+ // getQuote service is async => still has not returned with quote
+ expect(getQuote()).toBe('...', 'no quote yet');
+ expect(spy.calls.any()).toBe(true, 'getQuote called');
+ });
+
+ // #docregion async-test
+ it('should show quote after getQuote promise (async)', async(() => {
+ fixture.detectChanges(); // trigger data binding
+
+ fixture.whenStable().then(() => { // wait for async getQuote
+ fixture.detectChanges(); // update view with quote
+ expect(getQuote()).toBe(testQuote);
+ });
+ }));
+ // #enddocregion async-test
+
+ // #docregion fake-async-test
+ it('should show quote after getQuote promise (fakeAsync)', fakeAsync(() => {
+ fixture.detectChanges(); // trigger data binding
+ tick(); // wait for async getQuote
+ fixture.detectChanges(); // update view with quote
+ expect(getQuote()).toBe(testQuote);
+ }));
+ // #enddocregion fake-async-test
+ // #enddocregion tests
+
+ // #docregion done-test
+ it('should show quote after getQuote promise (done)', done => {
+ fixture.detectChanges(); // trigger data binding
+
+ // get the spy promise and wait for it to resolve
+ spy.calls.mostRecent().returnValue.then(() => {
+ fixture.detectChanges(); // update view with quote
+ expect(getQuote()).toBe(testQuote);
+ done();
+ });
+ });
+ // #enddocregion done-test
+});
diff --git a/public/docs/_examples/testing/ts/app/shared/twain.component.timer.spec.ts.no-work b/public/docs/_examples/testing/ts/app/shared/twain.component.timer.spec.ts.no-work
new file mode 100644
index 0000000000..74dec3e766
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/twain.component.timer.spec.ts.no-work
@@ -0,0 +1,116 @@
+// #docplaster
+// When AppComponent learns to present quote with intervalTimer
+import { async, discardPeriodicTasks, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { TwainService } from './model';
+import { TwainComponent } from './twain.component';
+
+xdescribe('TwainComponent', () => {
+
+ let comp: TwainComponent;
+ let fixture: ComponentFixture;
+
+ const quotes = [
+ 'Test Quote 1',
+ 'Test Quote 2',
+ 'Test Quote 3'
+ ];
+
+ let spy: jasmine.Spy;
+ let twainEl: DebugElement; // the element with the Twain quote
+ let twainService: TwainService; // the actually injected service
+
+ function getQuote() { return twainEl.nativeElement.textContent; }
+
+ // #docregion setup
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [ TwainComponent ],
+ providers: [ TwainService ],
+ });
+
+ fixture = TestBed.createComponent(TwainComponent);
+ comp = fixture.componentInstance;
+
+ // TwainService actually injected into the component
+ twainService = fixture.debugElement.injector.get(TwainService);
+
+ // Setup spy on the `getQuote` method
+ spy = spyOn(twainService, 'getQuote')
+ .and.returnValues(...quotes.map(q => Promise.resolve(q)));
+
+ // Get the Twain quote element by CSS selector (e.g., by class name)
+ twainEl = fixture.debugElement.query(By.css('.twain'));
+ });
+
+ afterEach(() => {
+ // destroy component to stop the component timer
+ fixture.destroy();
+ });
+ // #enddocregion setup
+
+ // #docregion tests
+ it('should not show quote before OnInit', () => {
+ expect(getQuote()).toBe('');
+ });
+
+ it('should still not show quote after component initialized', () => {
+ // because the getQuote service is async
+ fixture.detectChanges(); // trigger data binding
+ expect(getQuote()).toContain('not initialized');
+ });
+
+ // WIP
+ // If go this way, add jasmine.clock().uninstall(); to afterEach
+ // it('should show quote after Angular "settles"', async(() => {
+ // //jasmine.clock().install();
+ // fixture.detectChanges(); // trigger data binding
+ // fixture.whenStable().then(() => {
+ // fixture.detectChanges(); // update view with the quote
+ // expect(getQuote()).toBe(quotes[0]);
+ // });
+ // // jasmine.clock().tick(5000);
+ // // fixture.whenStable().then(() => {
+ // // fixture.detectChanges(); // update view with the quote
+ // // expect(getQuote()).toBe(quotes[1]);
+ // // });
+ // }));
+
+ it('should show quote after getQuote promise returns', fakeAsync(() => {
+ fixture.detectChanges(); // trigger data binding
+ tick(); // wait for first async getQuote to return
+ fixture.detectChanges(); // update view with the quote
+ expect(getQuote()).toBe(quotes[0]);
+
+ // destroy component to stop the component timer before test ends
+ // else test errors because still have timer in the queue
+ fixture.destroy();
+ }));
+
+ it('should show 2nd quote after 5 seconds pass', fakeAsync(() => {
+ fixture.detectChanges(); // trigger data binding
+ tick(5000); // wait for second async getQuote to return
+ fixture.detectChanges(); // update view with the quote
+ expect(getQuote()).toBe(quotes[1]);
+
+ // still have intervalTimer queuing requres
+ // discardPeriodicTasks() else test errors
+ discardPeriodicTasks();
+ }));
+
+ fit('should show 3rd quote after 10 seconds pass', fakeAsync(() => {
+ fixture.detectChanges(); // trigger data binding
+ tick(5000); // wait for second async getQuote to return
+ fixture.detectChanges(); // update view with the 2nd quote
+ tick(5000); // wait for third async getQuote to return
+ fixture.detectChanges(); // update view with the 3rd quote
+ expect(getQuote()).toBe(quotes[2]);
+
+ // still have intervalTimer queuing requres
+ // discardPeriodicTasks() else test errors
+ discardPeriodicTasks();
+ }));
+ // #enddocregion tests
+});
diff --git a/public/docs/_examples/testing/ts/app/shared/twain.component.timer.ts.no-work b/public/docs/_examples/testing/ts/app/shared/twain.component.timer.ts.no-work
new file mode 100644
index 0000000000..d3dc1f205d
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/twain.component.timer.ts.no-work
@@ -0,0 +1,27 @@
+// #docregion
+import { Component, OnInit, OnDestroy } from '@angular/core';
+
+import { TwainService } from './twain.service';
+
+@Component({
+ selector: 'twain-quote',
+ template: '{{quote}}
'
+})
+export class TwainComponent implements OnInit, OnDestroy {
+ intervalId: number;
+ quote = '-- not initialized yet --';
+ constructor(private twainService: TwainService) { }
+
+ getQuote() {
+ this.twainService.getQuote().then(quote => this.quote = quote);
+ }
+
+ ngOnInit(): void {
+ this.getQuote();
+ this.intervalId = window.setInterval(() => this.getQuote(), 5000);
+ }
+
+ ngOnDestroy(): void {
+ clearInterval(this.intervalId);
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/shared/twain.component.ts b/public/docs/_examples/testing/ts/app/shared/twain.component.ts
new file mode 100644
index 0000000000..29f24459ab
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/twain.component.ts
@@ -0,0 +1,20 @@
+// #docregion
+import { Component, OnInit } from '@angular/core';
+
+import { TwainService } from './twain.service';
+
+// #docregion component
+@Component({
+ selector: 'twain-quote',
+ template: '{{quote}}
'
+})
+export class TwainComponent implements OnInit {
+ intervalId: number;
+ quote = '...';
+ constructor(private twainService: TwainService) { }
+
+ ngOnInit(): void {
+ this.twainService.getQuote().then(quote => this.quote = quote);
+ }
+}
+// #enddocregion component
diff --git a/public/docs/_examples/testing/ts/app/shared/twain.service.ts b/public/docs/_examples/testing/ts/app/shared/twain.service.ts
new file mode 100644
index 0000000000..9e394df1ee
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/shared/twain.service.ts
@@ -0,0 +1,32 @@
+import { Injectable } from '@angular/core';
+
+const quotes = [
+'Always do right. This will gratify some people and astonish the rest.',
+'I have never let my schooling interfere with my education.',
+'Don\'t go around saying the world owes you a living. The world owes you nothing. It was here first.',
+'Whenever you find yourself on the side of the majority, it is time to pause and reflect.',
+'If you tell the truth, you don\'t have to remember anything.',
+'Clothes make the man. Naked people have little or no influence on society.',
+'It\'s not the size of the dog in the fight, it\'s the size of the fight in the dog.',
+'Truth is stranger than fiction, but it is because Fiction is obliged to stick to possibilities; Truth isn\'t.',
+'The man who does not read good books has no advantage over the man who cannot read them.',
+'Get your facts first, and then you can distort them as much as you please.',
+];
+
+@Injectable()
+export class TwainService {
+ private next = 0;
+
+ // Imaginary todo: get quotes from a remote quote service
+ // returns quote after delay simulating server latency
+ getQuote(): Promise {
+ return new Promise(resolve => {
+ setTimeout( () => resolve(this.nextQuote()), 500 );
+ });
+ }
+
+ private nextQuote() {
+ if (this.next === quotes.length) { this.next = 0; }
+ return quotes[ this.next++ ];
+ }
+}
diff --git a/public/docs/_examples/testing/ts/app/welcome.component.spec.ts b/public/docs/_examples/testing/ts/app/welcome.component.spec.ts
new file mode 100644
index 0000000000..f99687148f
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/welcome.component.spec.ts
@@ -0,0 +1,92 @@
+// #docplaster
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { UserService } from './model';
+import { WelcomeComponent } from './welcome.component';
+
+describe('WelcomeComponent', () => {
+
+ let comp: WelcomeComponent;
+ let fixture: ComponentFixture;
+ let userService: UserService; // the actually injected service
+ let welcomeEl: DebugElement; // the element with the welcome message
+
+ let userServiceStub: {
+ isLoggedIn: boolean;
+ user: { name: string}
+ };
+
+ // #docregion setup
+ beforeEach(() => {
+ // stub UserService for test purposes
+ // #docregion user-service-stub
+ userServiceStub = {
+ isLoggedIn: true,
+ user: { name: 'Test User'}
+ };
+ // #enddocregion user-service-stub
+
+ // #docregion config-test-module
+ TestBed.configureTestingModule({
+ declarations: [ WelcomeComponent ],
+ // #enddocregion setup
+ // providers: [ UserService ] // a real service would be a problem!
+ // #docregion setup
+ providers: [ {provide: UserService, useValue: userServiceStub } ]
+ });
+ // #enddocregion config-test-module
+
+ fixture = TestBed.createComponent(WelcomeComponent);
+ comp = fixture.componentInstance;
+
+ // #enddocregion setup
+ // #docregion inject-from-testbed
+ // UserService provided to the TestBed
+ userService = TestBed.get(UserService);
+ // #enddocregion inject-from-testbed
+ // #docregion setup
+ // #docregion injected-service
+ // UserService actually injected into the component
+ userService = fixture.debugElement.injector.get(UserService);
+ // #enddocregion injected-service
+
+ // get the "welcome" element by CSS selector (e.g., by class name)
+ welcomeEl = fixture.debugElement.query(By.css('.welcome'));
+ });
+ // #enddocregion setup
+
+ // #docregion tests
+ it('should welcome the user', () => {
+ fixture.detectChanges(); // trigger data binding
+
+ let content = welcomeEl.nativeElement.textContent;
+ expect(content).toContain('Welcome', '"Welcome ..."');
+ expect(content).toContain('Test User', 'expected name');
+ });
+
+ it('should welcome "Bubba"', () => {
+ userService.user.name = 'Bubba'; // welcome message hasn't been shown yet
+
+ fixture.detectChanges(); // trigger data binding
+
+ let content = welcomeEl.nativeElement.textContent;
+ expect(content).toContain('Bubba');
+ });
+
+ it('should request login if not logged in', () => {
+ userService.isLoggedIn = false; // welcome message hasn't been shown yet
+
+ fixture.detectChanges(); // trigger data binding
+
+ let content = welcomeEl.nativeElement.textContent;
+ expect(content).not.toContain('Welcome', 'not welcomed');
+ expect(content).toMatch(/log in/i, '"log in"');
+ });
+ // #enddocregion tests
+
+ it('orig stub and injected UserService are not the same object', () => {
+ expect(userServiceStub === userService).toBe(false);
+ });
+});
diff --git a/public/docs/_examples/testing/ts/app/welcome.component.ts b/public/docs/_examples/testing/ts/app/welcome.component.ts
new file mode 100644
index 0000000000..35958cc5c9
--- /dev/null
+++ b/public/docs/_examples/testing/ts/app/welcome.component.ts
@@ -0,0 +1,18 @@
+// #docregion
+import { Component, OnInit } from '@angular/core';
+import { UserService } from './model';
+
+@Component({
+ selector: 'app-welcome',
+ template: '{{welcome}} '
+})
+export class WelcomeComponent implements OnInit {
+ welcome = '-- not initialized yet --';
+ constructor(private userService: UserService) { }
+
+ ngOnInit(): void {
+ this.welcome = this.userService.isLoggedIn ?
+ 'Welcome, ' + this.userService.user.name :
+ 'Please log in.';
+ }
+}
diff --git a/public/docs/_examples/testing/ts/bag-specs.html b/public/docs/_examples/testing/ts/bag-specs.html
new file mode 100644
index 0000000000..792ebc113f
--- /dev/null
+++ b/public/docs/_examples/testing/ts/bag-specs.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ Specs Bag
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/docs/_examples/testing/ts/bag-specs.plnkr.json b/public/docs/_examples/testing/ts/bag-specs.plnkr.json
new file mode 100644
index 0000000000..89d86da28a
--- /dev/null
+++ b/public/docs/_examples/testing/ts/bag-specs.plnkr.json
@@ -0,0 +1,20 @@
+{
+ "description": "Testing - bag.specs",
+ "files":[
+ "browser-test-shim.js",
+ "systemjs.config.extras.js",
+ "styles.css",
+
+ "app/bag/**/*.html",
+ "app/bag/**/*.ts",
+ "app/bag/**/*.spec.ts",
+
+ "!app/bag/bag-main.ts",
+
+ "testing/*.ts",
+
+ "bag-specs.html"
+ ],
+ "main": "bag-specs.html",
+ "tags": ["testing"]
+}
diff --git a/public/docs/_examples/router-deprecated/ts/index.html b/public/docs/_examples/testing/ts/bag.html
similarity index 73%
rename from public/docs/_examples/router-deprecated/ts/index.html
rename to public/docs/_examples/testing/ts/bag.html
index 35a6ddfc73..35ff270025 100644
--- a/public/docs/_examples/router-deprecated/ts/index.html
+++ b/public/docs/_examples/testing/ts/bag.html
@@ -1,10 +1,9 @@
+
-
-
- Router (Deprecated) Sample
+ Specs Bag
@@ -18,13 +17,11 @@
- loading...
+ Loading ...
-
-
diff --git a/public/docs/_examples/testing/ts/bag.plnkr.json b/public/docs/_examples/testing/ts/bag.plnkr.json
new file mode 100644
index 0000000000..96e0b79b65
--- /dev/null
+++ b/public/docs/_examples/testing/ts/bag.plnkr.json
@@ -0,0 +1,13 @@
+{
+ "description": "Running the bag",
+ "files":[
+ "styles.css",
+
+ "app/bag/bag.ts",
+ "app/bag/bag-external-template.html",
+ "app/bag/bag-main.ts",
+ "bag.html"
+ ],
+ "main": "bag.html",
+ "tags": ["testing"]
+}
diff --git a/public/docs/_examples/testing/ts/browser-test-shim.js b/public/docs/_examples/testing/ts/browser-test-shim.js
new file mode 100644
index 0000000000..1573c72ebd
--- /dev/null
+++ b/public/docs/_examples/testing/ts/browser-test-shim.js
@@ -0,0 +1,87 @@
+// BROWSER TESTING SHIM
+// Keep it in-sync with what karma-test-shim does
+// #docregion
+/*global jasmine, __karma__, window*/
+(function () {
+
+Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
+
+// Uncomment to get full stacktrace output. Sometimes helpful, usually not.
+// Error.stackTraceLimit = Infinity; //
+
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
+
+var baseURL = document.baseURI;
+baseURL = baseURL + baseURL[baseURL.length-1] ? '' : '/';
+
+System.config({
+ baseURL: baseURL,
+ // 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());
+ })
+}
+
+// Import all spec files defined in the html (__spec_files__)
+// and start Jasmine testrunner
+function initTesting () {
+ console.log('loading spec files: '+__spec_files__.join(', '));
+ return Promise.all(
+ __spec_files__.map(function(spec) {
+ return System.import(spec);
+ })
+ )
+ // After all imports load, re-execute `window.onload` which
+ // triggers the Jasmine test-runner start or explain what went wrong
+ .then(success, console.error.bind(console));
+
+ function success () {
+ console.log('Spec files loaded; starting Jasmine testrunner');
+ window.onload();
+ }
+}
+
+})();
diff --git a/public/docs/_examples/testing/ts/index.html b/public/docs/_examples/testing/ts/index.html
index bfde80afe3..b50b69ec18 100644
--- a/public/docs/_examples/testing/ts/index.html
+++ b/public/docs/_examples/testing/ts/index.html
@@ -1,8 +1,9 @@
+
- Testing Tour of Heroes
+ App Under Test
@@ -15,6 +16,7 @@
+
diff --git a/public/docs/_examples/testing/ts/karma-test-shim.js b/public/docs/_examples/testing/ts/karma-test-shim.js
new file mode 100644
index 0000000000..19fcc89fe9
--- /dev/null
+++ b/public/docs/_examples/testing/ts/karma-test-shim.js
@@ -0,0 +1,89 @@
+// #docregion
+// /*global jasmine, __karma__, window*/
+Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
+
+// Uncomment to get full stacktrace output. Sometimes helpful, usually not.
+// Error.stackTraceLimit = Infinity; //
+
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
+
+var builtPath = '/base/app/';
+
+__karma__.loaded = function () { };
+
+function isJsFile(path) {
+ return path.slice(-3) == '.js';
+}
+
+function isSpecFile(path) {
+ return /\.spec\.(.*\.)?js$/.test(path);
+}
+
+function isBuiltFile(path) {
+ return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
+}
+
+var allSpecFiles = Object.keys(window.__karma__.files)
+ .filter(isSpecFile)
+ .filter(isBuiltFile);
+
+System.config({
+ baseURL: '/base',
+ // 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());
+ })
+}
+
+// Import all spec files and start karma
+function initTesting () {
+ return Promise.all(
+ allSpecFiles.map(function (moduleName) {
+ return System.import(moduleName);
+ })
+ )
+ .then(__karma__.start, __karma__.error);
+}
diff --git a/public/docs/_examples/karma.conf.js b/public/docs/_examples/testing/ts/karma.conf.js
similarity index 60%
rename from public/docs/_examples/karma.conf.js
rename to public/docs/_examples/testing/ts/karma.conf.js
index faa52df98e..1e2d293721 100644
--- a/public/docs/_examples/karma.conf.js
+++ b/public/docs/_examples/testing/ts/karma.conf.js
@@ -1,7 +1,12 @@
+// #docregion
module.exports = function(config) {
- var appBase = 'app/'; // transpiled app JS files
- var appAssets ='/base/app/'; // component assets fetched by Angular's compiler
+ 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 testBase = 'testing/'; // transpiled test JS and map files
+ var testSrcBase = 'testing/'; // test source TS files
config.set({
basePath: '',
@@ -9,7 +14,8 @@ module.exports = function(config) {
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
- require('karma-htmlfile-reporter')
+ require('karma-jasmine-html-reporter'), // click "Debug" in browser to see it
+ require('karma-htmlfile-reporter') // crashing w/ strange socket error
],
customLaunchers: {
@@ -26,39 +32,48 @@ module.exports = function(config) {
// Polyfills
'node_modules/core-js/client/shim.js',
-
- // Reflect and Zone.js
'node_modules/reflect-metadata/Reflect.js',
+
+ // zone.js
'node_modules/zone.js/dist/zone.js',
+ 'node_modules/zone.js/dist/long-stack-trace-zone.js',
+ 'node_modules/zone.js/dist/proxy.js',
+ 'node_modules/zone.js/dist/sync-test.js',
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
- // RxJs.
+ // RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
- // Angular 2 itself and the testing library
+ // 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: 'systemjs.config.js', included: false, watched: false},
+ {pattern: 'systemjs.config.extras.js', included: false, watched: false},
'karma-test-shim.js',
// transpiled application & spec code paths loaded via module imports
{pattern: appBase + '**/*.js', included: false, watched: true},
+ {pattern: testBase + '**/*.js', included: false, watched: true},
- // asset (HTML & CSS) paths loaded via Angular's component compiler
+
+ // 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},
- // paths for debugging with source maps in dev tools
- {pattern: appBase + '**/*.ts', included: false, watched: false},
- {pattern: appBase + '**/*.js.map', included: false, watched: false}
+ // 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}
],
- // proxied base paths for loading assets
+ // Proxied base paths for loading assets
proxies: {
// required for component assets fetched by Angular's compiler
"/app/": appAssets
@@ -66,7 +81,8 @@ module.exports = function(config) {
exclude: [],
preprocessors: {},
- reporters: ['progress', 'html'],
+ // disabled HtmlReporter; suddenly crashing w/ strange socket error
+ reporters: ['progress', 'kjhtml'],//'html'],
// HtmlReporter configuration
htmlReporter: {
diff --git a/public/docs/_examples/testing/ts/liteserver-test-config.json b/public/docs/_examples/testing/ts/liteserver-test-config.json
deleted file mode 100644
index 6b1a2b5466..0000000000
--- a/public/docs/_examples/testing/ts/liteserver-test-config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "startPath": "unit-tests.html"
-}
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/plnkr.json b/public/docs/_examples/testing/ts/plnkr.json
new file mode 100644
index 0000000000..e3573a6b6d
--- /dev/null
+++ b/public/docs/_examples/testing/ts/plnkr.json
@@ -0,0 +1,16 @@
+{
+ "description": "Heroes Test App",
+ "files":[
+ "styles.css",
+ "systemjs.config.extras.js",
+
+ "app/**/*.css",
+ "app/**/*.html",
+ "app/**/*.ts",
+
+ "!app/bag/*.*",
+
+ "index.html"
+ ],
+ "tags": ["testing"]
+}
diff --git a/public/docs/_examples/testing/ts/systemjs.config.extras.js b/public/docs/_examples/testing/ts/systemjs.config.extras.js
new file mode 100644
index 0000000000..218e65715c
--- /dev/null
+++ b/public/docs/_examples/testing/ts/systemjs.config.extras.js
@@ -0,0 +1,9 @@
+// #docregion
+/** App specific SystemJS configuration */
+System.config({
+ packages: {
+ // barrels
+ 'app/model': {main:'index.js', defaultExtension:'js'},
+ 'app/model/testing': {main:'index.js', defaultExtension:'js'}
+ }
+});
diff --git a/public/docs/_examples/testing/ts/test-helpers/dom-setup.ts.not-yet b/public/docs/_examples/testing/ts/test-helpers/dom-setup.ts.not-yet
deleted file mode 100644
index 5e8f6d03a7..0000000000
--- a/public/docs/_examples/testing/ts/test-helpers/dom-setup.ts.not-yet
+++ /dev/null
@@ -1,18 +0,0 @@
-/////// MUST IMPORT AND EXECUTE BEFORE TestComponentBuilder TESTS ////////////
-
-// CRAZY BUG WORKAROUND:
-// Must FIRST import and mention something (anything?) from angular
-// else this file hangs systemjs for almost a minute
-import { bind } from 'angular2/angular2';
-function noop() { return bind; }
-
-/////// THIS SECTION REALLY SHOULD BE EXECUTED FOR US BY ANGULAR ////////////
-// should be in `angular2/test` or `angular2/angular2` but it isn't yet
-import {BrowserDomAdapter} from 'angular2/src/core/dom/browser_adapter';
-
-if (BrowserDomAdapter) {
- // MUST be called before any specs involving the TestComponentBuilder
- BrowserDomAdapter.makeCurrent();
-} else {
- console.log("BrowserDomAdapter not found; TestComponentBuilder tests will fail");
-}
diff --git a/public/docs/_examples/testing/ts/test-helpers/test-helpers.ts.not-yet b/public/docs/_examples/testing/ts/test-helpers/test-helpers.ts.not-yet
deleted file mode 100644
index e39f4ae8ee..0000000000
--- a/public/docs/_examples/testing/ts/test-helpers/test-helpers.ts.not-yet
+++ /dev/null
@@ -1,103 +0,0 @@
-import {FunctionWithParamTokens, injectAsync,RootTestComponent, TestComponentBuilder} from 'angular2/testing';
-import {By} from 'angular2/angular2'
-
-///////// Should be in testing /////////
-
-export type DoneFn = {
- fail: (err?:any) => void,
- (done?:any): () => void
-}
-
-///////// injectAsync extensions ///
-
-type PromiseLikeTestFn = (...args:any[]) => PromiseLike;
-type PromiseLikeTcbTestFn = (tcb: TestComponentBuilder, ...args:any[]) => PromiseLike;
-
-/** Run an async component test within Angular test bed using TestComponentBuilder
-// Example
-// it('async Component test', tcb => {
-// // your test here
-// // your test here
-// // your test here
-// return aPromise;
-// });
-//
-// May precede the test fn with some injectables which will be passed as args AFTER the TestComponentBuilder
-// Example:
-// it('async Component test w/ injectables', [HeroService], (tcb, service:HeroService) => {
-// // your test here
-// return aPromise;
-// });
-*/
-export function injectTcb(testFn: (tcb: TestComponentBuilder) => PromiseLike): FunctionWithParamTokens;
-export function injectTcb(dependencies: any[], testFn: PromiseLikeTcbTestFn): FunctionWithParamTokens;
-export function injectTcb(dependencies: any[] | PromiseLikeTcbTestFn, testFn?: PromiseLikeTcbTestFn) {
-
- if (typeof dependencies === 'function' ){
- testFn = dependencies;
- dependencies = [];
- }
-
- return injectAsync([TestComponentBuilder, ...(dependencies)], testFn);
-}
-///////// inspectors and expectations /////////
-
-export function getSelectedHtml(rootTC: RootTestComponent, selector: string) {
- var debugElement = rootTC.debugElement.query(By.css(selector));
- return debugElement && debugElement.nativeElement && debugElement.nativeElement.innerHTML;
-}
-
-export function expectSelectedHtml(rootTC: RootTestComponent, selector: string) {
- return expect(getSelectedHtml(rootTC, selector));
-}
-
-export function getSelectedClassName(rootTC: RootTestComponent, selector: string) {
- var debugElement = rootTC.debugElement.query(By.css(selector));
- return debugElement && debugElement.nativeElement && debugElement.nativeElement.className;
-}
-
-export function expectSelectedClassName(rootTC: RootTestComponent, selector: string) {
- return expect(getSelectedClassName(rootTC, selector));
-}
-
-export function getViewChildHtml(rootTC: RootTestComponent, elIndex: number = 0) {
- let child = rootTC.debugElement.componentViewChildren[elIndex];
- return child && child.nativeElement && child.nativeElement.innerHTML
-}
-
-export function expectViewChildHtml(rootTC: RootTestComponent, elIndex: number = 0) {
- return expect(getViewChildHtml(rootTC, elIndex));
-}
-
-export function expectViewChildClass(rootTC: RootTestComponent, elIndex: number = 0) {
- let child = rootTC.debugElement.componentViewChildren[elIndex];
- return expect(child && child.nativeElement && child.nativeElement.className);
-}
-
-export function dispatchEvent(element: Element, eventType: string) {
- element.dispatchEvent(new Event(eventType));
-}
-
-/** Let time pass so that DOM or Ng can react
-// returns a promise that returns ("passes through")
-// the value resolved in the previous `then` (if any)
-// after delaying for [millis] which is zero by default.
-// Example (passing along the rootTC w/ no delay):
-// ...
-// return rootTC; // optional
-// })
-// .then(tick)
-// .then(rootTC:RTC => { .. do something ..});
-//
-// Example (passing along nothing in particular w/ 10ms delay):
-// ...
-// // don't care if it returns something or not
-// })
-// .then(_ => tick(_, 10)) // ten milliseconds pass
-// .then(() => { .. do something ..});
-*/
-export function tick(passThru?: any, millis: number = 0){
- return new Promise((resolve, reject) =>{
- setTimeout(() => resolve(passThru), millis);
- });
-}
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/test-shim.js b/public/docs/_examples/testing/ts/test-shim.js
deleted file mode 100644
index 31e1998e69..0000000000
--- a/public/docs/_examples/testing/ts/test-shim.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*global jasmine, __karma__, window*/
-
-// Browser testing shim
-(function () {
-
-// Error.stackTraceLimit = Infinity;
-
-jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
-
-// Configure systemjs to use the .js extension for imports from the app folder
-System.config({
- packages: {
- app: {
- format: 'register',
- defaultExtension: 'js'
- }
- }
-});
-
-// Configure Angular for the browser and with test versions of the platform providers
-System.import('angular2/testing')
- .then(function (testing) {
- return System.import('angular2/platform/testing/browser')
- .then(function (providers) {
- testing.setBaseTestProviders(
- providers.TEST_BROWSER_PLATFORM_PROVIDERS,
- providers.TEST_BROWSER_APPLICATION_PROVIDERS
- );
- });
- })
-
- // Load the spec files (__spec_files__) explicitly
- .then(function () {
- console.log('loading spec files: '+__spec_files__.join(', '));
- return Promise.all(__spec_files__.map(function(spec) { return System.import(spec);} ));
- })
-
- // After all imports load, re-execute `window.onload` which
- // triggers the Jasmine test-runner start or explain what went wrong
- .then(success, console.error.bind(console));
-
-function success () {
- console.log('Spec files loaded; starting Jasmine testrunner');
- window.onload();
-}
-
-
-})();
diff --git a/public/docs/_examples/testing/ts/testing/index.ts b/public/docs/_examples/testing/ts/testing/index.ts
new file mode 100644
index 0000000000..907b968c0c
--- /dev/null
+++ b/public/docs/_examples/testing/ts/testing/index.ts
@@ -0,0 +1,23 @@
+import { tick, ComponentFixture } from '@angular/core/testing';
+
+export * from './jasmine-matchers';
+export * from './router-stubs';
+
+// Short utilities
+/**
+ * Create custom DOM event the old fashioned way
+ *
+ * https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent
+ * Although officially deprecated, some browsers (phantom) don't accept the preferred "new Event(eventName)"
+ */
+export function newEvent(eventName: string, bubbles = false, cancelable = false) {
+ let evt = document.createEvent('CustomEvent'); // MUST be 'CustomEvent'
+ evt.initCustomEvent(eventName, bubbles, cancelable, null);
+ return evt;
+}
+
+/** Wait a tick, then detect changes */
+export function advance(f: ComponentFixture): void {
+ tick();
+ f.detectChanges();
+}
diff --git a/public/docs/_examples/testing/ts/testing/jasmine-matchers.d.ts b/public/docs/_examples/testing/ts/testing/jasmine-matchers.d.ts
new file mode 100644
index 0000000000..f1c5acf77c
--- /dev/null
+++ b/public/docs/_examples/testing/ts/testing/jasmine-matchers.d.ts
@@ -0,0 +1,5 @@
+declare namespace jasmine {
+ interface Matchers {
+ toHaveText(actual: any, expectationFailOutput?: any): jasmine.CustomMatcher;
+ }
+}
diff --git a/public/docs/_examples/testing/ts/testing/jasmine-matchers.ts b/public/docs/_examples/testing/ts/testing/jasmine-matchers.ts
new file mode 100644
index 0000000000..4cab02e148
--- /dev/null
+++ b/public/docs/_examples/testing/ts/testing/jasmine-matchers.ts
@@ -0,0 +1,45 @@
+///
+
+//// Jasmine Custom Matchers ////
+// Be sure to extend jasmine-matchers.d.ts when adding matchers
+
+export function addMatchers(): void {
+ jasmine.addMatchers({
+ toHaveText: toHaveText
+ });
+}
+
+function toHaveText(): jasmine.CustomMatcher {
+ return {
+ compare: function (actual: any, expectedText: string, expectationFailOutput?: any): jasmine.CustomMatcherResult {
+ const actualText = elementText(actual);
+ const pass = actualText.indexOf(expectedText) > -1;
+ const message = pass ? '' : composeMessage();
+ return { pass, message };
+
+ function composeMessage () {
+ const a = (actualText.length < 100 ? actualText : actualText.substr(0, 100) + '...');
+ const efo = expectationFailOutput ? ` '${expectationFailOutput}'` : '';
+ return `Expected element to have text content '${expectedText}' instead of '${a}'${efo}`;
+ }
+ }
+ };
+}
+
+function elementText(n: any): string {
+ if (n instanceof Array) {
+ return n.map(elementText).join('');
+ }
+
+ if (n.nodeType === Node.COMMENT_NODE) {
+ return '';
+ }
+
+ if (n.nodeType === Node.ELEMENT_NODE && n.hasChildNodes()) {
+ return elementText(Array.prototype.slice.call(n.childNodes));
+ }
+
+ if (n.nativeElement) { n = n.nativeElement; }
+
+ return n.textContent;
+}
diff --git a/public/docs/_examples/testing/ts/testing/router-stubs.ts b/public/docs/_examples/testing/ts/testing/router-stubs.ts
new file mode 100644
index 0000000000..75a2858f65
--- /dev/null
+++ b/public/docs/_examples/testing/ts/testing/router-stubs.ts
@@ -0,0 +1,57 @@
+ // export for convenience.
+export { ActivatedRoute, Router, RouterLink, RouterOutlet} from '@angular/router';
+
+import { Component, Directive, Injectable, Input } from '@angular/core';
+import { NavigationExtras } from '@angular/router';
+
+// #docregion router-link
+@Directive({
+ selector: '[routerLink]',
+ host: {
+ '(click)': 'onClick()'
+ }
+})
+export class RouterLinkStubDirective {
+ @Input('routerLink') linkParams: any;
+ navigatedTo: any = null;
+
+ onClick() {
+ this.navigatedTo = this.linkParams;
+ }
+}
+// #enddocregion router-link
+
+@Component({selector: 'router-outlet', template: ''})
+export class RouterOutletStubComponent { }
+
+@Injectable()
+export class RouterStub {
+ navigate(commands: any[], extras?: NavigationExtras) { }
+}
+
+
+// Only implements params and part of snapshot.params
+// #docregion activated-route-stub
+import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+
+@Injectable()
+export class ActivatedRouteStub {
+
+ // ActivatedRoute.params is Observable
+ private subject = new BehaviorSubject(this.testParams);
+ params = this.subject.asObservable();
+
+ // Test parameters
+ private _testParams: {};
+ get testParams() { return this._testParams; }
+ set testParams(params: {}) {
+ this._testParams = params;
+ this.subject.next(params);
+ }
+
+ // ActivatedRoute.snapshot.params
+ get snapshot() {
+ return { params: this.testParams };
+ }
+}
+// #enddocregion activated-route-stub
diff --git a/public/docs/_examples/testing/ts/unit-tests-0.html b/public/docs/_examples/testing/ts/unit-tests-0.html
deleted file mode 100644
index af7d1b9192..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-0.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/docs/_examples/testing/ts/unit-tests-1.html b/public/docs/_examples/testing/ts/unit-tests-1.html
deleted file mode 100644
index b370ca053a..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-1.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/docs/_examples/testing/ts/unit-tests-2.html b/public/docs/_examples/testing/ts/unit-tests-2.html
deleted file mode 100644
index d47b4d1f60..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-2.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/docs/_examples/testing/ts/unit-tests-3.html b/public/docs/_examples/testing/ts/unit-tests-3.html
deleted file mode 100644
index 349606bd6d..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-3.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/docs/_examples/testing/ts/unit-tests-4.html b/public/docs/_examples/testing/ts/unit-tests-4.html
deleted file mode 100644
index a3e252fdb0..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-4.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/docs/_examples/testing/ts/unit-tests-5.html b/public/docs/_examples/testing/ts/unit-tests-5.html
deleted file mode 100644
index b95b36760a..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-5.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/docs/_examples/testing/ts/unit-tests-6.html.not-yet b/public/docs/_examples/testing/ts/unit-tests-6.html.not-yet
deleted file mode 100644
index df8e3704ba..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-6.html.not-yet
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/unit-tests-7.html.not-yet b/public/docs/_examples/testing/ts/unit-tests-7.html.not-yet
deleted file mode 100644
index d5449711ee..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-7.html.not-yet
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/unit-tests-bag.html b/public/docs/_examples/testing/ts/unit-tests-bag.html
deleted file mode 100644
index f373c387e8..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests-bag.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
- Bag of Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/docs/_examples/testing/ts/unit-tests.html.not-yet b/public/docs/_examples/testing/ts/unit-tests.html.not-yet
deleted file mode 100644
index f1b8ab444d..0000000000
--- a/public/docs/_examples/testing/ts/unit-tests.html.not-yet
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
- Ng App Unit Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/public/docs/_examples/testing/ts/wallaby.js b/public/docs/_examples/testing/ts/wallaby.js
new file mode 100644
index 0000000000..acc34d35f5
--- /dev/null
+++ b/public/docs/_examples/testing/ts/wallaby.js
@@ -0,0 +1,119 @@
+// 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);
+ });
+ }
+}
diff --git a/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart b/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart
index 8b21290440..3bfa89762d 100644
--- a/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart
+++ b/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart
@@ -32,6 +32,6 @@ template: '''
// #docregion app-component-1
class AppComponent {
String title = 'Tour of Heroes';
- Hero hero = 'Windstorm';
+ var hero = 'Windstorm';
}
// #enddocregion app-component-1
diff --git a/public/docs/_examples/toh-1/dart/pubspec.yaml b/public/docs/_examples/toh-1/dart/pubspec.yaml
index 9657ed659d..c4826c3511 100644
--- a/public/docs/_examples/toh-1/dart/pubspec.yaml
+++ b/public/docs/_examples/toh-1/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/toh-1/e2e-spec.ts b/public/docs/_examples/toh-1/e2e-spec.ts
index 15acf6e434..11e51e4df9 100644
--- a/public/docs/_examples/toh-1/e2e-spec.ts
+++ b/public/docs/_examples/toh-1/e2e-spec.ts
@@ -4,7 +4,7 @@
type WPromise = webdriver.promise.Promise;
const expectedH1 = 'Tour of Heroes';
-const expectedTitle = `Angular 2 ${expectedH1}`;
+const expectedTitle = `Angular ${expectedH1}`;
class Hero {
id: number;
@@ -19,7 +19,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
- name: _name.substr(0, _name.indexOf(' '))
+ name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}
diff --git a/public/docs/_examples/toh-1/ts/index.html b/public/docs/_examples/toh-1/ts/index.html
index e9c099696b..4445befc9a 100644
--- a/public/docs/_examples/toh-1/ts/index.html
+++ b/public/docs/_examples/toh-1/ts/index.html
@@ -1,7 +1,7 @@
- Angular 2 Tour of Heroes
+ Angular Tour of Heroes
diff --git a/public/docs/_examples/toh-2/dart/pubspec.yaml b/public/docs/_examples/toh-2/dart/pubspec.yaml
index 9657ed659d..c4826c3511 100644
--- a/public/docs/_examples/toh-2/dart/pubspec.yaml
+++ b/public/docs/_examples/toh-2/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/toh-2/e2e-spec.ts b/public/docs/_examples/toh-2/e2e-spec.ts
index 256ffbb5d7..cde9e93edf 100644
--- a/public/docs/_examples/toh-2/e2e-spec.ts
+++ b/public/docs/_examples/toh-2/e2e-spec.ts
@@ -2,7 +2,7 @@
'use strict';
const expectedH1 = 'Tour of Heroes';
-const expectedTitle = `Angular 2 ${expectedH1}`;
+const expectedTitle = `Angular ${expectedH1}`;
const expectedH2 = 'My Heroes';
const targetHero = { id: 16, name: 'RubberMan' };
const nameSuffix = 'X';
@@ -31,7 +31,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
- name: _name.substr(0, _name.indexOf(' '))
+ name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}
diff --git a/public/docs/_examples/toh-2/ts-snippets/app.component.snippets.pt2.ts b/public/docs/_examples/toh-2/ts-snippets/app.component.snippets.pt2.ts
index 10475a0954..801c550130 100644
--- a/public/docs/_examples/toh-2/ts-snippets/app.component.snippets.pt2.ts
+++ b/public/docs/_examples/toh-2/ts-snippets/app.component.snippets.pt2.ts
@@ -40,7 +40,7 @@
// #enddocregion ng-if
// #docregion hero-array-1
-public heroes = HEROES;
+heroes = HEROES;
// #enddocregion hero-array-1
// #docregion heroes-template-1
diff --git a/public/docs/_examples/toh-2/ts/app/app.component.ts b/public/docs/_examples/toh-2/ts/app/app.component.ts
index 5d10fc55a9..3e7c86f150 100644
--- a/public/docs/_examples/toh-2/ts/app/app.component.ts
+++ b/public/docs/_examples/toh-2/ts/app/app.component.ts
@@ -102,6 +102,8 @@ export class AppComponent {
// #enddocregion selected-hero
// #docregion on-select
- onSelect(hero: Hero) { this.selectedHero = hero; }
+ onSelect(hero: Hero): void {
+ this.selectedHero = hero;
+ }
// #enddocregion on-select
}
diff --git a/public/docs/_examples/toh-2/ts/index.html b/public/docs/_examples/toh-2/ts/index.html
index e9c099696b..4445befc9a 100644
--- a/public/docs/_examples/toh-2/ts/index.html
+++ b/public/docs/_examples/toh-2/ts/index.html
@@ -1,7 +1,7 @@
- Angular 2 Tour of Heroes
+ Angular Tour of Heroes
diff --git a/public/docs/_examples/toh-3/dart/pubspec.yaml b/public/docs/_examples/toh-3/dart/pubspec.yaml
index 9657ed659d..c4826c3511 100644
--- a/public/docs/_examples/toh-3/dart/pubspec.yaml
+++ b/public/docs/_examples/toh-3/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/toh-3/e2e-spec.ts b/public/docs/_examples/toh-3/e2e-spec.ts
index 070dd69ebd..f1e51f5b39 100644
--- a/public/docs/_examples/toh-3/e2e-spec.ts
+++ b/public/docs/_examples/toh-3/e2e-spec.ts
@@ -2,7 +2,7 @@
'use strict';
const expectedH1 = 'Tour of Heroes';
-const expectedTitle = `Angular 2 ${expectedH1}`;
+const expectedTitle = `Angular ${expectedH1}`;
const expectedH2 = 'My Heroes';
const targetHero = { id: 16, name: 'RubberMan' };
const nameSuffix = 'X';
@@ -31,7 +31,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
- name: _name.substr(0, _name.indexOf(' '))
+ name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}
diff --git a/public/docs/_examples/toh-3/ts/app/app.component.ts b/public/docs/_examples/toh-3/ts/app/app.component.ts
index fe5a5b98ad..022efc31eb 100644
--- a/public/docs/_examples/toh-3/ts/app/app.component.ts
+++ b/public/docs/_examples/toh-3/ts/app/app.component.ts
@@ -89,5 +89,7 @@ export class AppComponent {
heroes = HEROES;
selectedHero: Hero;
- onSelect(hero: Hero) { this.selectedHero = hero; }
+ onSelect(hero: Hero): void {
+ this.selectedHero = hero;
+ }
}
diff --git a/public/docs/_examples/toh-3/ts/index.html b/public/docs/_examples/toh-3/ts/index.html
index e9c099696b..4445befc9a 100644
--- a/public/docs/_examples/toh-3/ts/index.html
+++ b/public/docs/_examples/toh-3/ts/index.html
@@ -1,7 +1,7 @@
- Angular 2 Tour of Heroes
+ Angular Tour of Heroes
diff --git a/public/docs/_examples/toh-4/dart/lib/hero_service.dart b/public/docs/_examples/toh-4/dart/lib/hero_service.dart
index 30f25f5931..4eff635e4c 100644
--- a/public/docs/_examples/toh-4/dart/lib/hero_service.dart
+++ b/public/docs/_examples/toh-4/dart/lib/hero_service.dart
@@ -17,7 +17,7 @@ class HeroService {
// See the "Take it slow" appendix
// #docregion get-heroes-slowly
Future> getHeroesSlowly() {
- return new Future.delayed(const Duration(seconds: 2), () => mockHeroes);
+ return new Future.delayed(const Duration(seconds: 2), getHeroes);
}
// #enddocregion get-heroes-slowly
// #docregion
diff --git a/public/docs/_examples/toh-4/dart/lib/hero_service_1.dart b/public/docs/_examples/toh-4/dart/lib/hero_service_1.dart
index 87e11177d8..6feca85ae0 100644
--- a/public/docs/_examples/toh-4/dart/lib/hero_service_1.dart
+++ b/public/docs/_examples/toh-4/dart/lib/hero_service_1.dart
@@ -13,7 +13,7 @@ class HeroService {
// #enddocregion getHeroes-stub, empty-class, final
/*
// #docregion getHeroes-stub
- List getHeroes() {}
+ List getHeroes() {} // stub
// #enddocregion getHeroes-stub
*/
// #docregion final
diff --git a/public/docs/_examples/toh-4/dart/pubspec.yaml b/public/docs/_examples/toh-4/dart/pubspec.yaml
index 9657ed659d..c4826c3511 100644
--- a/public/docs/_examples/toh-4/dart/pubspec.yaml
+++ b/public/docs/_examples/toh-4/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/toh-4/e2e-spec.ts b/public/docs/_examples/toh-4/e2e-spec.ts
index 8f7852a3e3..456297b6d2 100644
--- a/public/docs/_examples/toh-4/e2e-spec.ts
+++ b/public/docs/_examples/toh-4/e2e-spec.ts
@@ -2,7 +2,7 @@
'use strict';
const expectedH1 = 'Tour of Heroes';
-const expectedTitle = `Angular 2 ${expectedH1}`;
+const expectedTitle = `Angular ${expectedH1}`;
const expectedH2 = 'My Heroes';
const targetHero = { id: 16, name: 'RubberMan' };
const nameSuffix = 'X';
@@ -31,7 +31,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
- name: _name.substr(0, _name.indexOf(' '))
+ name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}
diff --git a/public/docs/_examples/toh-4/ts/app/app.component.1.ts b/public/docs/_examples/toh-4/ts/app/app.component.1.ts
index 5a0a4d0524..675c7a64d0 100644
--- a/public/docs/_examples/toh-4/ts/app/app.component.1.ts
+++ b/public/docs/_examples/toh-4/ts/app/app.component.1.ts
@@ -7,7 +7,7 @@ import { Component } from '@angular/core';
import { Hero } from './hero';
// #docregion hero-service-import
-import { HeroService } from './hero.service.1';
+import { HeroService } from './hero.service.2';
// #enddocregion hero-service-import
// Testable but never shown
@@ -41,7 +41,7 @@ export class AppComponent implements OnInit {
constructor(private heroService: HeroService) { }
// #enddocregion ctor
// #docregion getHeroes
- getHeroes() {
+ getHeroes(): void {
// #docregion get-heroes
this.heroes = this.heroService.getHeroes();
// #enddocregion get-heroes
@@ -50,7 +50,7 @@ export class AppComponent implements OnInit {
// #docregion ng-on-init
// #docregion on-init
- ngOnInit() {
+ ngOnInit(): void {
// #enddocregion on-init
this.getHeroes();
// #docregion on-init
@@ -58,6 +58,8 @@ export class AppComponent implements OnInit {
// #enddocregion on-init
// #enddocregion ng-on-init
- onSelect(hero: Hero) { this.selectedHero = hero; }
+ onSelect(hero: Hero): void {
+ this.selectedHero = hero;
+ }
// #docregion on-init
}
diff --git a/public/docs/_examples/toh-4/ts/app/app.component.ts b/public/docs/_examples/toh-4/ts/app/app.component.ts
index 00bee85659..b16acb8375 100644
--- a/public/docs/_examples/toh-4/ts/app/app.component.ts
+++ b/public/docs/_examples/toh-4/ts/app/app.component.ts
@@ -82,14 +82,16 @@ export class AppComponent implements OnInit {
constructor(private heroService: HeroService) { }
// #docregion get-heroes
- getHeroes() {
+ getHeroes(): void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
// #enddocregion get-heroes
- ngOnInit() {
+ ngOnInit(): void {
this.getHeroes();
}
- onSelect(hero: Hero) { this.selectedHero = hero; }
+ onSelect(hero: Hero): void {
+ this.selectedHero = hero;
+ }
}
diff --git a/public/docs/_examples/toh-4/ts/app/hero.service.1.ts b/public/docs/_examples/toh-4/ts/app/hero.service.1.ts
index 5a15d5c285..2366215259 100644
--- a/public/docs/_examples/toh-4/ts/app/hero.service.1.ts
+++ b/public/docs/_examples/toh-4/ts/app/hero.service.1.ts
@@ -1,19 +1,24 @@
// #docplaster
// #docregion
-// #docregion empty-class
+// #docregion empty-class, full
import { Injectable } from '@angular/core';
// #enddocregion empty-class
+import { Hero } from './hero';
import { HEROES } from './mock-heroes';
// #docregion empty-class, getHeroes-stub
@Injectable()
export class HeroService {
- // #enddocregion empty-class
- getHeroes() {
- // #enddocregion getHeroes-stub
+ // #enddocregion empty-class, getHeroes-stub, full
+ /*
+ // #docregion getHeroes-stub
+ getHeroes(): void {} // stub
+ // #enddocregion getHeroes-stub
+ */
+ // #docregion full
+ getHeroes(): Hero[] {
return HEROES;
- // #docregion getHeroes-stub
}
- // #docregion empty-class
+ // #docregion empty-class, getHeroes-stub
}
diff --git a/public/docs/_examples/toh-4/ts/app/hero.service.2.ts b/public/docs/_examples/toh-4/ts/app/hero.service.2.ts
new file mode 100644
index 0000000000..d14fe02410
--- /dev/null
+++ b/public/docs/_examples/toh-4/ts/app/hero.service.2.ts
@@ -0,0 +1,13 @@
+// #docregion
+import { Injectable } from '@angular/core';
+
+import { Hero } from './hero';
+import { HEROES } from './mock-heroes';
+
+@Injectable()
+export class HeroService {
+
+ getHeroes(): Hero[] {
+ return HEROES;
+ }
+}
diff --git a/public/docs/_examples/toh-4/ts/app/hero.service.ts b/public/docs/_examples/toh-4/ts/app/hero.service.ts
index 87eb9ec673..2b4de81c39 100644
--- a/public/docs/_examples/toh-4/ts/app/hero.service.ts
+++ b/public/docs/_examples/toh-4/ts/app/hero.service.ts
@@ -9,17 +9,17 @@ import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
// #docregion get-heroes
- getHeroes() {
+ getHeroes(): Promise {
return Promise.resolve(HEROES);
}
// #enddocregion get-heroes, just-get-heroes
// #enddocregion
// See the "Take it slow" appendix
// #docregion get-heroes-slowly
- getHeroesSlowly() {
+ getHeroesSlowly(): Promise {
return new Promise(resolve =>
- setTimeout(() => resolve(HEROES), 2000) // 2 seconds
- );
+ setTimeout(resolve, 2000)) // delay 2 seconds
+ .then(() => this.getHeroes());
}
// #enddocregion get-heroes-slowly
// #docregion
diff --git a/public/docs/_examples/toh-4/ts/index.html b/public/docs/_examples/toh-4/ts/index.html
index e9c099696b..4445befc9a 100644
--- a/public/docs/_examples/toh-4/ts/index.html
+++ b/public/docs/_examples/toh-4/ts/index.html
@@ -1,7 +1,7 @@
- Angular 2 Tour of Heroes
+ Angular Tour of Heroes
diff --git a/public/docs/_examples/toh-5/dart/lib/app_component.dart b/public/docs/_examples/toh-5/dart/lib/app_component.dart
index ecf2bf4f3c..ba1ed39c88 100644
--- a/public/docs/_examples/toh-5/dart/lib/app_component.dart
+++ b/public/docs/_examples/toh-5/dart/lib/app_component.dart
@@ -1,18 +1,18 @@
// #docplaster
// #docregion
import 'package:angular2/core.dart';
+// #docregion import-router
import 'package:angular2/router.dart';
+// #enddocregion import-router
-import 'package:angular2_tour_of_heroes/heroes_component.dart';
-import 'package:angular2_tour_of_heroes/hero_service.dart';
-import 'package:angular2_tour_of_heroes/dashboard_component.dart';
-// #docregion hero-detail-import
-import 'package:angular2_tour_of_heroes/hero_detail_component.dart';
-// #enddocregion hero-detail-import
+import 'dashboard_component.dart';
+import 'hero_detail_component.dart';
+import 'hero_service.dart';
+import 'heroes_component.dart';
@Component(
selector: 'my-app',
- // #docregion template
+ // #docregion template, template-v3
template: '''
{{title}}
@@ -20,26 +20,32 @@ import 'package:angular2_tour_of_heroes/hero_detail_component.dart';
Heroes
''',
- // #enddocregion template
- // #docregion style-urls
+ // #enddocregion template, template-v3
+ // #docregion styleUrls
styleUrls: const ['app_component.css'],
- // #enddocregion style-urls
+ // #enddocregion styleUrls
+ // #docregion directives-and-providers
directives: const [ROUTER_DIRECTIVES],
providers: const [HeroService, ROUTER_PROVIDERS])
+// #enddocregion directives-and-providers
+// #docregion heroes
@RouteConfig(const [
- // #docregion dashboard-route
+ // #enddocregion heroes
+ // #docregion dashboard
const Route(
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
useAsDefault: true),
- // #enddocregion dashboard-route
- // #docregion hero-detail-route
+ // #enddocregion dashboard
+ // #docregion hero-detail
const Route(
path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent),
- // #enddocregion hero-detail-route
+ // #enddocregion hero-detail
+ // #docregion heroes
const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
])
+// #enddocregion heroes
class AppComponent {
String title = 'Tour of Heroes';
}
diff --git a/public/docs/_examples/toh-5/dart/lib/app_component_1.dart b/public/docs/_examples/toh-5/dart/lib/app_component_1.dart
index 880974b28f..8455181dbc 100644
--- a/public/docs/_examples/toh-5/dart/lib/app_component_1.dart
+++ b/public/docs/_examples/toh-5/dart/lib/app_component_1.dart
@@ -1,25 +1,40 @@
// #docplaster
-// #docregion
+// #docregion , v2
import 'package:angular2/core.dart';
-// #enddocregion
-import 'package:angular2/router.dart'; // for testing only
+// #enddocregion ,
+// #docregion v2
+import 'package:angular2/router.dart';
// #docregion
import 'hero_service.dart';
import 'heroes_component.dart';
+// #enddocregion v2
@Component(
selector: 'my-app',
template: '''
{{title}}
''',
directives: const [HeroesComponent],
- providers: const [
- // #enddocregion
- ROUTER_PROVIDERS,
- // #docregion
- HeroService
- ])
+ providers: const [HeroService])
+// #enddocregion ,
+class Bogus {}
+
+// #docregion v2
+@Component(
+ selector: 'my-app',
+ // #docregion template-v2
+ template: '''
+ {{title}}
+ Heroes
+ ''',
+ // #enddocregion template-v2
+ directives: const [ROUTER_DIRECTIVES],
+ providers: const [HeroService, ROUTER_PROVIDERS])
+@RouteConfig(const [
+ const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
+])
+// #docregion ,
class AppComponent {
String title = 'Tour of Heroes';
}
diff --git a/public/docs/_examples/toh-5/dart/lib/app_component_2.dart b/public/docs/_examples/toh-5/dart/lib/app_component_2.dart
deleted file mode 100644
index 024c2b6ac9..0000000000
--- a/public/docs/_examples/toh-5/dart/lib/app_component_2.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// #docplaster
-// #docregion
-import 'package:angular2/core.dart';
-// #docregion import-router
-import 'package:angular2/router.dart';
-// #enddocregion import-router
-
-import 'hero_service.dart';
-import 'heroes_component.dart';
-
-@Component(
- selector: 'my-app',
- // #docregion template
- template: '''
- {{title}}
- Heroes
- ''',
- // #enddocregion template
- // #docregion directives-and-providers
- directives: const [ROUTER_DIRECTIVES],
- providers: const [ROUTER_PROVIDERS, HeroService]
- // #enddocregion directives-and-providers
-)
-// #docregion route-config
-@RouteConfig(const [
- const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
-])
-// #enddocregion route-config
-class AppComponent {
- String title = 'Tour of Heroes';
-}
diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart
index ff0fb8c0d1..8b2f6fe4af 100644
--- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart
+++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart
@@ -12,9 +12,9 @@ import 'hero_service.dart';
@Component(
selector: 'my-dashboard',
- // #docregion template-url
+ // #docregion templateUrl
templateUrl: 'dashboard_component.html',
- // #enddocregion template-url
+ // #enddocregion templateUrl
// #docregion css
styleUrls: const ['dashboard_component.css']
// #enddocregion css
@@ -35,7 +35,7 @@ class DashboardComponent implements OnInit {
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
}
- // #docregion goto-detail
+ // #docregion gotoDetail
void gotoDetail(Hero hero) {
var link = [
'HeroDetail',
@@ -43,5 +43,5 @@ class DashboardComponent implements OnInit {
];
_router.navigate(link);
}
-// #enddocregion goto-detail
+// #enddocregion gotoDetail
}
diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart
index aa9afb38d7..c5304f572a 100644
--- a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart
+++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart
@@ -22,5 +22,5 @@ class DashboardComponent implements OnInit {
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
}
- gotoDetail() {/* not implemented yet */}
+ gotoDetail(Hero hero) {/* not implemented yet */}
}
diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart
index a6c506a231..a99528cbaa 100644
--- a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart
+++ b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart
@@ -1,30 +1,28 @@
// #docplaster
// #docregion , v2
+// #docregion added-imports
import 'dart:async';
-import 'dart:html';
+import 'dart:html' show window;
-// #docregion import-oninit
+// #enddocregion added-imports
import 'package:angular2/core.dart';
-// #enddocregion import-oninit
-// #docregion import-route-params
+// #docregion added-imports
import 'package:angular2/router.dart';
-// #enddocregion import-route-params
+// #enddocregion added-imports
import 'hero.dart';
-// #docregion import-hero-service
+// #docregion added-imports
import 'hero_service.dart';
-// #enddocregion import-hero-service
+// #enddocregion added-imports
-// #docregion extract-template
@Component(
selector: 'my-hero-detail',
- // #docregion template-url
+ // #docregion templateUrl
templateUrl: 'hero_detail_component.html',
- // #enddocregion template-url, v2
+ // #enddocregion templateUrl, v2
styleUrls: const ['hero_detail_component.css']
// #docregion v2
)
-// #enddocregion extract-template
// #docregion implement
class HeroDetailComponent implements OnInit {
// #enddocregion implement
@@ -36,19 +34,17 @@ class HeroDetailComponent implements OnInit {
HeroDetailComponent(this._heroService, this._routeParams);
// #enddocregion ctor
- // #docregion ng-oninit
+ // #docregion ngOnInit
Future ngOnInit() async {
- // #docregion get-id
var idString = _routeParams.get('id');
- var id = int.parse(idString, onError: (_) => null);
- // #enddocregion get-id
+ var id = int.parse(idString ?? '', onError: (_) => null);
if (id != null) hero = await (_heroService.getHero(id));
}
- // #enddocregion ng-oninit
+ // #enddocregion ngOnInit
- // #docregion go-back
+ // #docregion goBack
void goBack() {
window.history.back();
}
- // #enddocregion go-back
+ // #enddocregion goBack
}
diff --git a/public/docs/_examples/toh-5/dart/lib/hero_service.dart b/public/docs/_examples/toh-5/dart/lib/hero_service.dart
index e626b38200..aca9e3c21d 100644
--- a/public/docs/_examples/toh-5/dart/lib/hero_service.dart
+++ b/public/docs/_examples/toh-5/dart/lib/hero_service.dart
@@ -10,14 +10,13 @@ import 'mock_heroes.dart';
class HeroService {
Future> getHeroes() async => mockHeroes;
- // See the "Take it slow" appendix
Future> getHeroesSlowly() {
return new Future>.delayed(
- const Duration(seconds: 2), () => mockHeroes);
+ const Duration(seconds: 2), getHeroes);
}
- // #docregion get-hero
+ // #docregion getHero
Future getHero(int id) async =>
(await getHeroes()).firstWhere((hero) => hero.id == id);
- // #enddocregion get-hero
+ // #enddocregion getHero
}
diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.dart b/public/docs/_examples/toh-5/dart/lib/heroes_component.dart
index 48e1a167bf..e19c3ab3be 100644
--- a/public/docs/_examples/toh-5/dart/lib/heroes_component.dart
+++ b/public/docs/_examples/toh-5/dart/lib/heroes_component.dart
@@ -6,27 +6,28 @@ import 'package:angular2/core.dart';
import 'package:angular2/router.dart';
import 'hero.dart';
-import 'hero_detail_component.dart';
import 'hero_service.dart';
-// #docregion metadata, heroes-component-renaming
+// #docregion metadata, renaming
@Component(
selector: 'my-heroes',
- // #enddocregion heroes-component-renaming
+ // #enddocregion renaming
templateUrl: 'heroes_component.html',
- styleUrls: const ['heroes_component.css'],
- directives: const [HeroDetailComponent])
-// #docregion heroes-component-renaming
-// #enddocregion heroes-component-renaming, metadata
-// #docregion class, heroes-component-renaming
+ styleUrls: const ['heroes_component.css']
+// #docregion renaming
+)
+// #enddocregion metadata
+// #docregion class
class HeroesComponent implements OnInit {
- // #enddocregion heroes-component-renaming
+ // #enddocregion renaming
final Router _router;
final HeroService _heroService;
List heroes;
Hero selectedHero;
+ // #docregion renaming
HeroesComponent(this._heroService, this._router);
+ // #enddocregion renaming
Future getHeroes() async {
heroes = await _heroService.getHeroes();
@@ -44,5 +45,5 @@ class HeroesComponent implements OnInit {
'HeroDetail',
{'id': selectedHero.id.toString()}
]);
- // #docregion heroes-component-renaming
+ // #docregion renaming
}
diff --git a/public/docs/_examples/toh-5/dart/pubspec.yaml b/public/docs/_examples/toh-5/dart/pubspec.yaml
index 9657ed659d..c4826c3511 100644
--- a/public/docs/_examples/toh-5/dart/pubspec.yaml
+++ b/public/docs/_examples/toh-5/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/toh-5/dart/web/styles_1.css b/public/docs/_examples/toh-5/dart/web/styles_1.css
deleted file mode 100644
index dee6d5b8ca..0000000000
--- a/public/docs/_examples/toh-5/dart/web/styles_1.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/* #docregion toh-excerpt */
-/* 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;
-}
-/* . . . */
-/* everywhere else */
-* {
- font-family: Arial, Helvetica, sans-serif;
-}
diff --git a/public/docs/_examples/toh-5/e2e-spec.ts b/public/docs/_examples/toh-5/e2e-spec.ts
index e0dc96b63e..6935ff19a2 100644
--- a/public/docs/_examples/toh-5/e2e-spec.ts
+++ b/public/docs/_examples/toh-5/e2e-spec.ts
@@ -1,113 +1,190 @@
///
'use strict';
-describe('Tutorial', function () {
- beforeAll(function () {
- browser.get('');
- });
+const expectedH1 = 'Tour of Heroes';
+const expectedTitle = `Angular ${expectedH1}`;
+const targetHero = { id: 15, name: 'Magneta' };
+const targetHeroDashboardIndex = 3;
+const nameSuffix = 'X';
+const newHeroName = targetHero.name + nameSuffix;
- function getPageStruct() {
- let hrefEles = element.all(by.css('my-app a'));
+type WPromise = webdriver.promise.Promise;
+
+class Hero {
+ id: number;
+ name: string;
+
+ // Factory methods
+
+ // Get hero from s formatted as ' '.
+ static fromString(s: string): Hero {
+ return {
+ id: +s.substr(0, s.indexOf(' ')),
+ name: s.substr(s.indexOf(' ') + 1),
+ };
+ }
+
+ // Get hero id and name from the given detail element.
+ static async fromDetail(detail: protractor.ElementFinder): Promise {
+ // Get hero id from the first
+ let _id = await detail.all(by.css('div')).first().getText();
+ // Get name from the h2
+ let _name = await detail.element(by.css('h2')).getText();
+ return {
+ id: +_id.substr(_id.indexOf(' ') + 1),
+ name: _name.substr(0, _name.lastIndexOf(' '))
+ };
+ }
+}
+
+describe('Tutorial part 5', () => {
+
+ beforeAll(() => browser.get(''));
+
+ function getPageElts() {
+ let hrefElts = element.all(by.css('my-app a'));
return {
- hrefs: hrefEles,
- myDashboardHref: hrefEles.get(0),
- myDashboardParent: element(by.css('my-app my-dashboard')),
- topHeroes: element.all(by.css('my-app my-dashboard .module.hero')),
+ hrefs: hrefElts,
- myHeroesHref: hrefEles.get(1),
- myHeroesParent: element(by.css('my-app my-heroes')),
+ myDashboardHref: hrefElts.get(0),
+ myDashboard: element(by.css('my-app my-dashboard')),
+ topHeroes: element.all(by.css('my-app my-dashboard > div h4')),
+
+ myHeroesHref: hrefElts.get(1),
+ myHeroes: element(by.css('my-app my-heroes')),
allHeroes: element.all(by.css('my-app my-heroes li')),
+ selectedHero: element(by.css('my-app li.selected')),
+ selectedHeroSubview: element(by.css('my-app my-heroes > div')),
- heroDetail: element(by.css('my-app my-hero-detail'))
+ heroDetail: element(by.css('my-app my-hero-detail > div'))
};
}
- it('should be able to see the start screen', function () {
- let page = getPageStruct();
- expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
- expect(page.myDashboardHref.getText()).toEqual('Dashboard');
- expect(page.myHeroesHref.getText()).toEqual('Heroes');
- });
+ describe('Initial page', () => {
- it('should be able to see dashboard choices', function () {
- let page = getPageStruct();
- expect(page.topHeroes.count()).toBe(4, 'should be 4 dashboard hero choices');
- });
+ it(`has title '${expectedTitle}'`, () => {
+ expect(browser.getTitle()).toEqual(expectedTitle);
+ });
- it('should be able to toggle the views', function () {
- let page = getPageStruct();
+ it(`has h1 '${expectedH1}'`, () => {
+ expectHeading(1, expectedH1);
+ });
- expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
- page.myHeroesHref.click().then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element');
- expect(page.allHeroes.count()).toBeGreaterThan(4, 'should be more than 4 heroes shown');
- return page.myDashboardHref.click();
- }).then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element');
+ const expectedViewNames = ['Dashboard', 'Heroes'];
+ it(`has views ${expectedViewNames}`, () => {
+ let viewNames = getPageElts().hrefs.map(el => el.getText());
+ expect(viewNames).toEqual(expectedViewNames);
+ });
+
+ it('has dashboard as the active view', () => {
+ let page = getPageElts();
+ expect(page.myDashboard.isPresent()).toBeTruthy();
});
});
- it('should be able to edit details from "Dashboard" view', function () {
- let page = getPageStruct();
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
- let heroEle = page.topHeroes.get(3);
- let heroDescrEle = heroEle.element(by.css('h4'));
- let heroDescr: string;
- return heroDescrEle.getText().then(function(text) {
- heroDescr = text;
- return heroEle.click();
- }).then(function() {
- return editDetails(page, heroDescr, '-foo');
- }).then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back');
- expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo');
+ describe('Dashboard tests', () => {
+
+ beforeAll(() => browser.get(''));
+
+ it('has top heroes', () => {
+ let page = getPageElts();
+ expect(page.topHeroes.count()).toEqual(4);
});
+
+ it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero);
+
+ it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView);
+
+ it(`saves and shows ${newHeroName} in Dashboard`, () => {
+ element(by.buttonText('Back')).click();
+ let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex);
+ expect(targetHeroElt.getText()).toEqual(newHeroName);
+ });
+
});
- it('should be able to edit details from "Heroes" view', function () {
- let page = getPageStruct();
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present');
- let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
- let heroEle: protractor.ElementFinder;
- let heroDescr: string;
- page.myHeroesHref.click().then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
- expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
- expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present');
- heroEle = page.allHeroes.get(2);
- return heroEle.getText();
- }).then(function(text) {
- // remove leading 'id' from the element
- heroDescr = text.substr(text.indexOf(' ') + 1);
- return heroEle.click();
- }).then(function() {
- expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
- return viewDetailsButtonEle.click();
- }).then(function() {
- return editDetails(page, heroDescr, '-bar');
- }).then(function() {
- expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back');
- expect(heroEle.getText()).toContain(heroDescr + '-bar');
- expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present');
+ describe('Heroes tests', () => {
+
+ beforeAll(() => browser.get(''));
+
+ it('can switch to Heroes view', () => {
+ getPageElts().myHeroesHref.click();
+ let page = getPageElts();
+ expect(page.myHeroes.isPresent()).toBeTruthy();
+ expect(page.allHeroes.count()).toEqual(10, 'number of heroes');
});
+
+ it(`selects and shows ${targetHero.name} as selected in list`, () => {
+ getHeroLiEltById(targetHero.id).click();
+ let expectedText = `${targetHero.id} ${targetHero.name}`;
+ expect(getPageElts().selectedHero.getText()).toBe(expectedText);
+ });
+
+ it('shows selected hero subview', async () => {
+ let page = getPageElts();
+ let title = page.selectedHeroSubview.element(by.css('h2')).getText();
+ let expectedTitle = `${targetHero.name.toUpperCase()} is my hero`;
+ expect(title).toEqual(expectedTitle);
+ });
+
+ it('can route to hero details', async () => {
+ element(by.buttonText('View Details')).click();
+
+ let page = getPageElts();
+ expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail');
+ let hero = await Hero.fromDetail(page.heroDetail);
+ expect(hero.id).toEqual(targetHero.id);
+ expect(hero.name).toEqual(targetHero.name);
+ });
+
+ it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView);
+
+ it(`shows ${newHeroName} in Heroes list`, () => {
+ element(by.buttonText('Back')).click();
+ let expectedText = `${targetHero.id} ${newHeroName}`;
+ expect(getHeroLiEltById(targetHero.id).getText()).toEqual(expectedText);
+ });
+
});
- function editDetails(page: any, origValue: string, textToAdd: string) {
- expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
- expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present');
- expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details');
- let inputEle = page.heroDetail.element(by.css('input'));
- expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
- let backButtonEle = page.heroDetail.element(by.css('button'));
- expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
- let detailTextEle = page.heroDetail.element(by.css('div h2'));
- expect(detailTextEle.getText()).toContain(origValue);
- return sendKeys(inputEle, textToAdd).then(function () {
- expect(detailTextEle.getText()).toContain(origValue + textToAdd);
- return backButtonEle.click();
- });
+ async function dashboardSelectTargetHero() {
+ let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex);
+ expect(targetHeroElt.getText()).toEqual(targetHero.name);
+ targetHeroElt.click();
+
+ let page = getPageElts();
+ expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail');
+ let hero = await Hero.fromDetail(page.heroDetail);
+ expect(hero.id).toEqual(targetHero.id);
+ expect(hero.name).toEqual(targetHero.name);
+ }
+
+ async function updateHeroNameInDetailView() {
+ // Assumes that the current view is the hero details view.
+ addToHeroName(nameSuffix);
+
+ let page = getPageElts();
+ let hero = await Hero.fromDetail(page.heroDetail);
+ expect(hero.id).toEqual(targetHero.id);
+ expect(hero.name).toEqual(newHeroName);
}
});
+
+function addToHeroName(text: string): WPromise
{
+ let input = element(by.css('input'));
+ return sendKeys(input, text);
+}
+
+function expectHeading(hLevel: number, expectedText: string): void {
+ let hTag = `h${hLevel}`;
+ let hText = element(by.css(hTag)).getText();
+ expect(hText).toEqual(expectedText, hTag);
+};
+
+function getHeroLiEltById(id: number) {
+ let spanForId = element(by.cssContainingText('li span.badge', id.toString()));
+ return spanForId.element(by.xpath('..'));
+}
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.1.ts b/public/docs/_examples/toh-5/ts/app/app.component.1.ts
index cbdd040437..c9f5db9712 100644
--- a/public/docs/_examples/toh-5/ts/app/app.component.1.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.component.1.ts
@@ -1,7 +1,8 @@
// #docplaster
-// #docregion
+// #docregion , v2
import { Component } from '@angular/core';
+// #enddocregion v2
@Component({
selector: 'my-app',
template: `
@@ -9,6 +10,33 @@ import { Component } from '@angular/core';
`
})
+// #enddocregion
+// #docregion v2
+@Component({
+ selector: 'my-app',
+ // #docregion template-v2
+ template: `
+ {{title}}
+ Heroes
+
+ `
+ // #enddocregion template-v2
+})
+// #enddocregion
+@Component({
+ selector: 'my-app',
+ // #docregion template-v3
+ template: `
+ {{title}}
+
+ Dashboard
+ Heroes
+
+
+ `
+ // #enddocregion template-v3
+})
+// #docregion , v2
export class AppComponent {
title = 'Tour of Heroes';
}
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.2.ts b/public/docs/_examples/toh-5/ts/app/app.component.2.ts
deleted file mode 100644
index 82e5147775..0000000000
--- a/public/docs/_examples/toh-5/ts/app/app.component.2.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// #docplaster
-// #docregion
-import { Component } from '@angular/core';
-
-@Component({
- selector: 'my-app',
- // #docregion template
- template: `
- {{title}}
- Heroes
-
- `
- // #enddocregion template
-})
-export class AppComponent {
- title = 'Tour of Heroes';
-}
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.3.ts b/public/docs/_examples/toh-5/ts/app/app.component.3.ts
deleted file mode 100644
index 2d1f83853c..0000000000
--- a/public/docs/_examples/toh-5/ts/app/app.component.3.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// #docplaster
-// #docregion
-import { Component } from '@angular/core';
-
-@Component({
- selector: 'my-app',
- // #docregion template
- template: `
- {{title}}
-
- Dashboard
- Heroes
-
-
- `,
- // #enddocregion template
- // #docregion style-urls
- styleUrls: ['app/app.component.css'],
- // #enddocregion style-urls
-})
-export class AppComponent {
- title = 'Tour of Heroes';
-}
-// #enddocregion
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.ts b/public/docs/_examples/toh-5/ts/app/app.component.ts
index fbf2279067..12fe3bfd52 100644
--- a/public/docs/_examples/toh-5/ts/app/app.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.component.ts
@@ -1,4 +1,3 @@
-// #docplaster
// #docregion
import { Component } from '@angular/core';
@@ -14,9 +13,9 @@ import { Component } from '@angular/core';
`,
// #enddocregion template
- // #docregion style-urls
+ // #docregion styleUrls
styleUrls: ['app/app.component.css'],
- // #enddocregion style-urls
+ // #enddocregion styleUrls
})
export class AppComponent {
title = 'Tour of Heroes';
diff --git a/public/docs/_examples/toh-5/ts/app/app.module.1.ts b/public/docs/_examples/toh-5/ts/app/app.module.1.ts
index 473ca08fb8..e1cda9b620 100644
--- a/public/docs/_examples/toh-5/ts/app/app.module.1.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.module.1.ts
@@ -3,11 +3,10 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { AppComponent } from './app.component';
-
-import { HeroesComponent } from './heroes.component';
-
-import { HeroService } from './hero.service';
+import { AppComponent } from './app.component';
+import { HeroDetailComponent } from './hero-detail.component';
+import { HeroesComponent } from './heroes.component';
+import { HeroService } from './hero.service';
@NgModule({
imports: [
@@ -16,6 +15,7 @@ import { HeroService } from './hero.service';
],
declarations: [
AppComponent,
+ HeroDetailComponent,
HeroesComponent
],
providers: [
diff --git a/public/docs/_examples/toh-5/ts/app/app.module.2.ts b/public/docs/_examples/toh-5/ts/app/app.module.2.ts
deleted file mode 100644
index 1a4ac0f48d..0000000000
--- a/public/docs/_examples/toh-5/ts/app/app.module.2.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// #docregion
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from '@angular/forms';
-
-import { AppComponent } from './app.component';
-import { routing } from './app.routing';
-
-import { HeroesComponent } from './heroes.component';
-
-import { HeroService } from './hero.service';
-
-@NgModule({
- imports: [
- BrowserModule,
- FormsModule,
- routing
- ],
- declarations: [
- AppComponent,
- HeroesComponent
- ],
- providers: [
- HeroService
- ],
- bootstrap: [ AppComponent ]
-})
-export class AppModule {
-}
-// #enddocregion
diff --git a/public/docs/_examples/toh-5/ts/app/app.module.3.ts b/public/docs/_examples/toh-5/ts/app/app.module.3.ts
deleted file mode 100644
index 2eca272b26..0000000000
--- a/public/docs/_examples/toh-5/ts/app/app.module.3.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-// #docplaster
-// #docregion
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from '@angular/forms';
-
-import { AppComponent } from './app.component';
-import { routing } from './app.routing';
-
-import { HeroesComponent } from './heroes.component';
-// #docregion dashboard-declaration
-import { DashboardComponent } from './dashboard.component';
-// #enddocregion dashboard-declaration
-// #docregion hero-detail-declaration
-import { HeroDetailComponent } from './hero-detail.component';
-// #enddocregion hero-detail-declaration
-import { HeroService } from './hero.service';
-
-@NgModule({
- imports: [
- BrowserModule,
- FormsModule,
- routing
- ],
-// #docregion dashboard-declaration, hero-detail-declaration
-
- declarations: [
-// #enddocregion dashboard-declaration, hero-detail-declaration
- AppComponent,
- HeroesComponent,
-// #docregion dashboard-declaration
- DashboardComponent,
-// #enddocregion dashboard-declaration
-// #docregion hero-detail-declaration
- HeroDetailComponent
-// #enddocregion hero-detail-declaration
-// #docregion dashboard-declaration, hero-detail-declaration
- ],
-// #enddocregion dashboard-declaration, hero-detail-declaration
- providers: [
- HeroService
- ],
- bootstrap: [ AppComponent ]
-})
-export class AppModule {
-}
-// #enddocregion
diff --git a/public/docs/_examples/toh-5/ts/app/app.module.ts b/public/docs/_examples/toh-5/ts/app/app.module.ts
index 47cc9415bb..67bafebd38 100644
--- a/public/docs/_examples/toh-5/ts/app/app.module.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.module.ts
@@ -1,16 +1,17 @@
+// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
-import { AppComponent } from './app.component';
-import { routing } from './app.routing';
-
-import { HeroesComponent } from './heroes.component';
+import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard.component';
import { HeroDetailComponent } from './hero-detail.component';
-
-import { HeroService } from './hero.service';
+import { HeroesComponent } from './heroes.component';
+import { HeroService } from './hero.service';
+// #docregion routing
+import { routing } from './app.routing';
+// #docregion routing
@NgModule({
imports: [
@@ -18,17 +19,20 @@ import { HeroService } from './hero.service';
FormsModule,
routing
],
+ // #enddocregion routing
+ // #docregion dashboard, hero-detail
declarations: [
AppComponent,
- HeroesComponent,
DashboardComponent,
- HeroDetailComponent
+ HeroDetailComponent,
+ HeroesComponent
],
+ // #enddocregion dashboard, hero-detail
providers: [
HeroService
],
bootstrap: [ AppComponent ]
+ // #docregion routing
})
export class AppModule {
}
-// #enddocregion
diff --git a/public/docs/_examples/toh-5/ts/app/app.routing.1.ts b/public/docs/_examples/toh-5/ts/app/app.routing.1.ts
index 055b26754e..a69db4104b 100644
--- a/public/docs/_examples/toh-5/ts/app/app.routing.1.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.routing.1.ts
@@ -1,5 +1,5 @@
-// #docregion
-// #docregion routing-config
+// #docregion , heroes, routing
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HeroesComponent } from './heroes.component';
@@ -10,8 +10,8 @@ const appRoutes: Routes = [
component: HeroesComponent
}
];
-// #enddocregion routing-config
+// #enddocregion heroes, routing
// #docregion routing-export
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
// #enddocregion routing-export
diff --git a/public/docs/_examples/toh-5/ts/app/app.routing.2.ts b/public/docs/_examples/toh-5/ts/app/app.routing.2.ts
deleted file mode 100644
index a75df506e7..0000000000
--- a/public/docs/_examples/toh-5/ts/app/app.routing.2.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-// #docregion
-import { Routes, RouterModule } from '@angular/router';
-
-import { DashboardComponent } from './dashboard.component';
-import { HeroesComponent } from './heroes.component';
-// #docregion hero-detail-import
-import { HeroDetailComponent } from './hero-detail.component';
-// #enddocregion hero-detail-import
-
-const appRoutes: Routes = [
- // #docregion redirect-route
- {
- path: '',
- redirectTo: '/dashboard',
- pathMatch: 'full'
- },
- // #enddocregion redirect-route
- // #docregion dashboard-route
- {
- path: 'dashboard',
- component: DashboardComponent
- },
- // #enddocregion dashboard-route
- // #docregion hero-detail-route
- {
- path: 'detail/:id',
- component: HeroDetailComponent
- },
- // #enddocregion hero-detail-route
- {
- path: 'heroes',
- component: HeroesComponent
- }
-];
-
-export const routing = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/toh-5/ts/app/app.routing.ts b/public/docs/_examples/toh-5/ts/app/app.routing.ts
index 62071e2567..81f6d05ed2 100644
--- a/public/docs/_examples/toh-5/ts/app/app.routing.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.routing.ts
@@ -1,30 +1,43 @@
-// #docregion
+// #docplaster
+// #docregion , heroes
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-import { DashboardComponent } from './dashboard.component';
-import { HeroesComponent } from './heroes.component';
-// #docregion hero-detail-import
-import { HeroDetailComponent } from './hero-detail.component';
-// #enddocregion hero-detail-import
+// #enddocregion heroes
+import { DashboardComponent } from './dashboard.component';
+// #docregion heroes
+import { HeroesComponent } from './heroes.component';
+// #enddocregion heroes
+import { HeroDetailComponent } from './hero-detail.component';
+// #docregion heroes
const appRoutes: Routes = [
+ // #enddocregion heroes
+ // #docregion redirect
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full'
},
+ // #enddocregion redirect
+ // #docregion dashboard
{
path: 'dashboard',
component: DashboardComponent
},
+ // #enddocregion dashboard
+ // #docregion hero-detail
{
path: 'detail/:id',
component: HeroDetailComponent
},
+ // #enddocregion hero-detail
+ // #docregion heroes
{
path: 'heroes',
component: HeroesComponent
}
];
+// #enddocregion heroes
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts
index e6b9609ab0..38decd2b50 100644
--- a/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts
+++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts
@@ -17,10 +17,10 @@ export class DashboardComponent implements OnInit {
constructor(private heroService: HeroService) { }
- ngOnInit() {
+ ngOnInit(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
- gotoDetail() { /* not implemented yet */}
+ gotoDetail(hero: Hero): void { /* not implemented yet */}
}
diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts
index 6dd4b1abc2..3deb5bc2ec 100644
--- a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts
@@ -10,9 +10,9 @@ import { HeroService } from './hero.service';
@Component({
selector: 'my-dashboard',
- // #docregion template-url
+ // #docregion templateUrl
templateUrl: 'app/dashboard.component.html',
- // #enddocregion template-url
+ // #enddocregion templateUrl
// #docregion css
styleUrls: ['app/dashboard.component.css']
// #enddocregion css
@@ -29,15 +29,15 @@ export class DashboardComponent implements OnInit {
}
// #enddocregion ctor
- ngOnInit() {
+ ngOnInit(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
- // #docregion goto-detail
- gotoDetail(hero: Hero) {
+ // #docregion gotoDetail
+ gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
- // #enddocregion goto-detail
+ // #enddocregion gotoDetail
}
diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.1.ts b/public/docs/_examples/toh-5/ts/app/hero-detail.component.1.ts
new file mode 100644
index 0000000000..efbe8ee913
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/hero-detail.component.1.ts
@@ -0,0 +1,27 @@
+// Imports in comments cause problems when the app is executed
+// (some error about 'traceur' missing). Hence this separate file
+// is solely for containing the transitory state of the imports.
+
+// #docregion added-imports
+// Keep the Input import for now, we'll remove it later:
+import { Component, Input, OnInit } from '@angular/core';
+import { ActivatedRoute, Params } from '@angular/router';
+
+import { HeroService } from './hero.service';
+// #enddocregion added-imports
+
+// Bogus code below this point. It is only here to make lint happy.
+import { Hero } from './hero';
+
+@Component({})
+export class HeroDetailComponent implements OnInit {
+ @Input() hero: Hero;
+ bogus: Params;
+
+ constructor(
+ private heroService: HeroService,
+ private route: ActivatedRoute) {
+ }
+
+ ngOnInit() {}
+}
diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts
index 713d27c9f2..5513904452 100644
--- a/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts
@@ -1,30 +1,22 @@
// #docplaster
-// #docregion
-// #docregion import-oninit, v2
+// #docregion , v2
import { Component, OnInit } from '@angular/core';
-// #enddocregion import-oninit
-// #docregion import-activated-route
import { ActivatedRoute, Params } from '@angular/router';
-// #enddocregion import-activated-route
import { Hero } from './hero';
-// #docregion import-hero-service
import { HeroService } from './hero.service';
-// #enddocregion import-hero-service
-// #docregion extract-template
@Component({
selector: 'my-hero-detail',
- // #docregion template-url
+ // #docregion templateUrl
templateUrl: 'app/hero-detail.component.html',
- // #enddocregion template-url, v2
+ // #enddocregion templateUrl, v2
styleUrls: ['app/hero-detail.component.css']
// #docregion v2
})
-// #enddocregion extract-template
// #docregion implement
export class HeroDetailComponent implements OnInit {
- // #enddocregion implement
+// #enddocregion implement
hero: Hero;
// #docregion ctor
@@ -34,21 +26,19 @@ export class HeroDetailComponent implements OnInit {
}
// #enddocregion ctor
- // #docregion ng-oninit
- ngOnInit() {
- // #docregion get-id
+ // #docregion ngOnInit
+ ngOnInit(): void {
this.route.params.forEach((params: Params) => {
let id = +params['id'];
this.heroService.getHero(id)
.then(hero => this.hero = hero);
});
- // #enddocregion get-id
}
- // #enddocregion ng-oninit
+ // #enddocregion ngOnInit
- // #docregion go-back
- goBack() {
+ // #docregion goBack
+ goBack(): void {
window.history.back();
}
-// #enddocregion go-back
+// #enddocregion goBack
}
diff --git a/public/docs/_examples/toh-5/ts/app/hero.service.ts b/public/docs/_examples/toh-5/ts/app/hero.service.ts
index 900d0da712..163734fe5f 100644
--- a/public/docs/_examples/toh-5/ts/app/hero.service.ts
+++ b/public/docs/_examples/toh-5/ts/app/hero.service.ts
@@ -6,21 +6,20 @@ import { Injectable } from '@angular/core';
@Injectable()
export class HeroService {
- getHeroes() {
+ getHeroes(): Promise {
return Promise.resolve(HEROES);
}
- // See the "Take it slow" appendix
- getHeroesSlowly() {
+ getHeroesSlowly(): Promise {
return new Promise(resolve =>
- setTimeout(() => resolve(HEROES), 2000) // 2 seconds
- );
+ setTimeout(resolve, 2000)) // delay 2 seconds
+ .then(() => this.getHeroes());
}
- // #docregion get-hero
- getHero(id: number) {
+ // #docregion getHero
+ getHero(id: number): Promise {
return this.getHeroes()
.then(heroes => heroes.find(hero => hero.id === id));
}
- // #enddocregion get-hero
+ // #enddocregion getHero
}
diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.ts b/public/docs/_examples/toh-5/ts/app/heroes.component.ts
index c0dbd9c8e7..da66bfa7af 100644
--- a/public/docs/_examples/toh-5/ts/app/heroes.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/heroes.component.ts
@@ -6,18 +6,18 @@ import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
-// #docregion heroes-component-renaming, metadata
+// #docregion renaming, metadata
@Component({
selector: 'my-heroes',
- // #enddocregion heroes-component-renaming
+ // #enddocregion renaming
templateUrl: 'app/heroes.component.html',
styleUrls: ['app/heroes.component.css']
- // #docregion heroes-component-renaming
+ // #docregion renaming
})
-// #enddocregion heroes-component-renaming, metadata
-// #docregion class, heroes-component-renaming
+// #enddocregion metadata
+// #docregion class
export class HeroesComponent implements OnInit {
- // #enddocregion heroes-component-renaming
+ // #enddocregion renaming
heroes: Hero[];
selectedHero: Hero;
@@ -25,18 +25,20 @@ export class HeroesComponent implements OnInit {
private router: Router,
private heroService: HeroService) { }
- getHeroes() {
+ getHeroes(): void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
- ngOnInit() {
+ ngOnInit(): void {
this.getHeroes();
}
- onSelect(hero: Hero) { this.selectedHero = hero; }
+ onSelect(hero: Hero): void {
+ this.selectedHero = hero;
+ }
- gotoDetail() {
+ gotoDetail(): void {
this.router.navigate(['/detail', this.selectedHero.id]);
}
- // #docregion heroes-component-renaming
+ // #docregion renaming
}
diff --git a/public/docs/_examples/toh-5/ts/index.html b/public/docs/_examples/toh-5/ts/index.html
index 4df64edba1..f8383d0c94 100644
--- a/public/docs/_examples/toh-5/ts/index.html
+++ b/public/docs/_examples/toh-5/ts/index.html
@@ -5,7 +5,7 @@
- Angular 2 Tour of Heroes
+ Angular Tour of Heroes
diff --git a/public/docs/_examples/toh-5/ts/styles.1.css b/public/docs/_examples/toh-5/ts/styles.1.css
deleted file mode 100644
index dee6d5b8ca..0000000000
--- a/public/docs/_examples/toh-5/ts/styles.1.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/* #docregion toh-excerpt */
-/* 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;
-}
-/* . . . */
-/* everywhere else */
-* {
- font-family: Arial, Helvetica, sans-serif;
-}
diff --git a/public/docs/_examples/forms-deprecated/ts/example-config.json b/public/docs/_examples/toh-6/dart/example-config.json
similarity index 100%
rename from public/docs/_examples/forms-deprecated/ts/example-config.json
rename to public/docs/_examples/toh-6/dart/example-config.json
diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart
index da965c301c..d23b7f543d 100644
--- a/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart
+++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart
@@ -1,4 +1,4 @@
-// #docregion , search
+// #docregion
import 'dart:async';
import 'package:angular2/core.dart';
@@ -6,6 +6,7 @@ import 'package:angular2/router.dart';
import 'hero.dart';
import 'hero_service.dart';
+// #docregion search
import 'hero_search_component.dart';
@Component(
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart
index 39f9f531f5..5e7a1b6168 100644
--- a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart
+++ b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart
@@ -3,59 +3,38 @@
import 'dart:async';
import 'dart:html';
-// #docregion import-oninit
import 'package:angular2/core.dart';
-// #enddocregion import-oninit
-// #docregion import-route-params
import 'package:angular2/router.dart';
-// #enddocregion import-route-params
import 'hero.dart';
-// #docregion import-hero-service
import 'hero_service.dart';
-// #enddocregion import-hero-service
-// #docregion extract-template
@Component(
selector: 'my-hero-detail',
- // #docregion template-url
templateUrl: 'hero_detail_component.html',
- // #enddocregion template-url, v2
styleUrls: const ['hero_detail_component.css']
- // #docregion v2
)
-// #enddocregion extract-template
-// #docregion implement
class HeroDetailComponent implements OnInit {
- // #enddocregion implement
Hero hero;
- // #docregion ctor
final HeroService _heroService;
final RouteParams _routeParams;
HeroDetailComponent(this._heroService, this._routeParams);
- // #enddocregion ctor
- // #docregion ng-oninit
Future ngOnInit() async {
- // #docregion get-id
var idString = _routeParams.get('id');
var id = int.parse(idString, onError: (_) => null);
- // #enddocregion get-id
if (id != null) hero = await (_heroService.getHero(id));
}
- // #enddocregion ng-oninit
// #docregion save
Future save() async {
- await _heroService.save(hero);
+ await _heroService.update(hero);
goBack();
}
// #enddocregion save
- // #docregion go-back
void goBack() {
window.history.back();
}
- // #enddocregion go-back
}
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html
index d15546af74..161dc2246e 100644
--- a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html
+++ b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html
@@ -1,4 +1,3 @@
-
{{hero.name}} details!
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_service.dart b/public/docs/_examples/toh-6/dart/lib/hero_service.dart
index 7a15c6473f..38e8357968 100644
--- a/public/docs/_examples/toh-6/dart/lib/hero_service.dart
+++ b/public/docs/_examples/toh-6/dart/lib/hero_service.dart
@@ -1,4 +1,5 @@
-// #docregion
+// #docplaster
+// #docregion , imports
import 'dart:async';
import 'dart:convert';
@@ -6,12 +7,13 @@ import 'package:angular2/core.dart';
import 'package:http/http.dart';
import 'hero.dart';
+// #enddocregion imports
@Injectable()
class HeroService {
- // #docregion post
+ // #docregion update
static final _headers = {'Content-Type': 'application/json'};
- // #enddocregion post
+ // #enddocregion update
// #docregion getHeroes
static const _heroesUrl = 'app/heroes'; // URL to web API
@@ -35,25 +37,20 @@ class HeroService {
// #docregion extract-data
dynamic _extractData(Response resp) => JSON.decode(resp.body)['data'];
- // #enddocregion extract-data, getHeroes
-
- Future
getHero(int id) async =>
- (await getHeroes()).firstWhere((hero) => hero.id == id);
-
- // #docregion save
- Future save(dynamic heroOrName) =>
- heroOrName is Hero ? _put(heroOrName) : _post(heroOrName);
- // #enddocregion save
+ // #enddocregion extract-data
// #docregion handleError
Exception _handleError(dynamic e) {
print(e); // for demo purposes only
return new Exception('Server error; cause: $e');
}
- // #enddocregion handleError
+ // #enddocregion handleError, getHeroes
- // #docregion post
- Future _post(String name) async {
+ Future getHero(int id) async =>
+ (await getHeroes()).firstWhere((hero) => hero.id == id);
+
+ // #docregion create
+ Future create(String name) async {
try {
final response = await _http.post(_heroesUrl,
headers: _headers, body: JSON.encode({'name': name}));
@@ -62,10 +59,10 @@ class HeroService {
throw _handleError(e);
}
}
- // #enddocregion post
+ // #enddocregion create
+ // #docregion update
- // #docregion put
- Future _put(Hero hero) async {
+ Future update(Hero hero) async {
try {
var url = '$_heroesUrl/${hero.id}';
final response =
@@ -75,7 +72,7 @@ class HeroService {
throw _handleError(e);
}
}
- // #enddocregion put
+ // #enddocregion update
// #docregion delete
Future delete(int id) async {
diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.css b/public/docs/_examples/toh-6/dart/lib/heroes_component.css
index 15efef53e4..d2c958a911 100644
--- a/public/docs/_examples/toh-6/dart/lib/heroes_component.css
+++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.css
@@ -59,9 +59,10 @@ button:hover {
background-color: #cfd8dc;
}
/* #docregion additions */
-.error {color:red;}
-button.delete-button {
+button.delete {
float:right;
+ margin-top: 2px;
+ margin-right: .8em;
background-color: gray !important;
color:white;
}
diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.dart b/public/docs/_examples/toh-6/dart/lib/heroes_component.dart
index 4cfc0c427e..19b8f4e0ba 100644
--- a/public/docs/_examples/toh-6/dart/lib/heroes_component.dart
+++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.dart
@@ -1,4 +1,3 @@
-// #docplaster
// #docregion
import 'dart:async';
@@ -15,45 +14,35 @@ import 'hero_service.dart';
styleUrls: const ['heroes_component.css'],
directives: const [HeroDetailComponent])
class HeroesComponent implements OnInit {
- final Router _router;
- final HeroService _heroService;
List heroes;
Hero selectedHero;
- // #docregion error
- String errorMessage;
- // #enddocregion error
+
+ final HeroService _heroService;
+ final Router _router;
HeroesComponent(this._heroService, this._router);
- // #docregion addHero
- Future addHero(String name) async {
- name = name.trim();
- if (name.isEmpty) return;
- try {
- heroes.add(await _heroService.save(name));
- } catch (e) {
- errorMessage = e.toString();
- }
- }
- // #enddocregion addHero
-
- // #docregion deleteHero
- Future deleteHero(int id, event) async {
- try {
- event.stopPropagation();
- await _heroService.delete(id);
- heroes.removeWhere((hero) => hero.id == id);
- if (selectedHero?.id == id) selectedHero = null;
- } catch (e) {
- errorMessage = e.toString();
- }
- }
- // #enddocregion deleteHero
-
Future getHeroes() async {
heroes = await _heroService.getHeroes();
}
+ // #docregion add
+ Future add(String name) async {
+ name = name.trim();
+ if (name.isEmpty) return;
+ heroes.add(await _heroService.create(name));
+ selectedHero = null;
+ }
+ // #enddocregion add
+
+ // #docregion delete
+ Future delete(Hero hero) async {
+ await _heroService.delete(hero.id);
+ heroes.remove(hero);
+ if (selectedHero == hero) selectedHero = null;
+ }
+ // #enddocregion delete
+
void ngOnInit() {
getHeroes();
}
diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.html b/public/docs/_examples/toh-6/dart/lib/heroes_component.html
index 98f3db8442..3ffb597fbc 100644
--- a/public/docs/_examples/toh-6/dart/lib/heroes_component.html
+++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.html
@@ -1,31 +1,30 @@
My Heroes
-
-{{errorMessage}}
+
- Name:
-
- Add New Hero
+ Hero name:
+
+ Add
-
+
-
- {{hero.id}} {{hero.name}}
+
+
+ {{hero.id}}
+ {{hero.name}}
- x
+ x
+
-
-
{{selectedHero.name | uppercase}} is my hero
-
View Details
diff --git a/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart b/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart
index 927b93bc70..5be0f9e8c4 100644
--- a/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart
+++ b/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart
@@ -1,9 +1,8 @@
-// #docregion
+// #docregion , init
import 'dart:async';
import 'dart:convert';
import 'dart:math';
-// #docregion init
import 'package:angular2/core.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';
@@ -26,7 +25,6 @@ class InMemoryDataService extends MockClient {
];
static final List _heroesDb =
_initialHeroes.map((json) => new Hero.fromJson(json)).toList();
- // #enddocregion init
static int _nextId = _heroesDb.map((hero) => hero.id).reduce(max) + 1;
static Future _handler(Request request) async {
@@ -37,6 +35,7 @@ class InMemoryDataService extends MockClient {
final regExp = new RegExp(prefix, caseSensitive: false);
data = _heroesDb.where((hero) => hero.name.contains(regExp)).toList();
break;
+ // #enddocregion init-disabled
case 'POST':
var name = JSON.decode(request.body)['name'];
var newHero = new Hero(_nextId++, name);
@@ -54,6 +53,7 @@ class InMemoryDataService extends MockClient {
_heroesDb.removeWhere((hero) => hero.id == id);
// No data, so leave it as null.
break;
+ // #docregion init-disabled
default:
throw 'Unimplemented HTTP method ${request.method}';
}
@@ -62,5 +62,4 @@ class InMemoryDataService extends MockClient {
}
InMemoryDataService() : super(_handler);
- // #docregion init
}
diff --git a/public/docs/_examples/toh-6/dart/pubspec.yaml b/public/docs/_examples/toh-6/dart/pubspec.yaml
index cdb0ce29f1..653f7ec2f4 100644
--- a/public/docs/_examples/toh-6/dart/pubspec.yaml
+++ b/public/docs/_examples/toh-6/dart/pubspec.yaml
@@ -7,7 +7,7 @@ environment:
sdk: '>=1.13.0 <2.0.0'
# #docregion additions
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
# #enddocregion additions
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
diff --git a/public/docs/_examples/toh-6/dart/web/main.dart b/public/docs/_examples/toh-6/dart/web/main.dart
index ff344d1a54..614e95be10 100644
--- a/public/docs/_examples/toh-6/dart/web/main.dart
+++ b/public/docs/_examples/toh-6/dart/web/main.dart
@@ -1,12 +1,11 @@
// #docplaster
-// #docregion final
-// #docregion v1
+// #docregion , v1, v2
import 'package:angular2/core.dart';
import 'package:angular2/platform/browser.dart';
import 'package:angular2_tour_of_heroes/app_component.dart';
// #enddocregion v1
-import 'package:http/http.dart';
import 'package:angular2_tour_of_heroes/in_memory_data_service.dart';
+import 'package:http/http.dart';
void main() {
bootstrap(AppComponent,
@@ -15,7 +14,7 @@ void main() {
// [provide(Client, useFactory: () => new BrowserClient(), deps: [])]
);
}
-// #enddocregion final
+// #enddocregion v2,
/*
// #docregion v1
import 'package:http/browser_client.dart';
diff --git a/public/docs/_examples/toh-6/e2e-spec.ts b/public/docs/_examples/toh-6/e2e-spec.ts
index e2ab2602dc..8152ac308c 100644
--- a/public/docs/_examples/toh-6/e2e-spec.ts
+++ b/public/docs/_examples/toh-6/e2e-spec.ts
@@ -1,246 +1,283 @@
///
'use strict';
-describe('TOH Http Chapter', function () {
- beforeEach(function () {
- browser.get('');
- });
+const expectedH1 = 'Tour of Heroes';
+const expectedTitle = `Angular ${expectedH1}`;
+const targetHero = { id: 15, name: 'Magneta' };
+const targetHeroDashboardIndex = 3;
+const nameSuffix = 'X';
+const newHeroName = targetHero.name + nameSuffix;
- function getPageStruct() {
- let hrefEles = element.all(by.css('my-app a'));
+type WPromise = webdriver.promise.Promise;
+
+class Hero {
+ id: number;
+ name: string;
+
+ // Factory methods
+
+ // Hero from string formatted as ' '.
+ static fromString(s: string): Hero {
+ return {
+ id: +s.substr(0, s.indexOf(' ')),
+ name: s.substr(s.indexOf(' ') + 1),
+ };
+ }
+
+ // Hero from hero list element.
+ static async fromLi(li: protractor.ElementFinder): Promise {
+ let strings = await li.all(by.xpath('span')).getText();
+ return { id: +strings[0], name: strings[1] };
+ }
+
+ // Hero id and name from the given detail element.
+ static async fromDetail(detail: protractor.ElementFinder): Promise {
+ // Get hero id from the first
+ let _id = await detail.all(by.css('div')).first().getText();
+ // Get name from the h2
+ let _name = await detail.element(by.css('h2')).getText();
+ return {
+ id: +_id.substr(_id.indexOf(' ') + 1),
+ name: _name.substr(0, _name.lastIndexOf(' '))
+ };
+ }
+}
+
+describe('Tutorial part 6', () => {
+
+ beforeAll(() => browser.get(''));
+
+ function getPageElts() {
+ let hrefElts = element.all(by.css('my-app a'));
return {
- hrefs: hrefEles,
- myDashboardHref: hrefEles.get(0),
- myDashboardParent: element(by.css('my-app my-dashboard')),
- topHeroes: element.all(by.css('my-app my-dashboard .module.hero')),
+ hrefs: hrefElts,
- myHeroesHref: hrefEles.get(1),
- myHeroesParent: element(by.css('my-app my-heroes')),
- allHeroes: element.all(by.css('my-app my-heroes li .hero-element')),
+ myDashboardHref: hrefElts.get(0),
+ myDashboard: element(by.css('my-app my-dashboard')),
+ topHeroes: element.all(by.css('my-app my-dashboard > div h4')),
- firstDeleteButton: element.all(by.buttonText('Delete')).get(0),
+ myHeroesHref: hrefElts.get(1),
+ myHeroes: element(by.css('my-app my-heroes')),
+ allHeroes: element.all(by.css('my-app my-heroes li')),
+ selectedHero: element(by.css('my-app li.selected')),
+ selectedHeroSubview: element(by.css('my-app my-heroes > div:last-child')),
- addButton: element.all(by.buttonText('Add New Hero')).get(0),
-
- heroDetail: element(by.css('my-app my-hero-detail')),
+ heroDetail: element(by.css('my-app my-hero-detail > div')),
searchBox: element(by.css('#search-box')),
searchResults: element.all(by.css('.search-result'))
};
}
- it('should search for hero and navigate to details view', function() {
- let page = getPageStruct();
+ describe('Initial page', () => {
- return sendKeys(page.searchBox, 'Magneta').then(function () {
+ it(`has title '${expectedTitle}'`, () => {
+ expect(browser.getTitle()).toEqual(expectedTitle);
+ });
+
+ it(`has h1 '${expectedH1}'`, () => {
+ expectHeading(1, expectedH1);
+ });
+
+ const expectedViewNames = ['Dashboard', 'Heroes'];
+ it(`has views ${expectedViewNames}`, () => {
+ let viewNames = getPageElts().hrefs.map(el => el.getText());
+ expect(viewNames).toEqual(expectedViewNames);
+ });
+
+ it('has dashboard as the active view', () => {
+ let page = getPageElts();
+ expect(page.myDashboard.isPresent()).toBeTruthy();
+ });
+
+ });
+
+ describe('Dashboard tests', () => {
+
+ beforeAll(() => browser.get(''));
+
+ it('has top heroes', () => {
+ let page = getPageElts();
+ expect(page.topHeroes.count()).toEqual(4);
+ });
+
+ it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero);
+
+ it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView);
+
+ it(`cancels and shows ${targetHero.name} in Dashboard`, () => {
+ element(by.buttonText('Back')).click();
+ browser.waitForAngular(); // seems necessary to gets tests to past for toh-6
+
+ let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex);
+ expect(targetHeroElt.getText()).toEqual(targetHero.name);
+ });
+
+ it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero);
+
+ it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView);
+
+ it(`saves and shows ${newHeroName} in Dashboard`, () => {
+ element(by.buttonText('Save')).click();
+ browser.waitForAngular(); // seems necessary to gets tests to past for toh-6
+
+ let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex);
+ expect(targetHeroElt.getText()).toEqual(newHeroName);
+ });
+
+ });
+
+ describe('Heroes tests', () => {
+
+ beforeAll(() => browser.get(''));
+
+ it('can switch to Heroes view', () => {
+ getPageElts().myHeroesHref.click();
+ let page = getPageElts();
+ expect(page.myHeroes.isPresent()).toBeTruthy();
+ expect(page.allHeroes.count()).toEqual(10, 'number of heroes');
+ });
+
+ it(`selects and shows ${targetHero.name} as selected in list`, () => {
+ getHeroLiEltById(targetHero.id).click();
+ expect(Hero.fromLi(getPageElts().selectedHero)).toEqual(targetHero);
+ });
+
+ it('shows selected hero subview', () => {
+ let page = getPageElts();
+ let title = page.selectedHeroSubview.element(by.css('h2')).getText();
+ let expectedTitle = `${targetHero.name.toUpperCase()} is my hero`;
+ expect(title).toEqual(expectedTitle);
+ });
+
+ it('can route to hero details', () => {
+ element(by.buttonText('View Details')).click();
+
+ let page = getPageElts();
+ expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail');
+ let hero = Hero.fromDetail(page.heroDetail);
+ expect(hero).toEqual(targetHero);
+ });
+
+ it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView);
+
+ it(`shows ${newHeroName} in Heroes list`, () => {
+ element(by.buttonText('Save')).click();
+ browser.waitForAngular(); // seems necessary to gets tests to past for toh-6
+ let expectedHero = {id: targetHero.id, name: newHeroName};
+ expect(Hero.fromLi(getHeroLiEltById(targetHero.id))).toEqual(expectedHero);
+ });
+
+ it(`deletes ${newHeroName} from Heroes list`, async () => {
+ const heroesBefore = await toHeroArray(getPageElts().allHeroes);
+ const li = getHeroLiEltById(targetHero.id);
+ li.element(by.buttonText('x')).click();
+
+ const page = getPageElts();
+ expect(page.myHeroes.isPresent()).toBeTruthy();
+ expect(page.allHeroes.count()).toEqual(9, 'number of heroes');
+ const heroesAfter = await toHeroArray(page.allHeroes);
+ const expectedHeroes = heroesBefore.filter(h => h.name !== newHeroName);
+ expect(heroesAfter).toEqual(expectedHeroes);
+ expect(page.selectedHeroSubview.isPresent()).toBeFalsy();
+ });
+
+ it(`adds back ${targetHero.name}`, async () => {
+ const newHeroName = 'Alice';
+ const heroesBefore = await toHeroArray(getPageElts().allHeroes);
+ const numHeroes = heroesBefore.length;
+
+ sendKeys(element(by.css('input')), newHeroName);
+ element(by.buttonText('Add')).click();
+
+ let page = getPageElts();
+ let heroesAfter = await toHeroArray(page.allHeroes);
+ expect(heroesAfter.length).toEqual(numHeroes + 1, 'number of heroes');
+
+ expect(heroesAfter.slice(0, numHeroes)).toEqual(heroesBefore, 'Old heroes are still there');
+
+ const maxId = heroesBefore[heroesBefore.length - 1].id;
+ expect(heroesAfter[numHeroes]).toEqual({id: maxId + 1, name: newHeroName});
+ });
+ });
+
+ describe('Progressive hero search', () => {
+
+ beforeAll(() => browser.get(''));
+
+ it(`searches for 'Ma'`, async () => {
+ sendKeys(getPageElts().searchBox, 'Ma');
+ browser.sleep(1000);
+ expect(getPageElts().searchResults.count()).toBe(4);
+ });
+
+ it(`continues search with 'g'`, async () => {
+ sendKeys(getPageElts().searchBox, 'g');
+ browser.sleep(1000);
+ expect(getPageElts().searchResults.count()).toBe(2);
+ });
+
+ it(`continues search with 'n' and gets ${targetHero.name}`, async () => {
+ sendKeys(getPageElts().searchBox, 'n');
+ browser.sleep(1000);
+ let page = getPageElts();
expect(page.searchResults.count()).toBe(1);
let hero = page.searchResults.get(0);
- return hero.click();
- })
- .then(function() {
- browser.waitForAngular();
- let inputEle = page.heroDetail.element(by.css('input'));
- return inputEle.getAttribute('value');
- })
- .then(function(value) {
- expect(value).toBe('Magneta');
+ expect(hero.getText()).toEqual(targetHero.name);
+ });
+
+ it(`navigates to ${targetHero.name} details view`, async () => {
+ let hero = getPageElts().searchResults.get(0);
+ expect(hero.getText()).toEqual(targetHero.name);
+ hero.click();
+
+ let page = getPageElts();
+ expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail');
+ expect(Hero.fromDetail(page.heroDetail)).toEqual(targetHero);
});
});
- it('should be able to add a hero from the "Heroes" view', function(){
- let page = getPageStruct();
- let heroCount: webdriver.promise.Promise
;
+ function dashboardSelectTargetHero() {
+ let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex);
+ expect(targetHeroElt.getText()).toEqual(targetHero.name);
+ targetHeroElt.click();
+ browser.waitForAngular(); // seems necessary to gets tests to past for toh-6
- page.myHeroesHref.click().then(function() {
- browser.waitForAngular();
- heroCount = page.allHeroes.count();
- expect(heroCount).toBe(10, 'should show 10');
- }).then(function() {
- return page.addButton.click();
- }).then(function(){
- return save(page, '', 'The New Hero');
- }).then(function(){
- browser.waitForAngular();
-
- heroCount = page.allHeroes.count();
- expect(heroCount).toBe(11, 'should show 11');
-
- let newHero = element(by.xpath('//span[@class="hero-element" and contains(text(),"The New Hero")]'));
- expect(newHero).toBeDefined();
- });
- });
-
- it('should be able to delete hero from "Heroes" view', function(){
- let page = getPageStruct();
- let heroCount: webdriver.promise.Promise;
-
- page.myHeroesHref.click().then(function() {
- browser.waitForAngular();
- heroCount = page.allHeroes.count();
- expect(heroCount).toBe(10, 'should show 10');
- }).then(function() {
- return page.firstDeleteButton.click();
- }).then(function(){
- browser.waitForAngular();
- heroCount = page.allHeroes.count();
- expect(heroCount).toBe(9, 'should show 9');
- });
- });
-
- it('should be able to save details from "Dashboard" view', function () {
- let page = getPageStruct();
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
- let heroEle = page.topHeroes.get(2);
- let heroDescrEle = heroEle.element(by.css('h4'));
- let heroDescr: string;
-
- return heroDescrEle.getText().then(function(text) {
- heroDescr = text;
- return heroEle.click();
- }).then(function() {
- return save(page, heroDescr, '-foo');
- })
- .then(function(){
- return page.myDashboardHref.click();
- })
- .then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back');
- expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo');
- });
- });
-
- it('should be able to save details from "Heroes" view', function () {
- let page = getPageStruct();
-
- let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
- let heroEle: protractor.ElementFinder, heroDescr: string;
-
- page.myHeroesHref.click().then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
- expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
- expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present');
- heroEle = page.allHeroes.get(0);
- return heroEle.getText();
- }).then(function(text) {
- // remove leading 'id' from the element
- heroDescr = text.substr(text.indexOf(' ') + 1);
- return heroEle.click();
- }).then(function() {
- expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
- return viewDetailsButtonEle.click();
- }).then(function() {
- return save(page, heroDescr, '-bar');
- })
- .then(function(){
- return page.myHeroesHref.click();
- })
- .then(function() {
- expect(heroEle.getText()).toContain(heroDescr + '-bar');
- });
- });
-
- function save(page: any, origValue: string, textToAdd: string) {
- let inputEle = page.heroDetail.element(by.css('input'));
- expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
- let saveButtonEle = page.heroDetail.element(by.buttonText('Save'));
- let backButtonEle = page.heroDetail.element(by.buttonText('Back'));
- expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
- let detailTextEle = page.heroDetail.element(by.css('div h2'));
- expect(detailTextEle.getText()).toContain(origValue);
- return sendKeys(inputEle, textToAdd).then(function () {
- expect(detailTextEle.getText()).toContain(origValue + textToAdd);
- return saveButtonEle.click();
- });
+ let page = getPageElts();
+ expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail');
+ let hero = Hero.fromDetail(page.heroDetail);
+ expect(hero).toEqual(targetHero);
}
- it('should be able to see the start screen', function () {
- let page = getPageStruct();
- expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
- expect(page.myDashboardHref.getText()).toEqual('Dashboard');
- expect(page.myHeroesHref.getText()).toEqual('Heroes');
- });
+ async function updateHeroNameInDetailView() {
+ // Assumes that the current view is the hero details view.
+ addToHeroName(nameSuffix);
- it('should be able to see dashboard choices', function () {
- let page = getPageStruct();
- expect(page.topHeroes.count()).toBe(4, 'should be 4 dashboard hero choices');
- });
-
- it('should be able to toggle the views', function () {
- let page = getPageStruct();
-
- expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
- page.myHeroesHref.click().then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element');
- expect(page.allHeroes.count()).toBeGreaterThan(4, 'should be more than 4 heroes shown');
- return page.myDashboardHref.click();
- }).then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element');
- });
-
- });
-
- it('should be able to edit details from "Dashboard" view', function () {
- let page = getPageStruct();
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
- let heroEle = page.topHeroes.get(3);
- let heroDescrEle = heroEle.element(by.css('h4'));
- let heroDescr: string;
- return heroDescrEle.getText().then(function(text) {
- heroDescr = text;
- return heroEle.click();
- }).then(function() {
- return editDetails(page, heroDescr, '-foo');
- }).then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back');
- expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo');
- });
- });
-
- it('should be able to edit details from "Heroes" view', function () {
- let page = getPageStruct();
- expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present');
- let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
- let heroEle: protractor.ElementFinder, heroDescr: string;
- page.myHeroesHref.click().then(function() {
- expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
- expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
- expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present');
- heroEle = page.allHeroes.get(2);
- return heroEle.getText();
- }).then(function(text) {
- // remove leading 'id' from the element
- heroDescr = text.substr(text.indexOf(' ') + 1);
- return heroEle.click();
- }).then(function() {
- expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
- return viewDetailsButtonEle.click();
- }).then(function() {
- return editDetails(page, heroDescr, '-bar');
- }).then(function() {
- expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back');
- expect(heroEle.getText()).toContain(heroDescr + '-bar');
- expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present');
- });
- });
-
- function editDetails(page: any, origValue: string, textToAdd: string) {
- expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
- expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present');
- expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details');
- let inputEle = page.heroDetail.element(by.css('input'));
- expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
- let buttons = page.heroDetail.all(by.css('button'));
- let backButtonEle = buttons.get(0);
- let saveButtonEle = buttons.get(1);
- expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
- expect(saveButtonEle.isDisplayed()).toBe(true, 'should be able to see the save button');
- let detailTextEle = page.heroDetail.element(by.css('div h2'));
- expect(detailTextEle.getText()).toContain(origValue);
- return sendKeys(inputEle, textToAdd).then(function () {
- expect(detailTextEle.getText()).toContain(origValue + textToAdd);
- return saveButtonEle.click();
- });
+ let hero = await Hero.fromDetail(getPageElts().heroDetail);
+ expect(hero).toEqual({id: targetHero.id, name: newHeroName});
}
});
+
+function addToHeroName(text: string): WPromise {
+ let input = element(by.css('input'));
+ return sendKeys(input, text);
+}
+
+function expectHeading(hLevel: number, expectedText: string): void {
+ let hTag = `h${hLevel}`;
+ let hText = element(by.css(hTag)).getText();
+ expect(hText).toEqual(expectedText, hTag);
+};
+
+function getHeroLiEltById(id: number): protractor.ElementFinder {
+ let spanForId = element(by.cssContainingText('li span.badge', id.toString()));
+ return spanForId.element(by.xpath('..'));
+}
+
+async function toHeroArray(allHeroes: protractor.ElementArrayFinder): Promise {
+ let promisedHeroes: Array> = await allHeroes.map(Hero.fromLi);
+ // The cast is necessary to get around issuing with the signature of Promise.all()
+ return > Promise.all(promisedHeroes);
+}
diff --git a/public/docs/_examples/toh-6/ts/app/app.component.ts b/public/docs/_examples/toh-6/ts/app/app.component.ts
index 16d6396184..e55e09f661 100644
--- a/public/docs/_examples/toh-6/ts/app/app.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/app.component.ts
@@ -2,10 +2,6 @@
// #docregion
import { Component } from '@angular/core';
-// #docregion rxjs-extensions
-import './rxjs-extensions';
-// #enddocregion rxjs-extensions
-
@Component({
selector: 'my-app',
diff --git a/public/docs/_examples/toh-6/ts/app/app.module.1.ts b/public/docs/_examples/toh-6/ts/app/app.module.1.ts
deleted file mode 100644
index 6924d5a390..0000000000
--- a/public/docs/_examples/toh-6/ts/app/app.module.1.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-// #docplaster
-// #docregion
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from '@angular/forms';
-
-// Imports for loading & configuring the in-memory web api
-import { HttpModule, XHRBackend } from '@angular/http';
-
-import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
-import { InMemoryDataService } from './in-memory-data.service';
-
-import { AppComponent } from './app.component';
-import { routing } from './app.routing';
-
-import { HeroesComponent } from './heroes.component';
-import { DashboardComponent } from './dashboard.component';
-import { HeroDetailComponent } from './hero-detail.component';
-
-import { HeroService } from './hero.service';
-
-@NgModule({
- imports: [
- BrowserModule,
- FormsModule,
- routing,
- HttpModule
- ],
- declarations: [
- AppComponent,
- HeroesComponent,
- DashboardComponent,
- HeroDetailComponent
- ],
- providers: [
- HeroService,
- { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
- { provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data
- ],
- bootstrap: [ AppComponent ]
-})
-export class AppModule {
-}
-// #enddocregion final
diff --git a/public/docs/_examples/toh-6/ts/app/app.module.2.ts b/public/docs/_examples/toh-6/ts/app/app.module.2.ts
deleted file mode 100644
index 2ec598cd0b..0000000000
--- a/public/docs/_examples/toh-6/ts/app/app.module.2.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-// #docplaster
-// #docregion
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from '@angular/forms';
-import { HttpModule } from '@angular/http';
-
-import { AppComponent } from './app.component';
-import { routing } from './app.routing';
-
-import { HeroesComponent } from './heroes.component';
-import { DashboardComponent } from './dashboard.component';
-import { HeroDetailComponent } from './hero-detail.component';
-// #docregion hero-search-declaration
-import { HeroSearchComponent } from './hero-search.component';
-// #enddocregion hero-search-declaration
-
-import { HeroService } from './hero.service';
-
-@NgModule({
- imports: [
- BrowserModule,
- FormsModule,
- routing,
- HttpModule
- ],
-// #docregion hero-search-declaration
-
- declarations: [
- AppComponent,
- HeroesComponent,
- DashboardComponent,
- HeroDetailComponent,
- HeroSearchComponent
- ],
-// #enddocregion hero-search-declaration
- providers: [
- HeroService
- ],
- bootstrap: [ AppComponent ]
-})
-export class AppModule {
-}
-// #enddocregion
diff --git a/public/docs/_examples/toh-6/ts/app/app.module.ts b/public/docs/_examples/toh-6/ts/app/app.module.ts
index 0beff178e0..7c497b8f14 100644
--- a/public/docs/_examples/toh-6/ts/app/app.module.ts
+++ b/public/docs/_examples/toh-6/ts/app/app.module.ts
@@ -1,45 +1,58 @@
+// #docplaster
// #docregion
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from '@angular/forms';
+// #docregion rxjs-extensions
+import './rxjs-extensions';
+// #enddocregion rxjs-extensions
+// #docregion v1, v2
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { FormsModule } from '@angular/forms';
+import { HttpModule } from '@angular/http';
+
+// #enddocregion v1
// Imports for loading & configuring the in-memory web api
-import { HttpModule, XHRBackend } from '@angular/http';
+import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
+import { InMemoryDataService } from './in-memory-data.service';
-import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
-import { InMemoryDataService } from './in-memory-data.service';
-
-import { AppComponent } from './app.component';
-import { routing } from './app.routing';
-
-import { HeroesComponent } from './heroes.component';
+// #docregion v1
+import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard.component';
+import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
+import { HeroService } from './hero.service';
+// #enddocregion v1, v2
import { HeroSearchComponent } from './hero-search.component';
-
-import { HeroService } from './hero.service';
+// #docregion v1, v2
+import { routing } from './app.routing';
@NgModule({
imports: [
BrowserModule,
FormsModule,
- routing,
- HttpModule
+ HttpModule,
+ // #enddocregion v1
+ // #docregion in-mem-web-api
+ InMemoryWebApiModule.forRoot(InMemoryDataService),
+ // #enddocregion in-mem-web-api
+ // #docregion v1
+ routing
],
+ // #docregion search
declarations: [
AppComponent,
- HeroesComponent,
DashboardComponent,
HeroDetailComponent,
+ HeroesComponent,
+ // #enddocregion v1, v2
HeroSearchComponent
+ // #docregion v1, v2
],
+ // #enddocregion search
providers: [
HeroService,
- { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
- { provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
-// #enddocregion
diff --git a/public/docs/_examples/toh-6/ts/app/app.routing.ts b/public/docs/_examples/toh-6/ts/app/app.routing.ts
index c5753a4ee9..7acd3b9863 100644
--- a/public/docs/_examples/toh-6/ts/app/app.routing.ts
+++ b/public/docs/_examples/toh-6/ts/app/app.routing.ts
@@ -1,4 +1,5 @@
// #docregion
+import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
@@ -25,4 +26,4 @@ const appRoutes: Routes = [
}
];
-export const routing = RouterModule.forRoot(appRoutes);
+export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts b/public/docs/_examples/toh-6/ts/app/dashboard.component.ts
index 4a90a4d6bf..dd2e2ef2ce 100644
--- a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/dashboard.component.ts
@@ -19,12 +19,12 @@ export class DashboardComponent implements OnInit {
private heroService: HeroService) {
}
- ngOnInit() {
+ ngOnInit(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
- gotoDetail(hero: Hero) {
+ gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.html b/public/docs/_examples/toh-6/ts/app/hero-detail.component.html
index 38af5f707e..32fe6d4391 100644
--- a/public/docs/_examples/toh-6/ts/app/hero-detail.component.html
+++ b/public/docs/_examples/toh-6/ts/app/hero-detail.component.html
@@ -1,4 +1,3 @@
-
{{hero.name}} details!
diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts
index 062917401e..87333a9fe3 100644
--- a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts
@@ -1,8 +1,5 @@
-// #docplaster
-// #docregion, variables-imports
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-
-// #enddocregion variables-imports
+// #docregion
+import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Hero } from './hero';
@@ -13,50 +10,30 @@ import { HeroService } from './hero.service';
templateUrl: 'app/hero-detail.component.html',
styleUrls: ['app/hero-detail.component.css']
})
-// #docregion variables-imports
export class HeroDetailComponent implements OnInit {
- @Input() hero: Hero;
- @Output() close = new EventEmitter();
- error: any;
- navigated = false; // true if navigated here
- // #enddocregion variables-imports
+ hero: Hero;
constructor(
private heroService: HeroService,
private route: ActivatedRoute) {
}
- // #docregion ngOnInit
- ngOnInit() {
+ ngOnInit(): void {
this.route.params.forEach((params: Params) => {
- if (params['id'] !== undefined) {
- let id = +params['id'];
- this.navigated = true;
- this.heroService.getHero(id)
- .then(hero => this.hero = hero);
- } else {
- this.navigated = false;
- this.hero = new Hero();
- }
+ let id = +params['id'];
+ this.heroService.getHero(id)
+ .then(hero => this.hero = hero);
});
}
- // #enddocregion ngOnInit
// #docregion save
- save() {
- this.heroService
- .save(this.hero)
- .then(hero => {
- this.hero = hero; // saved hero, w/ id if new
- this.goBack(hero);
- })
- .catch(error => this.error = error); // TODO: Display error message
+ save(): void {
+ this.heroService.update(this.hero)
+ .then(this.goBack);
}
// #enddocregion save
- // #docregion goBack
- goBack(savedHero: Hero = null) {
- this.close.emit(savedHero);
- if (this.navigated) { window.history.back(); }
+
+ goBack(): void {
+ window.history.back();
}
- // #enddocregion goBack
}
diff --git a/public/docs/_examples/toh-6/ts/app/hero-search.component.ts b/public/docs/_examples/toh-6/ts/app/hero-search.component.ts
index 25ada285ac..384002098d 100644
--- a/public/docs/_examples/toh-6/ts/app/hero-search.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/hero-search.component.ts
@@ -28,11 +28,13 @@ export class HeroSearchComponent implements OnInit {
// #docregion searchTerms
// Push a search term into the observable stream.
- search(term: string) { this.searchTerms.next(term); }
+ search(term: string): void {
+ this.searchTerms.next(term);
+ }
// #enddocregion searchTerms
// #docregion search
- ngOnInit() {
+ ngOnInit(): void {
this.heroes = this.searchTerms
.debounceTime(300) // wait for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
@@ -49,7 +51,7 @@ export class HeroSearchComponent implements OnInit {
}
// #enddocregion search
- gotoDetail(hero: Hero) {
+ gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
diff --git a/public/docs/_examples/toh-6/ts/app/hero-search.service.ts b/public/docs/_examples/toh-6/ts/app/hero-search.service.ts
index 95a31707eb..ae2e47670a 100644
--- a/public/docs/_examples/toh-6/ts/app/hero-search.service.ts
+++ b/public/docs/_examples/toh-6/ts/app/hero-search.service.ts
@@ -1,6 +1,7 @@
// #docregion
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
+import { Observable } from 'rxjs';
import { Hero } from './hero';
@@ -9,7 +10,7 @@ export class HeroSearchService {
constructor(private http: Http) {}
- search(term: string) {
+ search(term: string): Observable
{
return this.http
.get(`app/heroes/?name=${term}`)
.map((r: Response) => r.json().data as Hero[]);
diff --git a/public/docs/_examples/toh-6/ts/app/hero.service.ts b/public/docs/_examples/toh-6/ts/app/hero.service.ts
index 04012768be..e220982f6f 100644
--- a/public/docs/_examples/toh-6/ts/app/hero.service.ts
+++ b/public/docs/_examples/toh-6/ts/app/hero.service.ts
@@ -1,5 +1,5 @@
// #docplaster
-// #docregion
+// #docregion , imports
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
@@ -8,16 +8,20 @@ import 'rxjs/add/operator/toPromise';
// #enddocregion rxjs
import { Hero } from './hero';
+// #enddocregion imports
@Injectable()
export class HeroService {
+ // #docregion update
+ private headers = new Headers({'Content-Type': 'application/json'});
+ // #enddocregion update
// #docregion getHeroes
private heroesUrl = 'app/heroes'; // URL to web api
constructor(private http: Http) { }
- getHeroes() {
+ getHeroes(): Promise {
return this.http.get(this.heroesUrl)
// #docregion to-promise
.toPromise()
@@ -31,67 +35,45 @@ export class HeroService {
}
// #enddocregion getHeroes
- getHero(id: number) {
+ getHero(id: number): Promise {
return this.getHeroes()
.then(heroes => heroes.find(hero => hero.id === id));
}
- // #docregion save
- save(hero: Hero): Promise {
- if (hero.id) {
- return this.put(hero);
- }
- return this.post(hero);
- }
- // #enddocregion save
-
// #docregion delete
- delete(hero: Hero) {
- let headers = new Headers();
- headers.append('Content-Type', 'application/json');
-
- let url = `${this.heroesUrl}/${hero.id}`;
-
- return this.http
- .delete(url, {headers: headers})
- .toPromise()
- .catch(this.handleError);
+ delete(id: number): Promise {
+ let url = `${this.heroesUrl}/${id}`;
+ return this.http.delete(url, {headers: this.headers})
+ .toPromise()
+ .then(() => null)
+ .catch(this.handleError);
}
// #enddocregion delete
- // #docregion post
- // Add new Hero
- private post(hero: Hero): Promise {
- let headers = new Headers({
- 'Content-Type': 'application/json'});
-
+ // #docregion create
+ create(name: string): Promise {
return this.http
- .post(this.heroesUrl, JSON.stringify(hero), {headers: headers})
- .toPromise()
- .then(res => res.json().data)
- .catch(this.handleError);
+ .post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers})
+ .toPromise()
+ .then(res => res.json().data)
+ .catch(this.handleError);
}
- // #enddocregion post
-
- // #docregion put
- // Update existing Hero
- private put(hero: Hero) {
- let headers = new Headers();
- headers.append('Content-Type', 'application/json');
-
- let url = `${this.heroesUrl}/${hero.id}`;
+ // #enddocregion create
+ // #docregion update
+ update(hero: Hero): Promise {
+ const url = `${this.heroesUrl}/${hero.id}`;
return this.http
- .put(url, JSON.stringify(hero), {headers: headers})
- .toPromise()
- .then(() => hero)
- .catch(this.handleError);
+ .put(url, JSON.stringify(hero), {headers: this.headers})
+ .toPromise()
+ .then(() => hero)
+ .catch(this.handleError);
}
- // #enddocregion put
+ // #enddocregion put, update
// #docregion handleError
- private handleError(error: any) {
- console.error('An error occurred', error);
+ private handleError(error: any): Promise {
+ console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
// #enddocregion handleError
diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.css b/public/docs/_examples/toh-6/ts/app/heroes.component.css
index 75969e0b3a..d2c958a911 100644
--- a/public/docs/_examples/toh-6/ts/app/heroes.component.css
+++ b/public/docs/_examples/toh-6/ts/app/heroes.component.css
@@ -59,9 +59,10 @@ button:hover {
background-color: #cfd8dc;
}
/* #docregion additions */
-.error {color:red;}
-button.delete-button{
+button.delete {
float:right;
+ margin-top: 2px;
+ margin-right: .8em;
background-color: gray !important;
color:white;
}
diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.html b/public/docs/_examples/toh-6/ts/app/heroes.component.html
index 05afc9ea2f..392d241d52 100644
--- a/public/docs/_examples/toh-6/ts/app/heroes.component.html
+++ b/public/docs/_examples/toh-6/ts/app/heroes.component.html
@@ -1,24 +1,26 @@
My Heroes
-
-
-
- {{hero.id}} {{hero.name}}
-
-
- Delete
-
-
-
-
-
-{{error}}
-Add New Hero
-
-
+
+
+ Hero name:
+
+ Add
+
-
-
+
+
+
+
+ {{hero.id}}
+ {{hero.name}}
+
+ x
+
+
+
+
{{selectedHero.name | uppercase}} is my hero
diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.ts b/public/docs/_examples/toh-6/ts/app/heroes.component.ts
index e5c5ab1c49..6c0e8f2306 100644
--- a/public/docs/_examples/toh-6/ts/app/heroes.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/heroes.component.ts
@@ -4,68 +4,58 @@ import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
-// #docregion hero-detail-component
@Component({
selector: 'my-heroes',
templateUrl: 'app/heroes.component.html',
styleUrls: ['app/heroes.component.css']
})
-// #enddocregion hero-detail-component
export class HeroesComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
- addingHero = false;
- // #docregion error
- error: any;
- // #enddocregion error
constructor(
- private router: Router,
- private heroService: HeroService) { }
+ private heroService: HeroService,
+ private router: Router) { }
- getHeroes() {
+ getHeroes(): void {
this.heroService
.getHeroes()
- .then(heroes => this.heroes = heroes)
- .catch(error => this.error = error);
+ .then(heroes => this.heroes = heroes);
}
- // #docregion addHero
- addHero() {
- this.addingHero = true;
- this.selectedHero = null;
+ // #docregion add
+ add(name: string): void {
+ name = name.trim();
+ if (!name) { return; }
+ this.heroService.create(name)
+ .then(hero => {
+ this.heroes.push(hero);
+ this.selectedHero = null;
+ });
}
+ // #enddocregion add
- close(savedHero: Hero) {
- this.addingHero = false;
- if (savedHero) { this.getHeroes(); }
- }
- // #enddocregion addHero
-
- // #docregion deleteHero
- deleteHero(hero: Hero, event: any) {
- event.stopPropagation();
+ // #docregion delete
+ delete(hero: Hero): void {
this.heroService
- .delete(hero)
- .then(res => {
+ .delete(hero.id)
+ .then(() => {
this.heroes = this.heroes.filter(h => h !== hero);
if (this.selectedHero === hero) { this.selectedHero = null; }
- })
- .catch(error => this.error = error);
+ });
}
- // #enddocregion deleteHero
+ // #enddocregion delete
- ngOnInit() {
+ ngOnInit(): void {
this.getHeroes();
}
- onSelect(hero: Hero) {
+ onSelect(hero: Hero): void {
this.selectedHero = hero;
- this.addingHero = false;
}
- gotoDetail() {
+ gotoDetail(): void {
this.router.navigate(['/detail', this.selectedHero.id]);
}
}
diff --git a/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts b/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts
index 261795a641..c63151a122 100644
--- a/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts
+++ b/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts
@@ -1,5 +1,6 @@
// #docregion , init
-export class InMemoryDataService {
+import { InMemoryDbService } from 'angular2-in-memory-web-api';
+export class InMemoryDataService implements InMemoryDbService {
createDb() {
let heroes = [
{id: 11, name: 'Mr. Nice'},
diff --git a/public/docs/_examples/toh-6/ts/index.html b/public/docs/_examples/toh-6/ts/index.html
index 8bbbc6123d..41faa36c28 100644
--- a/public/docs/_examples/toh-6/ts/index.html
+++ b/public/docs/_examples/toh-6/ts/index.html
@@ -2,7 +2,7 @@
- Angular 2 Tour of Heroes
+ Angular Tour of Heroes
diff --git a/public/docs/_examples/typings.json b/public/docs/_examples/typings.json
index 3d826df25a..7da31ca0af 100644
--- a/public/docs/_examples/typings.json
+++ b/public/docs/_examples/typings.json
@@ -1,7 +1,7 @@
{
"globalDependencies": {
- "core-js": "registry:dt/core-js#0.0.0+20160602141332",
+ "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+20160807145350"
+ "node": "registry:dt/node#6.0.0+20160909174046"
}
}
diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js
index bf17063954..31589119d2 100644
--- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js
+++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js
@@ -29,22 +29,18 @@ System.config({
});
System.import('systemjs.config.js')
- .then(function () {
- return Promise.all([
+ .then(() => Promise.all([
System.import('@angular/core/testing'),
System.import('@angular/platform-browser-dynamic/testing')
- ])
+ ]))
+ .then((providers) => {
+ var coreTesting = providers[0];
+ var browserTesting = providers[1];
+ coreTesting.TestBed.initTestEnvironment(
+ browserTesting.BrowserDynamicTestingModule,
+ browserTesting.platformBrowserDynamicTesting());
})
- .then(function (providers) {
- var testing = providers[0];
- var testingBrowser = providers[1];
-
- testing.setBaseTestProviders(
- testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
- testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
-
- })
- .then(function() {
+ .then(function () {
// Finally, load all spec files.
// This will run the tests directly.
return Promise.all(
diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js
index 7156e025ce..48cc490f89 100644
--- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js
+++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js
@@ -19,10 +19,13 @@ module.exports = function(config) {
// Polyfills
'node_modules/core-js/client/shim.js',
-
- // Reflect and Zone.js
'node_modules/reflect-metadata/Reflect.js',
+
+ // zone.js
'node_modules/zone.js/dist/zone.js',
+ 'node_modules/zone.js/dist/long-stack-trace-zone.js',
+ 'node_modules/zone.js/dist/proxy.js',
+ 'node_modules/zone.js/dist/sync-test.js',
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts
similarity index 100%
rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts.disabled
rename to public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts
diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js b/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js
index 7156e025ce..48cc490f89 100644
--- a/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js
+++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js
@@ -19,10 +19,13 @@ module.exports = function(config) {
// Polyfills
'node_modules/core-js/client/shim.js',
-
- // Reflect and Zone.js
'node_modules/reflect-metadata/Reflect.js',
+
+ // zone.js
'node_modules/zone.js/dist/zone.js',
+ 'node_modules/zone.js/dist/long-stack-trace-zone.js',
+ 'node_modules/zone.js/dist/proxy.js',
+ 'node_modules/zone.js/dist/sync-test.js',
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
diff --git a/public/docs/_examples/user-input/dart/pubspec.yaml b/public/docs/_examples/user-input/dart/pubspec.yaml
index fa28056488..a75460f74f 100644
--- a/public/docs/_examples/user-input/dart/pubspec.yaml
+++ b/public/docs/_examples/user-input/dart/pubspec.yaml
@@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
- angular2: 2.0.0-beta.18
+ angular2: 2.0.0-beta.21
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
diff --git a/public/docs/_examples/wallaby.js b/public/docs/_examples/wallaby.js
deleted file mode 100644
index 28053a11fe..0000000000
--- a/public/docs/_examples/wallaby.js
+++ /dev/null
@@ -1,77 +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},
-
- // Polyfills
- {pattern: 'node_modules/core-js/client/shim.min.js', instrument: false},
-
- // Reflect, Zone.js, and test shims
- // Rx.js, Angular 2 itself, and the testing library not here because loaded by systemjs
- {pattern: 'node_modules/reflect-metadata/Reflect.js', instrument: false},
- {pattern: 'node_modules/zone.js/dist/zone.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},
-
- {pattern: 'app/**/*+(ts|html|css)', load: false},
- {pattern: 'app/**/*.spec.ts', ignore: true}
- ],
-
- 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: function (wallaby) {
- wallaby.delayStart();
-
- System.config({
- packageWithIndex: true // sadly, we can't use umd packages (yet?)
- });
-
- System.import('systemjs.config.js')
- .then(function () {
- return Promise.all([
- System.import('@angular/core/testing'),
- System.import('@angular/platform-browser-dynamic/testing')
- ])
- })
- .then(function (providers) {
- var testing = providers[0];
- var testingBrowser = providers[1];
-
- testing.setBaseTestProviders(
- testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
- testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
-
- // Load all spec files
- return Promise.all(wallaby.tests.map(function (specFile) {
- return System.import(specFile);
- }));
- })
- .then(function () {
- wallaby.start();
- })
- .catch(function (e) {
- setTimeout(function () {
- throw e;
- }, 0);
- });
- }
- };
-};
diff --git a/public/docs/_examples/webpack/e2e-spec.ts.disabled b/public/docs/_examples/webpack/e2e-spec.ts
similarity index 87%
rename from public/docs/_examples/webpack/e2e-spec.ts.disabled
rename to public/docs/_examples/webpack/e2e-spec.ts
index 59bf5c5708..1e88bfccf1 100644
--- a/public/docs/_examples/webpack/e2e-spec.ts.disabled
+++ b/public/docs/_examples/webpack/e2e-spec.ts
@@ -2,7 +2,7 @@
'use strict';
describe('QuickStart E2E Tests', function () {
- let expectedMsg = 'Hello from Angular 2 App with Webpack';
+ let expectedMsg = 'Hello from Angular App with Webpack';
beforeEach(function () {
browser.get('');
diff --git a/public/docs/_examples/webpack/ts/config/karma-test-shim.js b/public/docs/_examples/webpack/ts/config/karma-test-shim.js
index 27fa731f5a..2ea37fbd72 100644
--- a/public/docs/_examples/webpack/ts/config/karma-test-shim.js
+++ b/public/docs/_examples/webpack/ts/config/karma-test-shim.js
@@ -2,10 +2,12 @@
Error.stackTraceLimit = Infinity;
require('core-js/es6');
-require('reflect-metadata');
+require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
+require('zone.js/dist/proxy');
+require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
@@ -17,7 +19,4 @@ appContext.keys().forEach(appContext);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
-testing.setBaseTestProviders(
- browser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
- browser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS
-);
+testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
diff --git a/public/docs/_examples/webpack/ts/config/webpack.common.js b/public/docs/_examples/webpack/ts/config/webpack.common.js
index 5de5af96d2..b707349719 100644
--- a/public/docs/_examples/webpack/ts/config/webpack.common.js
+++ b/public/docs/_examples/webpack/ts/config/webpack.common.js
@@ -24,7 +24,7 @@ module.exports = {
loaders: [
{
test: /\.ts$/,
- loaders: ['ts', 'angular2-template-loader']
+ loaders: ['awesome-typescript-loader', 'angular2-template-loader']
},
{
test: /\.html$/,
diff --git a/public/docs/_examples/webpack/ts/config/webpack.prod.js b/public/docs/_examples/webpack/ts/config/webpack.prod.js
index 0e897cb35a..7b2f8f9800 100644
--- a/public/docs/_examples/webpack/ts/config/webpack.prod.js
+++ b/public/docs/_examples/webpack/ts/config/webpack.prod.js
@@ -24,7 +24,11 @@ module.exports = webpackMerge(commonConfig, {
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
- new webpack.optimize.UglifyJsPlugin(),
+ new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
+ mangle: {
+ keep_fnames: true
+ }
+ }),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
diff --git a/public/docs/_examples/webpack/ts/config/webpack.test.js b/public/docs/_examples/webpack/ts/config/webpack.test.js
index 352e4f6126..c3f8727e70 100644
--- a/public/docs/_examples/webpack/ts/config/webpack.test.js
+++ b/public/docs/_examples/webpack/ts/config/webpack.test.js
@@ -1,4 +1,6 @@
// #docregion
+var helpers = require('./helpers');
+
module.exports = {
devtool: 'inline-source-map',
@@ -10,7 +12,7 @@ module.exports = {
loaders: [
{
test: /\.ts$/,
- loaders: ['ts', 'angular2-template-loader']
+ loaders: ['awesome-typescript-loader', 'angular2-template-loader']
},
{
test: /\.html$/,
@@ -23,7 +25,13 @@ module.exports = {
},
{
test: /\.css$/,
+ exclude: helpers.root('src', 'app'),
loader: 'null'
+ },
+ {
+ test: /\.css$/,
+ include: helpers.root('src', 'app'),
+ loader: 'raw'
}
]
}
diff --git a/public/docs/_examples/webpack/ts/package.webpack.json b/public/docs/_examples/webpack/ts/package.webpack.json
index 4b3dc3e15d..3995e724db 100644
--- a/public/docs/_examples/webpack/ts/package.webpack.json
+++ b/public/docs/_examples/webpack/ts/package.webpack.json
@@ -1,7 +1,7 @@
{
"name": "angular2-webpack",
"version": "1.0.0",
- "description": "A webpack starter for angular 2",
+ "description": "A webpack starter for Angular",
"scripts": {
"start": "webpack-dev-server --inline --progress --port 8080",
"test": "karma start",
@@ -10,40 +10,39 @@
},
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.5",
- "@angular/compiler": "2.0.0-rc.5",
- "@angular/core": "2.0.0-rc.5",
- "@angular/forms": "0.3.0",
- "@angular/http": "2.0.0-rc.5",
- "@angular/platform-browser": "2.0.0-rc.5",
- "@angular/platform-browser-dynamic": "2.0.0-rc.5",
- "@angular/router": "3.0.0-rc.1",
- "core-js": "^2.4.0",
- "reflect-metadata": "0.1.2",
- "rxjs": "5.0.0-beta.6",
- "zone.js": "0.6.12"
+ "@angular/common": "2.0.0",
+ "@angular/compiler": "2.0.0",
+ "@angular/core": "2.0.0",
+ "@angular/forms": "2.0.0",
+ "@angular/http": "2.0.0",
+ "@angular/platform-browser": "2.0.0",
+ "@angular/platform-browser-dynamic": "2.0.0",
+ "@angular/router": "3.0.0",
+ "core-js": "^2.4.1",
+ "rxjs": "5.0.0-beta.12",
+ "zone.js": "^0.6.23"
},
"devDependencies": {
"angular2-template-loader": "^0.4.0",
+ "awesome-typescript-loader": "^2.2.4",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"html-loader": "^0.4.3",
"html-webpack-plugin": "^2.15.0",
"jasmine-core": "^2.4.1",
- "karma": "^0.13.22",
- "karma-jasmine": "^0.3.8",
- "karma-phantomjs-launcher": "^1.0.0",
+ "karma": "^1.2.0",
+ "karma-jasmine": "^1.0.2",
+ "karma-phantomjs-launcher": "^1.0.2",
"karma-sourcemap-loader": "^0.3.7",
- "karma-webpack": "^1.7.0",
+ "karma-webpack": "^1.8.0",
"null-loader": "^0.1.1",
"phantomjs-prebuilt": "^2.1.7",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
"style-loader": "^0.13.1",
- "ts-loader": "^0.8.1",
- "typescript": "^1.8.10",
- "typings": "^1.0.4",
+ "typescript": "^2.0.2",
+ "typings": "^1.3.2",
"webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1",
"webpack-merge": "^0.14.0"
diff --git a/public/docs/_examples/webpack/ts/public/images/angular.png b/public/docs/_examples/webpack/ts/public/images/angular.png
index a1d9790bc3..c510293918 100644
Binary files a/public/docs/_examples/webpack/ts/public/images/angular.png and b/public/docs/_examples/webpack/ts/public/images/angular.png differ
diff --git a/public/docs/_examples/webpack/ts/src/app/app.component.html b/public/docs/_examples/webpack/ts/src/app/app.component.html
index a333a7a72f..b06ff16d11 100644
--- a/public/docs/_examples/webpack/ts/src/app/app.component.html
+++ b/public/docs/_examples/webpack/ts/src/app/app.component.html
@@ -1,6 +1,6 @@
- Hello from Angular 2 App with Webpack
+ Hello from Angular App with Webpack
diff --git a/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts b/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts
index d7d0696aef..a6512a11e7 100644
--- a/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts
+++ b/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts
@@ -1,21 +1,16 @@
// #docregion
-import {
- addProviders,
- inject,
-} from '@angular/core/testing';
+import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('App', () => {
beforeEach(() => {
- addProviders([
- AppComponent
- ]);
+ TestBed.configureTestingModule({ declarations: [AppComponent]});
});
- it ('should work', inject([AppComponent], (app: AppComponent) => {
- // Add real test here
- expect(2).toBe(2);
- }));
+ it ('should work', () => {
+ let fixture = TestBed.createComponent(AppComponent);
+ expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent');
+ });
});
// #enddocregion
diff --git a/public/docs/_examples/webpack/ts/src/main.ts b/public/docs/_examples/webpack/ts/src/main.ts
index 0057db95ab..e1d8cbc0fe 100644
--- a/public/docs/_examples/webpack/ts/src/main.ts
+++ b/public/docs/_examples/webpack/ts/src/main.ts
@@ -1,5 +1,5 @@
// #docregion
-import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app/app.module';
@@ -10,5 +10,5 @@ if (process.env.ENV === 'production') {
}
// #enddocregion enable-prod
-browserDynamicPlatform().bootstrapModule(AppModule);
+platformBrowserDynamic().bootstrapModule(AppModule);
// #enddocregion
diff --git a/public/docs/_examples/webpack/ts/src/vendor.ts b/public/docs/_examples/webpack/ts/src/vendor.ts
index ede1e2717d..8ffd09240a 100644
--- a/public/docs/_examples/webpack/ts/src/vendor.ts
+++ b/public/docs/_examples/webpack/ts/src/vendor.ts
@@ -1,5 +1,5 @@
// #docregion
-// Angular 2
+// Angular
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
diff --git a/public/docs/_examples/webpack/ts/typings.1.json b/public/docs/_examples/webpack/ts/typings.1.json
index 3d826df25a..7da31ca0af 100644
--- a/public/docs/_examples/webpack/ts/typings.1.json
+++ b/public/docs/_examples/webpack/ts/typings.1.json
@@ -1,7 +1,7 @@
{
"globalDependencies": {
- "core-js": "registry:dt/core-js#0.0.0+20160602141332",
+ "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+20160807145350"
+ "node": "registry:dt/node#6.0.0+20160909174046"
}
}
diff --git a/public/docs/_includes/_side-nav.jade b/public/docs/_includes/_side-nav.jade
index d1b8bbb5f7..f34ad29074 100644
--- a/public/docs/_includes/_side-nav.jade
+++ b/public/docs/_includes/_side-nav.jade
@@ -40,53 +40,71 @@
- var reference = sections('', function(item) { return item.reference; });
- var anyItemSelected = function(items) {
- var selectedCount = items.filter(function(item) { return !!item.class; }).length;
-- return selectedCount > 0 ? 'is-nav-title-selected' : '';
+- return selectedCount > 0 ? 'is-selected' : '';
- }
- var isQuickstartSelected = function() {
- var splitted = cur.split('/');
- var bit = splitted[splitted.length - 1].replace('.html', '');
-- return bit === 'quickstart' ? 'is-nav-title-selected' : '';
+- return bit === 'quickstart' ? 'is-selected' : '';
-}
- var isApiReferenceSelected = function() {
- var splitted = cur.split('/');
- var bit = splitted[splitted.length - 2];
-- return bit === 'api' ? 'is-nav-title-selected' : '';
+- return bit === 'api' ? 'is-selected' : '';
-}
- var isCollapsed = function(titleStyle) {
-- return titleStyle === 'is-nav-title-selected' ? '' : 'is-hidden';
+- return titleStyle === 'is-selected' ? '' : 'is-hidden';
- }
-nav.side-nav.l-pinned-left.l-layer-4.l-offset-nav
+- var language = current.path[1] || 'ts'
+- if (language !== 'ts' || language !== 'js' || language !== 'dart') { language = 'ts'; }
+
+
+nav(class="sidenav l-pinned-left l-layer-4 l-offset-nav" ng-class="appCtrl.showDocsNav ? 'is-visible' : ''")
// SEARCH BAR
- header.side-nav-search.st-input-wrapper
+ header.sidenav-search.st-input-wrapper
form.st-input-inner
label(for="search-io" class="is-hidden") Search Docs
input(type="search" id="search-io" placeholder="SEARCH DOCS...")
button(class="mobile-trigger button" aria-label="View Docs Menu" ng-click="appCtrl.toggleDocsMenu($event)" md-button) Docs
- div(class="side-nav-secondary" ng-class="appCtrl.showDocsNav ? 'is-visible' : ''")
- .nav-blocks
+ ul(class="sidenav-links")
+ li.sidenav-section.no-border
+ a(class="nav-title" href="/docs/#{current.path[1]}/latest/") Docs Home
+
+ // CORE DOCUMENTATION
+ li.sidenav-section-divider
+ h3 Core Documentation
+
+ li.sidenav-section
a(class="nav-title #{isQuickstartSelected(cur)}" href="#{qs.href}" title="#{qs.tooltip}") Quickstart
- .nav-blocks
- a(class="nav-title #{anyItemSelected(tutorial)}" href="#{tutorial[0].href}" title="#{tutorial[0].tooltip}") Tutorial
- img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg")
- .nav-ordered-lists(class="#{isCollapsed(anyItemSelected(tutorial))}")
- ul
- each item, index in tutorial
- li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{index + 1}. #{item.navTitle}
- .nav-blocks
- a(class="nav-title #{anyItemSelected(basics)}" href="#{basics[0].href}" title="#{basics[0].tooltip}") Basics
+ li.sidenav-section
+ a(class="nav-title is-parent #{anyItemSelected(basics)}" href="#{basics[0].href}" title="#{basics[0].tooltip}") Guide
img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg")
.nav-ordered-lists(class="#{isCollapsed(anyItemSelected(basics))}")
ul
each item, index in basics
li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{index + 1}. #{item.navTitle}
+ li.sidenav-section.no-border
+ a(class="nav-title #{isApiReferenceSelected()}" href="#{reference[0].href}" title="#{reference[0].tooltip}") API Reference
- .nav-blocks
- a(class="nav-title #{anyItemSelected(guide)}" href="#{guide[0].href}" title="#{guide[0].tooltip}") Developer Guide
+ // ADVANCED DOCUMENATION
+ li.sidenav-section-divider
+ h3 Additional Documentation
+
+ li.sidenav-section
+ a(class="nav-title is-parent #{anyItemSelected(tutorial)}" href="#{tutorial[0].href}" title="#{tutorial[0].tooltip}") Tutorial
+ img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg")
+ .nav-ordered-lists(class="#{isCollapsed(anyItemSelected(tutorial))}")
+ ul
+ each item, index in tutorial
+ li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{index + 1}. #{item.navTitle}
+
+ li.sidenav-section
+ a(class="nav-title is-parent #{anyItemSelected(guide)}" href="#{guide[0].href}" title="#{guide[0].tooltip}") Advanced
img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg")
.nav-unordered-lists(class="#{isCollapsed(anyItemSelected(guide))}")
@@ -94,8 +112,8 @@ nav.side-nav.l-pinned-left.l-layer-4.l-offset-nav
each item in guide
li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{item.navTitle}
- .nav-blocks
- a(class="nav-title #{anyItemSelected(cookbook)}" href="#{cookbook[0].href}" title="#{cookbook[0].tooltip}") Cookbook
+ li.sidenav-section
+ a(class="nav-title is-parent #{anyItemSelected(cookbook)}" href="#{cookbook[0].href}" title="#{cookbook[0].tooltip}") Cookbook
img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg")
.nav-unordered-lists(class="#{isCollapsed(anyItemSelected(cookbook))}")
@@ -103,13 +121,17 @@ nav.side-nav.l-pinned-left.l-layer-4.l-offset-nav
each item in cookbook
li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{item.navTitle}
- .nav-blocks
- a(class="nav-title #{isApiReferenceSelected()}" href="#{reference[0].href}" title="#{reference[0].tooltip}") API Reference
+
+
+
+ if current.path[0] == "docs"
+ != partial("../../_includes/_version-dropdown")
+
script.
// Could put in appCtrl but only needed here and clear here
(function scrollToSelectedLink() {
- var sideNav = document.getElementsByClassName('side-nav')[0];
+ var sideNav = document.getElementsByClassName('sidenav')[0];
var link = sideNav.getElementsByClassName('is-selected')[0];
if(link && link.offsetTop > window.innerHeight){
sideNav.scrollTop = link.offsetTop - (window.innerHeight/2);
diff --git a/public/docs/_includes/_ts-temp.jade b/public/docs/_includes/_ts-temp.jade
index b4a6b8ad8a..7c162672f4 100644
--- a/public/docs/_includes/_ts-temp.jade
+++ b/public/docs/_includes/_ts-temp.jade
@@ -8,26 +8,9 @@ if language == 'js'
if language == 'ts'
- lang = 'TypeScript'
-- var page = ''
-if current.path[4]
- - var page = current.path[4] + '.html'
-
+- var page = current.path[4] ? current.path[4] + '.html' : ''
+- if (page === 'index.html') page = ''
- var path = '/docs/ts/latest/'+ current.path[3] + '/' + page
-
-- var name = 'it'
-- var secondaryPath = public.docs[current.path[1]][current.path[2]][current.path[3]]
-if secondaryPath
- - var data = secondaryPath._data
- - var listType = data._listtype
- - var items = listType == 'api' ? secondaryPath : data
-
- for item, slug in items
- if slug == current.path[4]
- - name = 'the ' + item.title + ' chapter'
-
-p.
- This chapter is not yet available in #{lang}.
- We recommend reading the TypeScript version.
-a(href=path, class='md-primary md-button md-ink-ripple').
- Read !{name} in TypeScript
-// != partial(path)
\ No newline at end of file
+:marked
+ This page is not yet available in #{lang}.
+ We recommend reading [it in TypeScript](!{path}).
\ No newline at end of file
diff --git a/public/docs/_includes/styleguide/_code-examples.jade b/public/docs/_includes/styleguide/_code-examples.jade
index 8291c74e59..0586577c79 100644
--- a/public/docs/_includes/styleguide/_code-examples.jade
+++ b/public/docs/_includes/styleguide/_code-examples.jade
@@ -116,7 +116,7 @@ include ../../../_includes/_util-fns
selector: 'my-app',
// #enddocregion component
// #docregion view
- template: 'My First Angular 2 App '
+ template: 'My First Angular App '
})
// #enddocregion view
// #docregion class
@@ -143,7 +143,7 @@ include ../../../_includes/_util-fns
// #enddocregion twoparts, import
@Component({
selector: 'my-app',
- template: 'My first Angular 2 App '
+ template: 'My first Angular App '
})
class AppComponent {
}
@@ -160,7 +160,6 @@ include ../../../_includes/_util-fns
code-example(format="linenums" language="html").
<!-- #docregion -->
...
- <script src="https://code.angularjs.org/2.0.0-beta.7/angular2.sfx.dev.js"></script>
<script src="app.js"></script>
...
@@ -285,9 +284,9 @@ include ../../../_includes/_util-fns
Styling selected portions of the json is also supported.
code-example(format="" language="js").
- +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]})
+ +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*zone.*)/, /(\Score-js.*)/, /(\Ssystem.*)/ ]})
- +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]})
+ +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*zone.*)/, /(\Score-js.*)/, /(\Ssystem.*)/ ]})
:marked
As well as styling across multiple lines.
@@ -422,7 +421,7 @@ include ../../../_includes/_util-fns
.alert.is-important.
The '@example' and '@exampleTabs' inline tags MUST always appear at the beginning of a line.
- Example files referenced by inline tags are all assumed to be in the 'modules/angular2' folder in the angular/angular repo.
+ Example files referenced by inline tags are all assumed to be in the 'modules/@angular' folder in the angular/angular repo.
:marked
#### @example inline tag parameters
diff --git a/public/docs/_layout.jade b/public/docs/_layout.jade
index 936c478fee..1baf14d66c 100644
--- a/public/docs/_layout.jade
+++ b/public/docs/_layout.jade
@@ -29,12 +29,9 @@ html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Frame
!= yield
else
article(class="l-content-small grid-fluid docs-content")
- div(class="c10")
- .showcase
- .showcase-content
- != yield
- if (current.path[3] == 'guide' || current.path[3] == 'tutorial') && current.path[4]
- != partial("../_includes/_next-item")
+ != yield
+ if (current.path[3] == 'guide' || current.path[3] == 'tutorial') && current.path[4]
+ != partial("../_includes/_next-item")
!= partial("../_includes/_footer")
!= partial("../_includes/_scripts-include")
\ No newline at end of file
diff --git a/public/docs/dart/latest/_data.json b/public/docs/dart/latest/_data.json
index a93259c9ab..c23053213e 100644
--- a/public/docs/dart/latest/_data.json
+++ b/public/docs/dart/latest/_data.json
@@ -2,67 +2,76 @@
"index": {
"icon": "home",
"title": "Angular Docs",
+ "subtitle": "Dart",
"menuTitle": "Docs Home",
- "banner": "Welcome to angular.io/dart ! The current Angular 2 Dart release is beta.18 . Consult the Change Log about recent enhancements, fixes, and breaking changes."
+ "banner": "Angular release is beta.21 . View the change log to see enhancements, fixes, and breaking changes."
},
"quickstart": {
"icon": "query-builder",
- "title": "5 Min Quickstart",
- "description": "Get up and running with Angular 2"
+ "title": "Quickstart",
+ "subtitle": "Dart",
+ "description": "Get up and running with Angular",
+ "banner": "This QuickStart guide demonstrates how to build and run a simple Angular application."
},
"tutorial": {
"icon": "list",
"title": "Tutorial",
- "banner": "Angular 2 is currently in Release Candidate."
+ "subtitle": "Dart"
},
"guide": {
"icon": "list",
"title": "Developer Guides",
- "banner": "Angular 2 is currently in Release Candidate."
+ "subtitle": "Dart"
},
"cookbook": {
"icon": "list",
"title": "Cookbook",
+ "subtitle": "Dart",
"banner": "How to solve common implementation challenges."
},
"api/": {
"icon": "book",
- "title": "API Preview",
+ "title": "API Reference",
+ "subtitle": "Dart",
"reference": true
},
"cheatsheet": {
"title": "Angular Cheat Sheet",
- "intro": "A quick guide to Angular syntax.",
+ "subtitle": "Dart",
+ "intro": "A quick guide to Angular syntax. (Content is provisional and may change.)",
"reference": false
},
"glossary": {
"title": "Glossary",
- "intro": "Brief definitions of the most important words in the Angular 2 vocabulary",
+ "subtitle": "Dart",
+ "intro": "Brief definitions of the most important words in the Angular vocabulary",
"reference": false
},
"resources": {
"icon": "play-circle-fill",
"title": "Angular Resources",
- "banner": "Angular 2 is currently in Release Candidate.",
+ "subtitle": "Dart",
"resources": true
},
"help": {
"icon": "chat",
"title": "Help & Support",
+ "subtitle": "From our team & community",
"resources": true
},
"styleguide": {
"title": "Docs Style Guide",
+ "subtitle": "Dart",
"intro": "Design & Layout Patterns For Documentation"
}
}
diff --git a/public/docs/dart/latest/_util-fns.jade b/public/docs/dart/latest/_util-fns.jade
index cc59d49fb5..e4839cc688 100644
--- a/public/docs/dart/latest/_util-fns.jade
+++ b/public/docs/dart/latest/_util-fns.jade
@@ -20,6 +20,15 @@ include ../../../_includes/_util-fns
- var _indexHtmlDir = 'web';
- var _mainDir = 'web';
+//- NgModule related
+- var _AppModuleVsAppComp = 'AppComponent'
+- var _appModuleTsVsAppCompTs = 'app/app_component.dart'
+- var _appModuleTsVsMainTs = 'web/main.dart'
+- var _bootstrapModule = 'bootstrap'
+- var _moduleVsComp = 'component'
+- var _moduleVsRootComp = 'root component'
+- var _platformBrowserDynamicVsBootStrap = 'bootstrap'
+
//- Deprecated
mixin liveExampleLink(linkText, exampleUrlPartName)
- var text = linkText || 'live example';
diff --git a/public/docs/dart/latest/cheatsheet.jade b/public/docs/dart/latest/cheatsheet.jade
index 77c0f11d36..eec36cfb3f 100644
--- a/public/docs/dart/latest/cheatsheet.jade
+++ b/public/docs/dart/latest/cheatsheet.jade
@@ -1,9 +1,4 @@
- var base = current.path[4] ? '.' : './guide';
-.banner.grid-fluid
- .alert.is-important
- :marked
- This cheat sheet is provisional and subject to change.
-article(class="l-content-small grid-fluid docs-content")
- .cheatsheet
- ngio-cheatsheet(src= base + '/cheatsheet.json')
+.l-content-small.grid-fluid.docs-content.cheatsheet
+ ngio-cheatsheet(src= base + '/cheatsheet.json')
diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json
index c7f07e9834..931857b846 100644
--- a/public/docs/dart/latest/cookbook/_data.json
+++ b/public/docs/dart/latest/cookbook/_data.json
@@ -12,6 +12,12 @@
"hide": true
},
+ "ngmodule-faq": {
+ "title": "Angular Module FAQs",
+ "intro": "Answers to frequently asked questions about @NgModule",
+ "hide": true
+ },
+
"component-communication": {
"title": "Component Interaction",
"intro": "Share information between different directives and components"
@@ -35,6 +41,12 @@
"hide": true
},
+ "form-validation": {
+ "title": "Form Validation",
+ "intro": "Validate user's form entries",
+ "hide": true
+ },
+
"rc4-to-rc5": {
"title": "RC4 to RC5 Migration",
"intro": "Migrate your RC4 app to RC5 in minutes.",
diff --git a/public/docs/dart/latest/cookbook/a1-a2-quick-reference.jade b/public/docs/dart/latest/cookbook/a1-a2-quick-reference.jade
index 6778b6af28..c743361ac8 100644
--- a/public/docs/dart/latest/cookbook/a1-a2-quick-reference.jade
+++ b/public/docs/dart/latest/cookbook/a1-a2-quick-reference.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/aot-compiler.jade b/public/docs/dart/latest/cookbook/aot-compiler.jade
new file mode 100644
index 0000000000..c743361ac8
--- /dev/null
+++ b/public/docs/dart/latest/cookbook/aot-compiler.jade
@@ -0,0 +1 @@
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/component-communication.jade b/public/docs/dart/latest/cookbook/component-communication.jade
index 6778b6af28..c743361ac8 100644
--- a/public/docs/dart/latest/cookbook/component-communication.jade
+++ b/public/docs/dart/latest/cookbook/component-communication.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/component-relative-paths.jade b/public/docs/dart/latest/cookbook/component-relative-paths.jade
index 6778b6af28..c743361ac8 100644
--- a/public/docs/dart/latest/cookbook/component-relative-paths.jade
+++ b/public/docs/dart/latest/cookbook/component-relative-paths.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/dependency-injection.jade b/public/docs/dart/latest/cookbook/dependency-injection.jade
index f8df2a84a6..4782ba81d3 100644
--- a/public/docs/dart/latest/cookbook/dependency-injection.jade
+++ b/public/docs/dart/latest/cookbook/dependency-injection.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
\ No newline at end of file
+include ../../../_includes/_ts-temp
\ No newline at end of file
diff --git a/public/docs/dart/latest/cookbook/dynamic-form-deprecated.jade b/public/docs/dart/latest/cookbook/dynamic-form-deprecated.jade
index f8df2a84a6..4782ba81d3 100644
--- a/public/docs/dart/latest/cookbook/dynamic-form-deprecated.jade
+++ b/public/docs/dart/latest/cookbook/dynamic-form-deprecated.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
\ No newline at end of file
+include ../../../_includes/_ts-temp
\ No newline at end of file
diff --git a/public/docs/dart/latest/cookbook/dynamic-form.jade b/public/docs/dart/latest/cookbook/dynamic-form.jade
index f8df2a84a6..c743361ac8 100644
--- a/public/docs/dart/latest/cookbook/dynamic-form.jade
+++ b/public/docs/dart/latest/cookbook/dynamic-form.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
\ No newline at end of file
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/form-validation.jade b/public/docs/dart/latest/cookbook/form-validation.jade
new file mode 100644
index 0000000000..c743361ac8
--- /dev/null
+++ b/public/docs/dart/latest/cookbook/form-validation.jade
@@ -0,0 +1 @@
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/index.jade b/public/docs/dart/latest/cookbook/index.jade
index 6778b6af28..c743361ac8 100644
--- a/public/docs/dart/latest/cookbook/index.jade
+++ b/public/docs/dart/latest/cookbook/index.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/ngmodule-faq.jade b/public/docs/dart/latest/cookbook/ngmodule-faq.jade
new file mode 100644
index 0000000000..c743361ac8
--- /dev/null
+++ b/public/docs/dart/latest/cookbook/ngmodule-faq.jade
@@ -0,0 +1 @@
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/rc4-to-rc5.jade b/public/docs/dart/latest/cookbook/rc4-to-rc5.jade
index 6778b6af28..c743361ac8 100644
--- a/public/docs/dart/latest/cookbook/rc4-to-rc5.jade
+++ b/public/docs/dart/latest/cookbook/rc4-to-rc5.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/set-document-title.jade b/public/docs/dart/latest/cookbook/set-document-title.jade
index f8df2a84a6..4782ba81d3 100644
--- a/public/docs/dart/latest/cookbook/set-document-title.jade
+++ b/public/docs/dart/latest/cookbook/set-document-title.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
\ No newline at end of file
+include ../../../_includes/_ts-temp
\ No newline at end of file
diff --git a/public/docs/dart/latest/cookbook/ts-to-js.jade b/public/docs/dart/latest/cookbook/ts-to-js.jade
index 6778b6af28..c743361ac8 100644
--- a/public/docs/dart/latest/cookbook/ts-to-js.jade
+++ b/public/docs/dart/latest/cookbook/ts-to-js.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/cookbook/visual-studio-2015.jade b/public/docs/dart/latest/cookbook/visual-studio-2015.jade
index f8df2a84a6..4782ba81d3 100644
--- a/public/docs/dart/latest/cookbook/visual-studio-2015.jade
+++ b/public/docs/dart/latest/cookbook/visual-studio-2015.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
\ No newline at end of file
+include ../../../_includes/_ts-temp
\ No newline at end of file
diff --git a/public/docs/dart/latest/glossary.jade b/public/docs/dart/latest/glossary.jade
index 673436c805..26feb4d9f3 100644
--- a/public/docs/dart/latest/glossary.jade
+++ b/public/docs/dart/latest/glossary.jade
@@ -1,35 +1,68 @@
-include _util-fns
+extends ../../ts/_cache/glossary.jade
-block var-def
- - var fragPath='../../ts/latest/_fragments/';
+block includes
+ include _util-fns
-!=partial(fragPath + 'glossary-intro')
-!=partial(fragPath + 'glossary-a1')
-!=partial(fragPath + 'glossary-a-2')
-!=partial(fragPath + 'glossary-b-c')
-!=partial(fragPath + 'glossary-d1')
-!=partial(fragPath + 'glossary-d2')
-!=partial(fragPath + 'glossary-e1')
-!=partial(fragPath + 'glossary-e2')
-!=partial(fragPath + 'glossary-f-l')
-!=partial(fragPath + 'glossary-m1')
-//partial(fragPath + 'glossary-m2') not needed in dart
-!=partial(fragPath + 'glossary-n-s-1')
-
-:marked
- ## snake_case
-
-.l-sub-section
+block annotation-defn
:marked
- The practice of writing compound words or phrases such that each word is separated by an
- underscore (`_`).
-
- Library and file names are often spelled in snake_case. Examples include:
- `angular2_tour_of_heroes` and `app_component.dart`.
-
- This form is also known as **underscore case**.
+ When unqualified, _annotation_ refers to a Dart [metadata
+ annotation][metadata] (as opposed to, say, a type annotation). A metadata
+ annotation begins with the character `@`, followed by either a reference
+ to a compile-time constant (such as [`Component`](#component)) or a call
+ to a constant constructor. See the [Dart Language Guide][metadata] for
+ details.
-!=partial(fragPath + 'glossary-n-s-2')
-!=partial(fragPath + 'glossary-t1')
-//partial(fragPath + 'glossary-t2') notneeded in dart
-!=partial(fragPath + 'glossary-u-z')
+ The corresponding term in TypeScript and JavaScript is
+ [_decorator_](!{docsPath}/ts/latest/glossary.html#decorator).
+
+ [metadata]: https://www.dartlang.org/guides/language/language-tour#metadata
+
+block bootstrap-defn-top
+ :marked
+ We launch an Angular application by "bootstrapping" it with the
+ [bootstrap][bootstrap] method. The `bootstrap` method identifies an
+ application's top level "root" [Component](#component) and optionally
+ registers service [providers](#provider) with the [dependency injection
+ system](#dependency-injection).
+
+ [bootstrap]: !{docsLatest}/api/angular2.platform.browser/bootstrap.html
+
+block decorator-defn
+ :marked
+ When used in this guide, these JavaScript terms are taken as synonymous with
+ [annotation](#annotation).
+
+block module-defn
+ //- Taken from the Dart Difference in guide/architecture.jade
+ :marked
+ In this guide, the term _module_ refers to a Dart compilation unit, such
+ as a library, or a package. (If a Dart file has no `library` or `part`
+ directive, then that file itself is a library and thus a compilation
+ unit.) For more information about compilation units, see
+ the chapter on "Libraries and Scripts" in the
+ [Dart Language Specification](https://www.dartlang.org/docs/spec/).
+
+block routing-component-defn
+ :marked
+ A [Component](#component) with an attached router.
+
+ In most cases, the component became attached to a [router](#router) by means
+ of a `@RouterConfig` #{decorator} that defined routes to views controlled by this component.
+
+ The component's template has a `RouterOutlet` element where it can display views produced by the router.
+
+ It likely has anchor tags or buttons with `RouterLink` directives that users can click to navigate.
+
+block append snake-case-defn
+ :marked
+ Library and file names are often spelled in snake_case. Examples include:
+ `angular2_tour_of_heroes` and `app_component.dart`.
+
+block zone-defn
+ :marked
+ Zones are a mechanism for encapsulating and intercepting
+ a Dart application's asynchronous activity.
+
+ To learn more, consult the [zones article][zones].
+
+ [zones]: https://www.dartlang.org/articles/libraries/zones
diff --git a/public/docs/dart/latest/guide/_data.json b/public/docs/dart/latest/guide/_data.json
index 9fed0cf4fe..f13c3c42c8 100644
--- a/public/docs/dart/latest/guide/_data.json
+++ b/public/docs/dart/latest/guide/_data.json
@@ -36,13 +36,6 @@
"basics": true
},
- "forms-deprecated": {
- "title": "Forms",
- "intro": "A form creates a cohesive, effective, and compelling data entry experience. An Angular form coordinates a set of data-bound user controls, tracks changes, validates input, and presents errors.",
- "basics": true,
- "hide": true
- },
-
"dependency-injection": {
"title": "Dependency Injection",
"intro": "Angular's dependency injection system creates and delivers dependent services \"just-in-time\".",
@@ -59,7 +52,7 @@
"cheatsheet": {
"title": "Angular Cheat Sheet",
- "intro": "A quick guide to Angular syntax.",
+ "intro": "A quick guide to Angular syntax. (Content is provisional and may change.)",
"nextable": true,
"basics": true
},
@@ -87,6 +80,11 @@
"intro": "Attribute directives attach behavior to elements."
},
+ "browser-support": {
+ "title": "Browser support",
+ "intro": "Browser support and polyfills guide."
+ },
+
"component-styles": {
"title": "Component Styles",
"intro": "Learn how to apply CSS styles to components."
@@ -125,12 +123,6 @@
"intro": "Pipes transform displayed values within a template."
},
- "router-deprecated": {
- "title": "Routing & Navigation",
- "intro": "Discover the basics of screen navigation with the Angular 2 Component Router.",
- "hide": true
- },
-
"router": {
"title": "Routing & Navigation",
"intro": "Discover the basics of screen navigation with the Angular 2 Component Router."
diff --git a/public/docs/dart/latest/guide/animations.jade b/public/docs/dart/latest/guide/animations.jade
index 6778b6af28..c743361ac8 100644
--- a/public/docs/dart/latest/guide/animations.jade
+++ b/public/docs/dart/latest/guide/animations.jade
@@ -1 +1 @@
-!= partial("../../../_includes/_ts-temp")
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/guide/architecture.jade b/public/docs/dart/latest/guide/architecture.jade
index 9bf1256210..c72080b6e9 100644
--- a/public/docs/dart/latest/guide/architecture.jade
+++ b/public/docs/dart/latest/guide/architecture.jade
@@ -6,7 +6,7 @@ block includes
- var _at_angular = 'angular2'
:marked
- Angular 2 is a framework to help us build client applications in HTML and
+ Angular is a framework to help us build client applications in HTML and
either JavaScript or a language (like Dart or TypeScript) that compiles to JavaScript.
block angular-parts
diff --git a/public/docs/dart/latest/guide/browser-support.jade b/public/docs/dart/latest/guide/browser-support.jade
new file mode 100644
index 0000000000..c743361ac8
--- /dev/null
+++ b/public/docs/dart/latest/guide/browser-support.jade
@@ -0,0 +1 @@
+include ../../../_includes/_ts-temp
diff --git a/public/docs/dart/latest/guide/cheatsheet.jade b/public/docs/dart/latest/guide/cheatsheet.jade
index ff8cc6085c..51a21522a9 100644
--- a/public/docs/dart/latest/guide/cheatsheet.jade
+++ b/public/docs/dart/latest/guide/cheatsheet.jade
@@ -1 +1 @@
-!= partial("../cheatsheet")
+extends ../cheatsheet
diff --git a/public/docs/dart/latest/guide/dependency-injection.jade b/public/docs/dart/latest/guide/dependency-injection.jade
index c840601347..6656739107 100644
--- a/public/docs/dart/latest/guide/dependency-injection.jade
+++ b/public/docs/dart/latest/guide/dependency-injection.jade
@@ -34,6 +34,12 @@ block real-logger
A real implementation would probably use the
[logging package](https://pub.dartlang.org/packages/logging).
+block provider-shorthand
+ :marked
+ This is actually a shorthand expression for a provider registration
+ that creates a new instance of the
+ [Provider](../api/angular2.core/Provider-class.html) class:
+
block provider-ctor-args
- var _secondParam = 'named parameter, such as useClass
'
:marked
@@ -101,7 +107,7 @@ block dart-map-alternative
As an alternative to using a configuration `Map`, we can define
a custom configuration class:
- +makeExample('lib/app_config.dart (alternative config)','config-alt')
+ +makeExcerpt('lib/app_config.dart (alternative config)','config-alt')
:marked
Defining a configuration class has a few benefits. One key benefit
diff --git a/public/docs/dart/latest/guide/forms-deprecated.jade b/public/docs/dart/latest/guide/forms-deprecated.jade
deleted file mode 100644
index f5711f49ee..0000000000
--- a/public/docs/dart/latest/guide/forms-deprecated.jade
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../_util-fns
-
-:marked
- This page has no Dart equivalent. Instead, see the [forms guide](forms.html).
diff --git a/public/docs/dart/latest/guide/forms.jade b/public/docs/dart/latest/guide/forms.jade
index 19b7d09aa5..3eaa3ae40e 100644
--- a/public/docs/dart/latest/guide/forms.jade
+++ b/public/docs/dart/latest/guide/forms.jade
@@ -1,6 +1,5 @@
include ../_util-fns
-
:marked
We’ve all used a form to log in, submit a help request, place an order, book a flight,
schedule a meeting, and perform countless other data entry tasks.
@@ -30,6 +29,8 @@ include ../_util-fns
- How to share information across controls with template reference variables
+ Run the .
+
.l-main-section
:marked
## Template-driven forms
@@ -88,7 +89,7 @@ figure.image-display
:marked
## Setup
- Create a new project folder (`angular2_forms`) and create 3 files:
+ Create a new project folder (`angular_forms`) and create 3 files:
`pubspec.yaml`, `web/index.html`, and `web/main.dart`.
(These files should be familiar from the
[QuickStart](../quickstart.html).) Put these contents in the files:
@@ -159,7 +160,7 @@ figure.image-display
There’s nothing special about this component, nothing form-specific,
nothing to distinguish it from any component we've written before.
- Understanding this component requires only the Angular 2 concepts covered in previous chapters.
+ Understanding this component requires only the Angular concepts covered in previous chapters.
1. The code imports a standard set of symbols from the Angular library.
@@ -517,7 +518,7 @@ figure.image-display
Recall from the previous section that `ngControl` registered this input box with the
`NgForm` directive as "name".
- We didn't add the **[`NgForm`](../api/common/index/NgForm-directive.html) directive*
+ We didn't add the [NgForm](../api/angular2.common/NgForm-class.html) directive
explicitly. Angular added it surreptitiously, wrapping it around the `