├── .gitignore ├── LICENSE ├── README.md ├── favicon.ico ├── gulpfile.js ├── index.html ├── karma.conf.js ├── package.json ├── scripts ├── src │ ├── bootstrap.ts │ ├── components │ │ └── header │ │ │ ├── header.html │ │ │ └── header.ts │ ├── pages │ │ └── app │ │ │ ├── app.html │ │ │ └── app.ts │ └── settings.ts └── test │ └── header-spec.ts ├── test-main.js ├── tsconfig.json └── tsd.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | # VS Code settings files 30 | .settings 31 | 32 | # Build files 33 | scripts/build 34 | scripts/maps 35 | 36 | # Tests compiled files 37 | scripts/test/*.js 38 | scripts/test/maps 39 | 40 | # Typings files 41 | typings -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dima Kuzmich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular2 Unit Tests 2 | Angular2 alpha tiny starter that includes unit tests 3 | 4 | ** NOTE: This module is out of date and probably should not be used. Check out [angular2-starter](https://github.com/forforeach/angular2-starter) instead. 5 | 6 | 7 | > This starter uses [gulp.js](http://gulpjs.com/) for a build workflow. 8 | 9 | ## Dependencies 10 | 11 | To run this starter you have to install: 12 | 13 | - [node.js](https://nodejs.org/) (has installation file) 14 | - [gulp](http://gulpjs.com/) (npm install -g gulp) 15 | - [tsd](http://definitelytyped.org/tsd/) (npm install -g tsd) 16 | 17 | ## Installation 18 | * Clone this repository 19 | * `$ npm start` 20 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/forforeach/Angular2-Unit-Tests/a47a0c088f1c2c81df43322825877954a5ef5877/favicon.ico -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var ts = require('gulp-typescript'); 3 | var typescript = require('typescript'); 4 | var del = require('del'); 5 | var runSequence = require('run-sequence'); 6 | var sourcemaps = require('gulp-sourcemaps'); 7 | var connect = require('gulp-connect'); 8 | var open = require('gulp-open'); 9 | var sass = require('gulp-sass'); 10 | var KarmaServer = require('karma').Server; 11 | 12 | 13 | // Add debounce to gulp watch for FTP 14 | (function ftp_debounce_fix() { 15 | 16 | var watch = gulp.watch; 17 | // Overwrite the local gulp.watch function 18 | gulp.watch = function (glob, opt, fn) { 19 | var _this = this, _fn, timeout; 20 | // This is taken from the gulpjs file, but needed to 21 | // qualify the "fn" variable 22 | if (typeof opt === 'function' || Array.isArray(opt)) { 23 | fn = opt; 24 | opt = null; 25 | } 26 | // Make a copy of the callback function for reference 27 | _fn = fn; 28 | // Create a new delayed callback function 29 | fn = function () { 30 | if (timeout) { 31 | clearTimeout(timeout); 32 | } 33 | timeout = setTimeout(Array.isArray(_fn) ? function () { 34 | _this.start.call(_this, _fn); 35 | } : _fn, 2000); 36 | }; 37 | return watch.call(this, glob, opt, fn); 38 | }; 39 | })(); 40 | 41 | var serverOptions = { 42 | root: '', 43 | port: 8000, 44 | livereload: true, 45 | }; 46 | 47 | var tasks = { 48 | defaultTask: 'default', 49 | typeScript: 'typeScript-compile', 50 | htmlAndCss: 'copy-HTML-and-CSS', 51 | copy: 'copy-compiled-JS', 52 | cleanSrc: 'clean-source', 53 | buildSass: 'build-sass', 54 | startWebServer: 'start-webServer', 55 | openBrowser: 'open-browser', 56 | watch: 'watch', 57 | watcherRebuild: 'watcher-rebuild', 58 | cleanTestBuild: 'clean-test-build', 59 | testBuild: 'test-build', 60 | test: 'test' 61 | }; 62 | 63 | // Main task 64 | gulp.task(tasks.defaultTask, function () { 65 | runSequence(tasks.cleanSrc, 66 | tasks.typeScript, 67 | tasks.htmlAndCss, 68 | tasks.test, 69 | tasks.startWebServer, 70 | tasks.openBrowser, 71 | tasks.watch); 72 | }); 73 | 74 | // default task starts watcher. in order not to start it each change 75 | // watcher will run the task bellow 76 | gulp.task(tasks.watcherRebuild, function (callback) { 77 | runSequence( 78 | tasks.cleanSrc, 79 | tasks.typeScript, 80 | //tasks.test, 81 | tasks.htmlAndCss); 82 | callback(); 83 | }); 84 | 85 | // compiles *.ts files by tsconfig.json file and creates sourcemap filse 86 | gulp.task(tasks.typeScript, function () { 87 | var tsProject = ts.createProject('tsconfig.json', { 88 | typescript: typescript 89 | }); 90 | 91 | return gulp.src(['typings/**/**.ts', 'scripts/src/**/**.ts']) 92 | .pipe(sourcemaps.init()) 93 | .pipe(ts(tsProject)) 94 | .pipe(sourcemaps.write('../maps', { includeContent: false, sourceRoot: '/scripts/src' })) 95 | .pipe(gulp.dest('scripts/build')); 96 | }); 97 | 98 | // copy *.html files (templates of components) 99 | // to apropriate directory under public/scripts 100 | gulp.task(tasks.htmlAndCss, function () { 101 | return gulp.src(['scripts/src/**/**.html', 'scripts/src/**/**.css']) 102 | .pipe(gulp.dest('scripts/build')) 103 | .pipe(connect.reload()); 104 | }); 105 | 106 | 107 | gulp.task(tasks.buildSass, function () { 108 | return gulp.src('./scripts/src/angular2_material/src/**/*.scss') 109 | .pipe(sass()) 110 | .pipe(gulp.dest('./scripts/src/angular2_material/src')); 111 | }); 112 | 113 | 114 | // clean all generated/compiled files 115 | // only in both scripts/ directory 116 | gulp.task(tasks.cleanSrc, function () { 117 | return del(['scripts/build/*', 'scripts/maps/*']); 118 | }); 119 | 120 | // watcher 121 | gulp.task(tasks.watch, function () { 122 | gulp.watch(['scripts/src/**/**.ts', 'scripts/src/**/**.html'], [tasks.watcherRebuild]); 123 | }); 124 | 125 | // starts web server 126 | gulp.task(tasks.startWebServer, function () { 127 | connect.server(serverOptions); 128 | }); 129 | 130 | gulp.task(tasks.openBrowser, function () { 131 | gulp.src('index.html') 132 | .pipe(open('', { url: 'http://localhost:' + serverOptions.port })); 133 | }); 134 | 135 | 136 | // tests 137 | gulp.task(tasks.cleanTestBuild, function () { 138 | return del(['scripts/test/**/*.js', 'scripts/test/maps/**']); 139 | }); 140 | 141 | gulp.task(tasks.testBuild, [tasks.cleanTestBuild], function () { 142 | var tsProject = ts.createProject('tsconfig.json', { 143 | typescript: typescript 144 | }); 145 | 146 | return gulp.src(['scripts/test/**/**.ts']) 147 | .pipe(sourcemaps.init()) 148 | .pipe(ts(tsProject)) 149 | .pipe(sourcemaps.write('/maps', { includeContent: false, sourceRoot: '/test' })) 150 | .pipe(gulp.dest('scripts/test')); 151 | }); 152 | 153 | gulp.task(tasks.test, [tasks.testBuild], function (done) { 154 | new KarmaServer({ 155 | configFile: __dirname + '/karma.conf.js', 156 | singleRun: true 157 | }, done).start(); 158 | }); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Angular2 with tests 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Tue Aug 11 2015 17:15:50 GMT+0300 (Jerusalem Daylight Time) 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | 16 | // list of files / patterns to load in the browser 17 | // list of files / patterns to load in the browser 18 | files: [ 19 | 'node_modules/traceur/bin/traceur-runtime.js', 20 | { pattern: 'scripts/build/**/*.js', included: false, serve: true }, 21 | 'node_modules/es6-module-loader/dist/es6-module-loader.js', 22 | 'node_modules/systemjs/dist/system.js', 23 | 'https://code.angularjs.org/2.0.0-alpha.34/angular2.dev.js', 24 | 'test-main.js', 25 | { 26 | pattern: 'scripts/test/**/*spec.js', 27 | included: false, 28 | serve: true, 29 | watch: true 30 | } 31 | ], 32 | 33 | 34 | // list of files to exclude 35 | exclude: [ 36 | 'scripts/build/bootstrap.js' 37 | ], 38 | 39 | // preprocess matching files before serving them to the browser 40 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 41 | preprocessors: { 42 | }, 43 | 44 | 45 | // test results reporter to use 46 | // possible values: 'dots', 'progress' 47 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 48 | reporters: ['progress', 'html'], 49 | 50 | 51 | // web server port 52 | port: 9876, 53 | 54 | 55 | // enable / disable colors in the output (reporters and logs) 56 | colors: true, 57 | 58 | 59 | // level of logging 60 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 61 | logLevel: config.LOG_INFO, 62 | 63 | 64 | // enable / disable watching file and executing tests whenever any file changes 65 | autoWatch: true, 66 | 67 | 68 | // start these browsers 69 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 70 | browsers: ['Chrome'], 71 | 72 | 73 | // Continuous Integration mode 74 | // if true, Karma captures browsers, runs the tests and exits 75 | singleRun: false, 76 | 77 | plugins: [ 78 | 'karma-jasmine', 79 | 'karma-chrome-launcher', 80 | 'karma-jasmine-html-reporter' 81 | ] 82 | }) 83 | } 84 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Angular2-Unit-Tests", 3 | "version": "0.0.1", 4 | "description": "Angular2 alpha tiny starter that includes unit tests", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "gulp test", 8 | "start": "npm install && tsd install && gulp" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/forforeach/Angular2-Unit-Tests" 13 | }, 14 | "author": "Dima Kuzmich", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/forforeach/Angular2-Unit-Tests" 18 | }, 19 | "devDependencies": { 20 | "del": "^1.2.0", 21 | "es6-module-loader": "^0.16.6", 22 | "gulp": "^3.9.0", 23 | "gulp-connect": "^2.2.0", 24 | "gulp-open": "^0.3.2", 25 | "gulp-sass": "^2.0.4", 26 | "gulp-sourcemaps": "^1.5.2", 27 | "gulp-typescript": "^2.7.6", 28 | "jasmine": "^2.3.2", 29 | "jasmine-core": "^2.3.4", 30 | "karma": "^0.13.9", 31 | "karma-chrome-launcher": "^0.2.0", 32 | "karma-jasmine": "^0.3.6", 33 | "karma-jasmine-html-reporter": "^0.1.8", 34 | "run-sequence": "^1.1.0", 35 | "systemjs": "^0.16.11", 36 | "traceur": "0.0.91", 37 | "tsd": "^0.6.3", 38 | "typescript": "^1.5.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /scripts/src/bootstrap.ts: -------------------------------------------------------------------------------- 1 | // Angular2 2 | import {bootstrap, httpInjectables} from 'angular2/angular2'; 3 | 4 | import {App} from './pages/app/app'; 5 | 6 | bootstrap(App); 7 | -------------------------------------------------------------------------------- /scripts/src/components/header/header.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Header

4 | 7 |
8 |
-------------------------------------------------------------------------------- /scripts/src/components/header/header.ts: -------------------------------------------------------------------------------- 1 | import {Component, View, NgFor} from 'angular2/angular2'; 2 | 3 | import { _settings } from '../../settings'; 4 | 5 | 6 | @Component({ 7 | selector: 'header' 8 | }) 9 | @View({ 10 | templateUrl: _settings.buildPath + '/components/header/header.html', 11 | directives: [NgFor] 12 | }) 13 | export class Header { 14 | names: Array; 15 | 16 | constructor() { 17 | this.names = new Array(); 18 | } 19 | 20 | addName(name: string) { 21 | this.names.push(name); 22 | } 23 | } -------------------------------------------------------------------------------- /scripts/src/pages/app/app.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

App body

4 |
-------------------------------------------------------------------------------- /scripts/src/pages/app/app.ts: -------------------------------------------------------------------------------- 1 | import {Component, View} from 'angular2/angular2'; 2 | 3 | import { _settings } from '../../settings' 4 | import {Header} from '../../components/header/header' 5 | 6 | @Component({ 7 | selector: 'app' 8 | }) 9 | @View({ 10 | templateUrl: _settings.pagesPath + '/app/app.html', 11 | directives: [Header] 12 | }) 13 | export class App { 14 | } -------------------------------------------------------------------------------- /scripts/src/settings.ts: -------------------------------------------------------------------------------- 1 | //settings object - currently angular does not support syntax 2 | //of setting relative path to templateUrl 3 | //so we will save it externally as settings const 4 | const _buildPath = 'scripts/build'; 5 | export const _settings = { 6 | buildPath: _buildPath, 7 | componentsPath: _buildPath + '/components', 8 | directivesPath: _buildPath + '/directives', 9 | pagesPath: _buildPath + '/pages' 10 | }; -------------------------------------------------------------------------------- /scripts/test/header-spec.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import {Header} from 'build/components/header/header'; 4 | 5 | export function main() { 6 | describe('header component', () => { 7 | 8 | it('should add string to header names', () => { 9 | var header = new Header(); 10 | var name = 'foo'; 11 | header.addName(name); 12 | expect(header.names.length).toBe(1); 13 | expect(header.names[0]).toBe(name); 14 | }); 15 | }); 16 | } -------------------------------------------------------------------------------- /test-main.js: -------------------------------------------------------------------------------- 1 | /* global System */ 2 | /* global __karma__ */ 3 | /* global System */ 4 | /* global __karma__ */ 5 | 6 | // Cancel Karma's synchronous start, 7 | // we will call `__karma__.start()` later, once all the specs are loaded. 8 | __karma__.loaded = function () { }; 9 | 10 | // Set the base url of our scripts 11 | System.baseURL = '/base/scripts/'; 12 | // Here we set all the preffixes so that we'll 13 | // be able for example to import 'test/test_name' 14 | // instead of 'scripts/build/test_name' 15 | System.paths = { 16 | 'test/*': '/base/scripts/test/*.js', 17 | 'build/*': '/base/scripts/build/*.js', 18 | 'angular2/*': 'angular2/*', 19 | 'rx': 'rx' 20 | }; 21 | 22 | // paths that include spec and ends with .js 23 | function onlySpecFiles(path) { 24 | return /spec\.js$/.test(path); 25 | } 26 | 27 | // takes paths and normalize them to module names 28 | // by removing a base url preffix and .js suffix 29 | function karmaFileToModule(fileName) { 30 | return fileName.replace(System.baseURL, '') 31 | .replace('.js', ''); 32 | } 33 | 34 | Promise.all( 35 | Object.keys(window.__karma__.files) // Takes all files that served by karma 36 | .filter(onlySpecFiles) // choose only test files 37 | .map(karmaFileToModule) // normalize them to module names 38 | .map(function (moduleName) { 39 | return System.import(moduleName) // import each module 40 | .then(function (module) { 41 | if (module.hasOwnProperty('main')) { 42 | module.main(); //expose the tests 43 | } else { 44 | throw new Error('Module ' + moduleName + ' does not implement main() method.'); 45 | } 46 | }); 47 | })).then(function () { 48 | __karma__.start(); // after all tests were exposed 49 | }, function (error) { 50 | console.error(error.stack || error); 51 | __karma__.start(); 52 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "removeComments": true, 5 | "preserveConstEnums": true, 6 | "sourceMap": true, 7 | "target": "es5", 8 | "experimentalDecorators": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tsd.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "v4", 3 | "repo": "borisyankov/DefinitelyTyped", 4 | "ref": "master", 5 | "path": "typings", 6 | "bundle": "typings/tsd.d.ts", 7 | "installed": { 8 | "es6-promise/es6-promise.d.ts": { 9 | "commit": "7c27233ae47768442b9b0a40d7f03fadf593fad2" 10 | }, 11 | "rx/rx.d.ts": { 12 | "commit": "7c27233ae47768442b9b0a40d7f03fadf593fad2" 13 | }, 14 | "angular2/angular2.d.ts": { 15 | "commit": "7c27233ae47768442b9b0a40d7f03fadf593fad2" 16 | }, 17 | "rx/rx-lite.d.ts": { 18 | "commit": "7c27233ae47768442b9b0a40d7f03fadf593fad2" 19 | }, 20 | "jasmine/jasmine.d.ts": { 21 | "commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7" 22 | } 23 | } 24 | } 25 | --------------------------------------------------------------------------------