Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Add sourcemap support for coverage by using remap-istanbul
Browse files Browse the repository at this point in the history
Added remap-istanbul and all supporting karma plugins to correctly
remap the coverage results back to their TypeScript source.

Since all generations happens in memory by Webpack, we needed inline
sourcemap support, provided by the Karma plugins, the Webpack devtool
setting, and the webpack typescript loader.

The normal `ts-loader` doesn't support inline sourcemaps, so we switched
to `awesome-typescript-loader`. We created a new `tsconfig.test.json`
that is the same as the normal `tsconfig.json` but enables inline
sourcemaps by adding `"inlineSourceMap": true`.

The webpack dist builds have also switched to `awesome-typescript-loader`
to keep the configuration consistent.

To make the `awesome-typescript-loader` correctly work with const enums,
we needed to enable `preserveConstEnums` property in the `tsconfig.json`.

We also switched he `test/index.js` to `index.ts` and included
`webpack-env` in the `typings.json` so all wepack requires work in
TypeScript.

To have correct coverage reports consisting of _all_ the source files,
we've added a `Dummy.ts` file in the `src/` folder that is not
referenced by any tests, but must show up in the coverage results.
If this is not the case, we know our test setup is incorrect.

re #15
  • Loading branch information
ThaNarie committed Jul 11, 2016
1 parent 1ae06bd commit 97d348e
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 76 deletions.
91 changes: 45 additions & 46 deletions config/karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,88 +1,87 @@
var path = require('path');
var webpackConfig = require('./webpack.config')();

webpackConfig.module.postLoaders = [
// instrument only testing sources with Istanbul
{
test: /\.ts$/,
include: path.resolve('src/'),
loader: 'istanbul-instrumenter'
}
];

module.exports = function (config)
/**
* Please see Karma config file reference for better understanding:
* http://karma-runner.github.io/latest/config/configuration-file.html
*/
module.exports = function(config)
{
config.set({

// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '../',


// frameworks to use
// List of test frameworks we will use. Most of them are provided by separate packages (adapters).
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'chai'],
frameworks: ['mocha', 'chai', 'source-map-support'],

// list of files / patterns to load in the browser
// Entry point / test environment builder is also written in TypeScript.
files: [
'test/index.js'
'./test/index.ts'
],


// list of files to exclude
exclude: [],


// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/index.js': ['webpack'],
'src/*.ts': ['webpack','coverage'] // only for webstorm, real coverage is injected as webpack-loader
'./src/**/*.ts': [
'webpack',
'sourcemap',
'coverage'
],
'./test/**/*.ts': [
'webpack'
]
},

webpack: {
module : webpackConfig.module,
resolve : webpackConfig.resolve
},
webpack: require('./webpack.config.test')(),

// Make dev server silent.
webpackServer: { noInfo: true },

// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage'],
// A lot of plugins are available for test results reporting.
// You can find them here: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage', 'karma-remap-istanbul'],

// Simple summary (printed to the console) and JSON file which we will remap back to TypeScript.
coverageReporter: {
dir: 'coverage',
reporters: [
// reporters not supporting the `file` property
{ type: 'json', dir: 'coverage', subdir: '.' },
{ type: 'lcov', dir: 'coverage', subdir: '.' },
{ type: 'json', subdir: '.' },
// { type: 'lcov', subdir: '.' },

{ type: 'text' }
]
},


// web server port
port: 9876,


// enable / disable colors in the output (reporters and logs)
colors: true,

// Map code coverage result back to TypeScript using `karma-remap-istanbul`.
remapIstanbulReporter: {
src: 'coverage/coverage-final.json',
reports: {
lcovonly: 'coverage/lcov.info',
html: 'coverage/report'
},
timeoutNotCreated: 5000,
timeoutNoMoreFiles: 1000
},

// 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: ['PhantomJS'],

// web server port
port: 9876,

// enable / disable colors in the output (reporters and logs)
colors: true,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
Expand All @@ -92,4 +91,4 @@ module.exports = function (config)
// how many browser should be started simultaneous
concurrency: Infinity
})
}
};
26 changes: 26 additions & 0 deletions config/tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es5",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"preserveConstEnums": true,
"noImplicitAny": false,
"removeComments": false,
"noEmitHelpers": true,
"sourceMap": false,
"inlineSourceMap": true
},
"exclude": [
"node_modules"
],
"filesGlob": [
"../src/**/*.ts",
"../typings/index.d.ts"
],
"awesomeTypescriptLoaderOptions": {
"resolveGlobs": false,
"forkChecker": true
}
}
5 changes: 4 additions & 1 deletion config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ module.exports = function()
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'ts'
loader: 'awesome-typescript-loader',
query: {
tsconfig: 'tsconfig.json'
}
}
]
},
Expand Down
57 changes: 57 additions & 0 deletions config/webpack.config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*eslint-disable */
var webpack = require('webpack');
var path = require('path');

module.exports = function()
{
return {
/**
* Inline source maps, generated by TypeScript compiler, will be used.
*/
devtool: 'inline-source-map',

resolve: {
extensions: ['', '.ts', '.js']
},
// entry is the "main" source file we want to include/import
entry: './test/index.ts',

verbose: true,

module: {
loaders: [
/**
* Unlike ts-loader, awesome-typescript-loader doesn't allow to override TS compiler options
* in query params. We use separate `tsconfig.test.json` file, which only differs in one thing:
* inline source maps. They are used for code coverage report.
*
* See project repository for details / configuration reference:
* https://github.com/s-panferov/awesome-typescript-loader
*/
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'awesome-typescript-loader',
query: {
tsconfig: 'config/tsconfig.test.json'
}
}
],
postLoaders: [
/**
* Instruments TS source files for subsequent code coverage.
* See https://github.com/deepsweet/istanbul-instrumenter-loader
*/
{
test: /\.ts$/,
loader: 'istanbul-instrumenter-loader',
exclude: [
/node_modules/,
/test/,
/Spec\.ts$/
]
}
]
},
};
};
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,27 @@
"url": "https://github.com/mediamonks/seng-boilerplate.git"
},
"devDependencies": {
"awesome-typescript-loader": "^2.0.1",
"chai": "^3.5.0",
"coveralls": "^2.11.6",
"istanbul": "^0.4.3",
"istanbul-instrumenter-loader": "^0.1.3",
"karma": "^0.13.19",
"istanbul-instrumenter-loader": "^0.2.0",
"karma": "^0.13.22",
"karma-chai": "^0.1.0",
"karma-coverage": "^0.5.3",
"karma-coverage": "^1.0.0",
"karma-mocha": "^1.1.1",
"karma-phantomjs-launcher": "^1.0.0",
"karma-remap-istanbul": "^0.1.1",
"karma-source-map-support": "^1.1.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"marked": "^0.3.5",
"mocha": "^2.5.3",
"npm-run-all": "^2.2.0",
"phantomjs-prebuilt": "^2.1.3",
"pre-push": "^0.1.1",
"remap-istanbul": "^0.6.4",
"rimraf": "^2.5.2",
"ts-loader": "^0.8.0",
"tslint": "^3.3.0",
"typedoc": "^0.4.3",
"typescript": "^1.8.0",
Expand Down
30 changes: 30 additions & 0 deletions src/lib/Dummy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Test file for code coverage checks
* This file is not covered by any tests, but should show up in code coverage
* results as a very low coverage percentage.
*
* @namespace example
* @class Dummy
* @constructor
*/
export default class Dummy
{
/**
* Returns a value!
*
* @method foo
* @param {string} str The input string
* @returns {string}
*/
public foo(str?:string):string
{
if (typeof str == 'undefined')
{
return 'baz';
}
else
{
return str + 'bar';
}
}
}
12 changes: 10 additions & 2 deletions test/index.js → test/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
// require all test files
const testsContext = require.context('./', true, /Spec\.ts$/);
const testsContext = require.context(
'./',
true,
/Spec\.ts/
);

testsContext.keys().forEach(testsContext);

// require all source files
const sourcesContext = require.context('../src/', true, /\.ts$/);
const sourcesContext = require.context(
'../src/',
true,
/\.ts$/
);

sourcesContext.keys().forEach(sourcesContext);
16 changes: 0 additions & 16 deletions test/tsconfig.json

This file was deleted.

16 changes: 9 additions & 7 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"removeComments": false,
"moduleResolution": "node",
"target": "es5",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"preserveConstEnums": true,
"noImplicitAny": false,
"removeComments": false,
"noEmitHelpers": true,
"sourceMap": false,
"experimentalDecorators": true,
"outDir": "./",
"moduleResolution": "node"
"inlineSourceMap": false,
"outDir": "./"
},
"files": [
"./typings/index.d.ts",
Expand Down
3 changes: 3 additions & 0 deletions typings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
},
"devDependencies": {
"chai": "registry:npm/chai#3.5.0+20160415060238"
},
"globalDependencies": {
"webpack-env": "registry:dt/webpack-env#1.12.2+20160316155526"
}
}

0 comments on commit 97d348e

Please sign in to comment.