├── .gitignore
├── README.md
├── bundle.js
├── coverage.png
├── index.html
├── index.ts
├── karma.conf.js
├── package.json
├── src
├── app
│ ├── app.controller.ts
│ ├── app.module.ts
│ └── index.ts
└── transformer
│ ├── index.ts
│ ├── transformer.factory.spec.ts
│ ├── transformer.factory.ts
│ └── transformer.module.ts
├── tsconfig.json
├── typings.json
├── webpack.config.js
└── webpack.config.karma.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 | *.pid.lock
11 |
12 | # Directory for instrumented libs generated by jscoverage/JSCover
13 | lib-cov
14 |
15 | # Coverage directory used by tools like istanbul
16 | coverage
17 |
18 | # nyc test coverage
19 | .nyc_output
20 |
21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
22 | .grunt
23 |
24 | # node-waf configuration
25 | .lock-wscript
26 |
27 | # Compiled binary addons (http://nodejs.org/api/addons.html)
28 | build/Release
29 |
30 | # Dependency directories
31 | node_modules
32 | jspm_packages
33 |
34 | # Optional npm cache directory
35 | .npm
36 |
37 | # Optional REPL history
38 | .node_repl_history
39 |
40 | typings
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-webpack-typescript-karma-coverage
2 | An exemplary project using Angular 1.x, Webpack, TypeScript and Karma (with Coverage).
3 |
4 | 
5 |
6 | ## How to run?
7 | 0. `npm install -g typings` (if you don't have it installed globally yet).
8 | 1. Clone the repository (i.e. `git clone https://github.com/zbicin/angular-webpack-typescript-karma-coverage.git && cd angular-webpack-typescript-karma-coverage`).
9 | 2. `npm install`.
10 | 3. `typings install`.
11 | 4. `npm start` to see the simple app running.
12 | 5. `npm test` to run karma and generate coverage tests. The latter are located in the `coverage/` directory.
13 |
14 | ## The most interesting parts:
15 | * `webpack.config.js` with `devtool` set to `inline-source-map` and an appropriate entry point:
16 | ```javascript
17 | // webpack.config.js
18 | module.exports = {
19 | entry: 'index.ts',
20 | devtool: 'inline-source-map',
21 |
22 | // ...
23 | }
24 | ```
25 | * `webpack.config.karma.js` - slightly modified webpack config which is used exclusively by karma:
26 | ```javascript
27 | // webpack.config.karma.js
28 | var webpackConfig = require('./webpack.config.js');
29 |
30 | webpackConfig.entry = {};
31 | webpackConfig.module.postLoaders = [
32 | {
33 | test: /\.ts$/,
34 | loader: 'istanbul-instrumenter-loader',
35 | exclude: [
36 | 'node_modules',
37 | /\.spec\.ts$/
38 | ]
39 | }
40 | ]
41 |
42 | module.exports = webpackConfig;
43 | ```
44 | * `karma.conf.js` using `source-map-support` framework and generating a json coverage report:
45 | ```javascript
46 | // karma.conf.js
47 | var webpackKarmaConfig = require('./webpack.config.karma.js');
48 |
49 | module.exports = function (config) {
50 | config.set({
51 | frameworks: ['jasmine', 'source-map-support'],
52 |
53 | files: [
54 | './index.ts',
55 | './node_modules/angular-mocks/angular-mocks.js',
56 | './src/**/*.spec.ts'
57 | ],
58 |
59 | preprocessors: {
60 | './index.ts': ['webpack'],
61 | './src/**/*.spec.ts': ['webpack']
62 | },
63 |
64 | reporters: ['progress', 'coverage'],
65 |
66 | webpack: webpackKarmaConfig,
67 |
68 | coverageReporter: {
69 | reporters: [
70 | {
71 | type: 'html',
72 | dir: 'coverage/html-js',
73 | subdir: '.'
74 | },
75 | {
76 | type: 'json',
77 | dir: 'coverage/json',
78 | subdir: '.'
79 | }
80 | ]
81 | }
82 |
83 | // ...
84 | })
85 | }
86 | ```
87 | * `tsconfig.json` with `inlineSourceMap` set to `true` and `sourceMap` set to `false`:
88 | ```javascript
89 | // tsconfig.json
90 | {
91 | "compilerOptions": {
92 | "inlineSourceMap": true,
93 | "sourceMap": false
94 | },
95 |
96 | // ...
97 | }
98 |
99 | ```
100 | * `remap-istanbul -i coverage/json/coverage-final.json -o coverage/html-ts -t html` being run by `npm test`. It generates an HTML report containing original TypeScript source files, basing on the json report generated by karma-coverage:
101 | ```javascript
102 | // package.json
103 | {
104 | "scripts": {
105 | "start": "http-server -o",
106 | "test": "npm run karma && npm run ts-coverage-remap",
107 | "karma": "karma start",
108 | "ts-coverage-remap": "remap-istanbul -i coverage/json/coverage-final.json -o coverage/html-ts -t html"
109 | },
110 |
111 | // ...
112 | }
113 | ```
114 |
115 | ## License
116 | [WTFPL](http://www.wtfpl.net/)
117 |
118 |
119 |
--------------------------------------------------------------------------------
/coverage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zbicin/angular-webpack-typescript-karma-coverage/ffdc3eef7bcf182b78160b3fad5555ea4bcf801e/coverage.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | An exemplary project using Angular 1.x, Webpack, TypeScript and Karma (with Coverage)
7 |
8 |
9 |
10 |
11 |
angular-webpack-typescript-karma-coverage
12 |
An exemplary project using Angular 1.x, Webpack, TypeScript and Karma (with Coverage)
13 |
14 |
15 |
16 |
33 |
34 |
35 |
36 |
37 | View on GitHub
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | import './node_modules/angular/angular.js';
2 | import './node_modules/bootstrap/dist/css/bootstrap.css';
3 |
4 | let requireAll = (requireContext) => requireContext.keys().map(requireContext);
5 | requireAll(require.context("./src", true, /index\.ts$/));
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | var webpackKarmaConfig = require('./webpack.config.karma.js');
2 |
3 | module.exports = function (config) {
4 | config.set({
5 |
6 | // base path that will be used to resolve all patterns (eg. files, exclude)
7 | basePath: '',
8 |
9 |
10 | // frameworks to use
11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
12 | frameworks: ['jasmine', 'source-map-support'],
13 |
14 |
15 | // list of files / patterns to load in the browser
16 | files: [
17 | './index.ts',
18 | './node_modules/angular-mocks/angular-mocks.js',
19 | './src/**/*.spec.ts'
20 | ],
21 |
22 |
23 | // list of files to exclude
24 | exclude: [
25 | ],
26 |
27 |
28 | // preprocess matching files before serving them to the browser
29 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
30 | preprocessors: {
31 | './index.ts': ['webpack'],
32 | './src/**/*.spec.ts': ['webpack']
33 | },
34 |
35 |
36 | // test results reporter to use
37 | // possible values: 'dots', 'progress'
38 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
39 | reporters: ['progress', 'coverage'],
40 |
41 |
42 | // web server port
43 | port: 9876,
44 |
45 |
46 | // enable / disable colors in the output (reporters and logs)
47 | colors: true,
48 |
49 |
50 | // level of logging
51 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
52 | logLevel: config.LOG_WARN,
53 |
54 |
55 | // enable / disable watching file and executing tests whenever any file changes
56 | autoWatch: false,
57 |
58 |
59 | // start these browsers
60 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
61 | browsers: ['PhantomJS'],
62 |
63 |
64 | // Continuous Integration mode
65 | // if true, Karma captures browsers, runs the tests and exits
66 | singleRun: true,
67 |
68 | // Concurrency level
69 | // how many browser should be started simultaneous
70 | concurrency: Infinity,
71 |
72 | webpack: webpackKarmaConfig,
73 |
74 | // optionally, configure the reporter
75 | coverageReporter: {
76 | reporters: [
77 | {
78 | type: 'html',
79 | dir: 'coverage/html-js',
80 | subdir: '.'
81 | },
82 | {
83 | type: 'json',
84 | dir: 'coverage/json',
85 | subdir: '.'
86 | }
87 | ]
88 | }
89 | })
90 | }
91 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-webpack-typescript-karma-coverage",
3 | "version": "1.0.0",
4 | "description": "An exemplary project using Angular 1.x, Webpack, TypeScript and Karma (with Coverage).",
5 | "scripts": {
6 | "start": "http-server -o",
7 | "test": "npm run karma && npm run ts-coverage-remap",
8 | "karma": "karma start",
9 | "ts-coverage-remap": "remap-istanbul -i coverage/json/coverage-final.json -o coverage/html-ts -t html"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/zbicin/angular-webpack-typescript-karma-coverage.git"
14 | },
15 | "keywords": [
16 | "angular",
17 | "webpack",
18 | "typescript",
19 | "karma",
20 | "coverage"
21 | ],
22 | "author": "Krzysztof Zbiciński ",
23 | "license": "WTFPL",
24 | "bugs": {
25 | "url": "https://github.com/zbicin/angular-webpack-typescript-karma-coverage/issues"
26 | },
27 | "homepage": "https://github.com/zbicin/angular-webpack-typescript-karma-coverage#readme",
28 | "dependencies": {
29 | "http-server": "^0.9.0"
30 | },
31 | "devDependencies": {
32 | "angular": "^1.5.8",
33 | "angular-mocks": "^1.5.8",
34 | "bootstrap": "^3.3.7",
35 | "css-loader": "^0.23.1",
36 | "file-loader": "^0.9.0",
37 | "istanbul-instrumenter-loader": "^0.2.0",
38 | "jasmine": "^2.4.1",
39 | "karma": "^1.1.2",
40 | "karma-coverage": "^1.1.1",
41 | "karma-jasmine": "^1.0.2",
42 | "karma-phantomjs-launcher": "^1.0.1",
43 | "karma-source-map-support": "^1.1.0",
44 | "karma-webpack": "^1.7.0",
45 | "remap-istanbul": "^0.6.4",
46 | "style-loader": "^0.13.1",
47 | "ts-loader": "^0.8.2",
48 | "typescript": "^1.8.10",
49 | "typings": "^1.3.2",
50 | "url-loader": "^0.5.7",
51 | "webpack": "^1.13.1"
52 |
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/app/app.controller.ts:
--------------------------------------------------------------------------------
1 | import * as Transformer from '../transformer';
2 |
3 | export class AppController {
4 | private input: string;
5 | private method: string;
6 | private result: string;
7 |
8 | public constructor(private transformer: Transformer.ITransformerService) {
9 | this.method = 'toLowerCase';
10 | this.input = 'Input some chars';
11 | }
12 |
13 | public transform() {
14 | if (this.method === 'toLowerCase') {
15 | this.result = this.transformer.toLowerCase(this.input);
16 | }
17 | else if (this.method === 'toUpperCase') {
18 | this.result = this.transformer.toUpperCase(this.input);
19 | }
20 | }
21 | }
22 |
23 | angular.module('app')
24 | .controller('AppController', AppController);
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import {} from '../transformer';
2 |
3 | angular.module('app', ['app.transformer']);
--------------------------------------------------------------------------------
/src/app/index.ts:
--------------------------------------------------------------------------------
1 | import './app.module.ts';
2 | export * from './app.controller.ts';
--------------------------------------------------------------------------------
/src/transformer/index.ts:
--------------------------------------------------------------------------------
1 | import './transformer.module.ts';
2 | export * from './transformer.factory.ts';
--------------------------------------------------------------------------------
/src/transformer/transformer.factory.spec.ts:
--------------------------------------------------------------------------------
1 | describe('transformer', () => {
2 | let factory;
3 |
4 | beforeEach(() => {
5 | angular.mock.module('app.transformer');
6 |
7 | angular.mock.inject((transformer) => {
8 | factory = transformer;
9 | });
10 | });
11 |
12 | it('should transform to upper case correctly', () => {
13 | let result = factory.toUpperCase('foo');
14 |
15 | expect(result).toEqual('FOO');
16 | });
17 | });
--------------------------------------------------------------------------------
/src/transformer/transformer.factory.ts:
--------------------------------------------------------------------------------
1 | export interface ITransformerService {
2 | toLowerCase(input: string): string;
3 | toUpperCase(input: string): string;
4 | }
5 |
6 | export class TransformerService {
7 | constructor() { }
8 |
9 | toLowerCase(input: string): string {
10 | return input.toLowerCase();
11 | }
12 |
13 | toUpperCase(input: string): string {
14 | return input.toUpperCase();
15 | }
16 | }
17 |
18 | angular.module('app.transformer')
19 | .factory('transformer', () => new TransformerService());
20 |
--------------------------------------------------------------------------------
/src/transformer/transformer.module.ts:
--------------------------------------------------------------------------------
1 | angular.module('app.transformer', []);
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "inlineSourceMap": true,
4 | "sourceMap": false
5 | },
6 | "exclude": [
7 | "node_modules"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "globalDependencies": {
3 | "angular": "registry:dt/angular#1.5.0+20160802155123",
4 | "angular-mocks": "registry:dt/angular-mocks#1.5.0+20160608104721",
5 | "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
6 | "jquery": "registry:dt/jquery#1.10.0+20160704162008",
7 | "webpack-env": "registry:dt/webpack-env#1.12.2+20160316155526"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: "./index.ts",
3 | devtool: 'inline-source-map',
4 | output: {
5 | path: __dirname,
6 | filename: "bundle.js"
7 | },
8 | module: {
9 | loaders: [
10 | { test: /\.css$/, loader: "style-loader!css-loader" },
11 | { test: /\.ts$/, loader: "ts-loader" },
12 | { test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader' }
13 | ]
14 | }
15 | };
--------------------------------------------------------------------------------
/webpack.config.karma.js:
--------------------------------------------------------------------------------
1 | var webpackConfig = require('./webpack.config.js');
2 |
3 | webpackConfig.entry = {};
4 | webpackConfig.module.postLoaders = [
5 | {
6 | test: /\.ts$/,
7 | loader: 'istanbul-instrumenter-loader',
8 | exclude: [
9 | 'node_modules',
10 | /\.spec\.ts$/
11 | ]
12 | }
13 | ]
14 |
15 | module.exports = webpackConfig;
--------------------------------------------------------------------------------