docs(testing): add tests that involve Angular 2

This commit is contained in:
Ward Bell
2016-04-13 14:02:36 -07:00
parent bd079369f3
commit dd7b5176a8
17 changed files with 1035 additions and 260 deletions
+1
View File
@@ -10,3 +10,4 @@ tsconfig.json
tslint.json
npm-debug*.
**/protractor.config.js
_test-output
+72 -49
View File
@@ -1,68 +1,91 @@
// Tun on full stack traces in errors to help debugging
Error.stackTraceLimit=Infinity;
/*global jasmine, __karma__, window*/
(function () {
// Error.stackTraceLimit = Infinity;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
// // Cancel Karma's synchronous start,
// // we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function() {};
// Cancel Karma's synchronous start,
// we call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function () { };
// SET THE RUNTIME APPLICATION ROOT HERE
var appRoot ='app'; // no trailing slash!
System.config({
packages: {
'base/app': {
defaultExtension: false,
// removed because of issues with raw .js files not being found.
// format: 'register',
map: Object.keys(window.__karma__.files).
filter(onlyAppFiles).
reduce(function createPathRecords(pathsMapping, appPath) {
// creates local module name mapping to global path with karma's fingerprint in path, e.g.:
// './hero.service': '/base/src/app/hero.service.js?f4523daf879cfb7310ef6242682ccf10b2041b3e'
var moduleName = appPath.replace(/^\/base\/app\//, './').replace(/\.js$/, '');
pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath]
return pathsMapping;
}, {})
// RegExp for client application base path within karma (which always starts 'base\')
var karmaBase = '^\/base\/'; // RegEx string for base of karma folders
var appPackage = 'base/' + appRoot; //e.g., base/app
var appRootRe = new RegExp(karmaBase + appRoot + '\/');
var onlyAppFilesRe = new RegExp(karmaBase + appRoot + '\/(?!.*\.spec\.js$)([a-z0-9-_\.\/]+)\.js$');
}
}
});
var moduleNames = [];
// old code from angular 44
// System.import('angular2/src/core/dom/browser_adapter').then(function(browser_adapter) {
// new path for angular 51
System.import('angular2/src/platform/browser/browser_adapter').then(function(browser_adapter) {
browser_adapter.BrowserDomAdapter.makeCurrent();
}).then(function() {
// Configure systemjs packages to use the .js extension for imports from the app folder
var packages = {};
packages[appPackage] = {
defaultExtension: false,
format: 'register',
map: Object.keys(window.__karma__.files)
.filter(onlyAppFiles)
// Create local module name mapping to karma file path for app files
// with karma's fingerprint in query string, e.g.:
// './hero.service': '/base/app/hero.service.js?f4523daf879cfb7310ef6242682ccf10b2041b3e'
.reduce(function (pathsMapping, appPath) {
var moduleName = appPath.replace(appRootRe, './').replace(/\.js$/, '');
pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath];
return pathsMapping;
}, {})
}
System.config({ packages: packages });
// 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 all spec files
// (e.g. 'base/app/hero.service.spec.js')
.then(function () {
return Promise.all(
Object.keys(window.__karma__.files) // All files served by Karma.
.filter(onlySpecFiles)
// .map(filePath2moduleName) // Normalize paths to module names.
.map(function(moduleName) {
// loads all spec files via their global module names (e.g. 'base/src/app/hero.service.spec')
return System.import(moduleName);
}));
Object.keys(window.__karma__.files)
.filter(onlySpecFiles)
.map(function (moduleName) {
moduleNames.push(moduleName);
return System.import(moduleName);
}));
})
.then(function() {
__karma__.start();
}, function(error) {
__karma__.error(error.stack || error);
});
.then(success, fail);
function filePath2moduleName(filePath) {
return filePath.
replace(/^\//, ''). // remove / prefix
replace(/\.\w+$/, ''); // remove suffix
}
////// Helpers //////
function onlyAppFiles(filePath) {
return /^\/base\/app\/.*\.js$/.test(filePath) && !onlySpecFiles(filePath);
return onlyAppFilesRe.test(filePath);
}
function onlySpecFiles(filePath) {
return /\.spec\.js$/.test(filePath);
}
function success () {
console.log(
'Spec files loaded:\n ' +
moduleNames.join('\n ') +
'\nStarting Jasmine testrunner');
__karma__.start();
}
function fail(error) {
__karma__.error(error.stack || error);
}
})();
+68 -29
View File
@@ -1,43 +1,82 @@
module.exports = function(config) {
var appBase = 'app/'; // transpiled app JS files
var appAssets ='base/app/'; // component assets fetched by Angular's compiler
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
// paths loaded by Karma
{pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true},
{pattern: 'node_modules/angular2/bundles/angular2.js', included: true, watched: true},
{pattern: 'node_modules/angular2/bundles/testing.js', included: true, watched: true},
{pattern: 'karma-test-shim.js', included: true, watched: true},
{pattern: 'app/test/*.js', included: true, watched: true},
// paths loaded via module imports
{pattern: 'app/**/*.js', included: false, watched: true},
// paths loaded via Angular's component compiler
// (these paths need to be rewritten, see proxies section)
{pattern: 'app/**/*.html', included: false, watched: true},
{pattern: 'app/**/*.css', included: false, watched: true},
// paths to support debugging with source maps in dev tools
{pattern: 'app/**/*.ts', included: false, watched: false},
{pattern: 'app/**/*.js.map', included: false, watched: false}
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-htmlfile-reporter')
],
// proxied base paths
proxies: {
// required for component assests fetched by Angular's compiler
"/app/": "/base/app/"
customLaunchers: {
// From the CLI. Not used here but interesting
// chrome setup for travis CI using chromium
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
reporters: ['progress'],
port: 9877,
files: [
// Angular and shim libraries loaded by Karma
{ pattern: 'node_modules/systemjs/dist/system-polyfills.js', included: true, watched: true },
{ pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true },
{ pattern: 'node_modules/es6-shim/es6-shim.js', included: true, watched: true },
{ pattern: 'node_modules/angular2/bundles/angular2-polyfills.js', included: true, watched: true },
{ pattern: 'node_modules/rxjs/bundles/Rx.js', included: true, watched: true },
{ pattern: 'node_modules/angular2/bundles/angular2.js', included: true, watched: true },
{ pattern: 'node_modules/angular2/bundles/testing.dev.js', included: true, watched: true },
// External libraries loaded by Karma
{ pattern: 'node_modules/angular2/bundles/http.dev.js', included: true, watched: true },
{ pattern: 'node_modules/angular2/bundles/router.dev.js', included: true, watched: true },
{ pattern: 'node_modules/a2-in-memory-web-api/web-api.js', included: true, watched: true },
// Configures module loader w/ app and specs, then launch karma
{ pattern: 'karma-test-shim.js', included: true, watched: true },
// transpiled application & spec code paths loaded via module imports
{pattern: appBase + '**/*.js', included: false, watched: true},
// asset (HTML & CSS) paths loaded via Angular's component compiler
// (these paths need to be rewritten, see proxies section)
{pattern: appBase + '**/*.html', included: false, watched: true},
{pattern: appBase + '**/*.css', included: false, watched: true},
// paths for debugging with source maps in dev tools
{pattern: appBase + '**/*.ts', included: false, watched: false},
{pattern: appBase + '**/*.js.map', included: false, watched: false}
],
// proxied base paths for loading assets
proxies: {
// required for component assets fetched by Angular's compiler
"/app/": appAssets
},
exclude: [],
preprocessors: {},
reporters: ['progress', 'html'],
// HtmlReporter configuration
htmlReporter: {
// Open this file to see results in browser
outputFile: '_test-output/tests.html',
// Optional
pageTitle: 'Unit Tests',
subPageTitle: __dirname
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: true
singleRun: false
})
}
-68
View File
@@ -1,68 +0,0 @@
// Karma configuration
// Generated on Mon Aug 10 2015 11:36:40 GMT-0700 (Pacific Daylight Time)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
{ pattern: 'https://code.angularjs.org/2.0.0-alpha.34/angular2.sfx.dev.js', watched: false },
'**/js/*.js',
],
// list of files to exclude
exclude: [
'**/*.e2e-spec.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
})
}
-70
View File
@@ -1,70 +0,0 @@
// Karma configuration
// Generated on Mon Aug 10 2015 11:36:40 GMT-0700 (Pacific Daylight Time)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
{ pattern: 'https://github.jspm.io/jmcriffey/[email protected]/traceur-runtime.js', watched: false },
{ pattern: 'https://jspm.io/[email protected]', watched: false },
{ pattern: 'https://code.angularjs.org/2.0.0-alpha.34/angular2.dev.js', watched: false },
'**/ts/**/*.spec.js'
],
// list of files to exclude
exclude: [
'**/*.e2e-spec.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
})
}
+3 -2
View File
@@ -4,12 +4,12 @@
"description": "Master package.json, the superset of all dependencies for all of the _example package.json files.",
"main": "index.js",
"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
"start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
"tsc": "tsc",
"tsc:w": "tsc -w",
"lite": "lite-server",
"live": "live-server",
"test": "karma start karma.conf.js",
"test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
"build-and-test": "npm run tsc && npm run test",
"http-server": "tsc && http-server",
"http-server:e2e": "http-server",
@@ -42,6 +42,7 @@
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
"karma-cli": "^0.1.2",
"karma-htmlfile-reporter": "^0.2.2",
"karma-jasmine": "^0.3.8",
"live-server": "^0.9.2",
"protractor": "^3.2.2",
@@ -1,24 +0,0 @@
exports.config = {
onPrepare: function() {
patchProtractorWait(browser);
},
seleniumAddress: 'http://localhost:4444/wd/hub',
baseUrl: 'http://localhost:8080/',
specs: [
'**/*e2e-spec.js'
]
};
// Disable waiting for Angular as we don't have an integration layer yet...
// TODO(tbosch): Implement a proper debugging API for Ng2.0, remove this here
// and the sleeps in all tests.
function patchProtractorWait(browser) {
browser.ignoreSynchronization = true;
var _get = browser.get;
var sleepInterval = process.env.TRAVIS || process.env.JENKINS_URL ? 14000 : 8000;
browser.get = function() {
var result = _get.apply(this, arguments);
browser.sleep(sleepInterval);
return result;
}
}
@@ -3,7 +3,7 @@
// #docregion
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Http} from 'angular2/http';
import {Headers, RequestOptions} from 'angular2/http';
import {Hero} from './hero';
@@ -32,13 +32,13 @@ export class HeroService {
.then(res => <Hero> res.json().data)
.catch(this.handleError);
}
private handleError (error: any) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Promise.reject(error.message || error.json().error || 'Server error');
console.error(error); // log to console instead
let errMsg = error.message || 'Server error';
return Promise.reject(errMsg);
}
// #enddocregion methods
}
// #enddocregion
@@ -3,7 +3,7 @@
// #docregion
// #docregion v1
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Http} from 'angular2/http';
// #enddocregion v1
// #docregion import-request-options
import {Headers, RequestOptions} from 'angular2/http';
@@ -32,10 +32,10 @@ export class HeroService {
// #docregion methods
// #docregion error-handling
getHeroes () {
getHeroes (): Observable<Hero[]> {
// #docregion http-get, http-get-v1
return this.http.get(this._heroesUrl)
.map(res => <Hero[]> res.json().data)
.map(this.extractData)
// #enddocregion v1, http-get-v1, error-handling
.do(data => console.log(data)) // eyeball results in the console
// #docregion v1, http-get-v1, error-handling
@@ -46,27 +46,36 @@ export class HeroService {
// #enddocregion v1
// #docregion addhero
addHero (name: string) : Observable<Hero> {
addHero (name: string): Observable<Hero> {
let body = JSON.stringify({ name });
//#docregion headers
// #docregion headers
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this._heroesUrl, body, options)
//#enddocregion headers
.map(res => <Hero> res.json().data)
.catch(this.handleError)
// #enddocregion headers
.map(this.extractData)
.catch(this.handleError);
}
// #enddocregion addhero
// #docregion v1
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body.data || { };
}
// #docregion error-handling
private handleError (error: Response) {
private handleError (error: any) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error.json().error || 'Server error');
console.error(error); // log to console instead
let errMsg = error.message || 'Server error';
return Observable.throw(errMsg);
}
// #enddocregion error-handling
// #enddocregion methods
+1 -1
View File
@@ -1,5 +1,5 @@
// #docregion
export interface Hero {
export class Hero {
id: number;
name: string;
}
@@ -0,0 +1,148 @@
/* tslint:disable:no-unused-variable */
import {
it,
iit,
xit,
describe,
ddescribe,
xdescribe,
expect,
fakeAsync,
tick,
beforeEach,
inject,
injectAsync,
withProviders,
beforeEachProviders
} from 'angular2/testing';
import { provide } from 'angular2/core';
import {
MockBackend,
MockConnection } from 'angular2/src/http/backends/mock_backend';
import {
BaseRequestOptions,
ConnectionBackend,
Request,
RequestMethod,
RequestOptions,
Response,
ResponseOptions,
URLSearchParams,
HTTP_PROVIDERS,
XHRBackend,
Http} from 'angular2/http';
// Add all operators to Observable
import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import { Hero } from './hero';
import { HeroService } from './http-hero.service';
type HeroData = {id: string, name: string}
const makeHeroData = () => [
{ "id": "1", "name": "Windstorm" },
{ "id": "2", "name": "Bombasto" },
{ "id": "3", "name": "Magneta" },
{ "id": "4", "name": "Tornado" }
];
// HeroService expects response data like {data: {the-data}}
const makeResponseData = (data: {}) => {return { data }; };
//////// SPECS /////////////
describe('Http-HeroService (mockBackend)', () => {
beforeEachProviders(() => [
HTTP_PROVIDERS,
provide(XHRBackend, {useClass: MockBackend})
]);
it('can instantiate service when inject service',
withProviders(() => [HeroService])
.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);
expect(service instanceof HeroService).toBe(true, 'new service should be ok');
}));
it('can provide the mockBackend as XHRBackend',
inject([XHRBackend], (backend: MockBackend) => {
expect(backend).not.toBeNull('backend should be provided');
}));
describe('when getHeroes', () => {
let backend: MockBackend;
let service: HeroService;
let fakeHeroes: HeroData[];
let response: Response;
beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => {
backend = be;
service = new HeroService(http);
fakeHeroes = makeHeroData();
let options = new ResponseOptions({status: 200, body: {data: fakeHeroes}});
response = new Response(options);
}));
it('should have expected fake heroes (then)', injectAsync([], () => {
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
return service.getHeroes().toPromise()
// .then(() => Promise.reject('deliberate'))
.then(heroes => {
expect(heroes.length).toEqual(fakeHeroes.length,
'should have expected no. of heroes');
});
}));
it('should have expected fake heroes (Observable.do)', injectAsync([], () => {
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
return service.getHeroes()
.do(heroes => {
expect(heroes.length).toEqual(fakeHeroes.length,
'should have expected no. of heroes');
})
.toPromise();
}));
it('should be OK returning no heroes', injectAsync([], () => {
let resp = new Response(new ResponseOptions({status: 200, body: {data: []}}));
backend.connections.subscribe((c: MockConnection) => c.mockRespond(resp));
return service.getHeroes()
.do(heroes => {
expect(heroes.length).toEqual(0, 'should have no heroes');
})
.toPromise();
}));
it('should treat 404 as an Observable error', injectAsync([], () => {
let resp = new Response(new ResponseOptions({status: 404}));
backend.connections.subscribe((c: MockConnection) => c.mockRespond(resp));
return service.getHeroes()
.do(heroes => {
fail('should not respond with heroes');
})
.catch(err => {
expect(err).toMatch(/Bad response status/, 'should catch bad response status code');
return Observable.of(null); // failure is the expected test result
})
.toPromise();
}));
});
});
@@ -0,0 +1,44 @@
// #docplaster
// #docregion
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Headers, RequestOptions} from 'angular2/http';
import {Hero} from './hero';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class HeroService {
constructor (private http: Http) {}
private _heroesUrl = 'app/heroes'; // URL to web api
getHeroes (): Observable<Hero[]> {
return this.http.get(this._heroesUrl)
.map(this.extractData)
// .do(data => console.log(data)) // eyeball results in the console
.catch(this.handleError);
}
addHero (name: string): Observable<Hero> {
let body = JSON.stringify({ name });
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(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);
}
let body = res.json();
return body.data || { };
}
private handleError (error: any) {
// in a real world app, we may send the error to some remote logging infrastructure
let errMsg = error.message || 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
@@ -0,0 +1 @@
<span>from external template</span>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,133 @@
// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
import { Component, Injectable } from 'angular2/core';
import { NgIf } from 'angular2/common';
// Let TypeScript know about the special SystemJS __moduleName variable
declare var __moduleName: string;
// moduleName is not set in some module loaders; set it explicitly
if (!__moduleName) {
__moduleName = `http://${location.host}/${location.pathname}/app/`;
}
// console.log(`The __moduleName is ${__moduleName} `);
////////// The App: Services and Components for the tests. //////////////
////////// Services ///////////////
@Injectable()
export class FancyService {
value: string = 'real value';
getAsyncValue() { return Promise.resolve('async value'); }
}
@Injectable()
export class MockFancyService extends FancyService {
value: string = 'mocked out value';
}
//////////// Components /////////////
@Component({
selector: 'button-comp',
template: `<button (click)='clicked()'>Click me!</button>`
})
export class ButtonComp {
wasClicked = false;
clicked() { this.wasClicked = true; }
}
@Component({
selector: 'child-comp',
template: `<span>Original {{childBinding}}</span>`
})
export class ChildComp {
childBinding = 'Child';
}
@Component({
selector: 'child-comp',
template: `<span>Mock</span>`
})
export class MockChildComp { }
@Component({
selector: 'parent-comp',
template: `Parent(<child-comp></child-comp>)`,
directives: [ChildComp]
})
export class ParentComp { }
@Component({
selector: 'my-if-comp',
template: `MyIf(<span *ngIf="showMore">More</span>)`,
directives: [NgIf]
})
export class MyIfComp {
showMore: boolean = false;
}
@Component({
selector: 'child-child-comp',
template: '<span>ChildChild</span>'
})
export class ChildChildComp { }
@Component({
selector: 'child-comp',
template: `<span>Original {{childBinding}}(<child-child-comp></child-child-comp>)</span>`,
directives: [ChildChildComp]
})
export class ChildWithChildComp {
childBinding = 'Child';
}
@Component({
selector: 'child-child-comp',
template: `<span>ChildChild Mock</span>`
})
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: __moduleName,
selector: 'external-template-comp',
templateUrl: 'public-external-template.html'
})
export class ExternalTemplateComp { }
@Component({
selector: 'bad-template-comp',
templateUrl: 'non-existant.html'
})
export class BadTemplateUrl { }
@@ -0,0 +1,48 @@
/*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();
}
})();
@@ -0,0 +1,32 @@
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Angular Public Unit Tests</title>
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
</head>
<body>
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/testing.dev.js"></script>
<script>
var __spec_files__ = ['app/public.spec'];
</script>
<script src="test-shim.js"></script>
</body>
</html>