From 0f4efb0d157eea72f82aaa80998c1dbc0eafc870 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Sun, 23 Oct 2016 14:26:50 +0100 Subject: [PATCH] feat(test): make code coverage and lint optional Heavily inspired by @abner's work on #1799. Partially address #1980 Close #1799 --- .../blueprints/ng2/files/karma.conf.js | 2 +- packages/angular-cli/commands/test.ts | 2 + .../angular-cli/models/webpack-build-test.js | 71 ++++++++++--------- packages/angular-cli/plugins/karma.js | 7 +- packages/angular-cli/tasks/test.ts | 5 ++ tests/e2e/tests/misc/coverage.ts | 2 +- 6 files changed, 53 insertions(+), 36 deletions(-) diff --git a/packages/angular-cli/blueprints/ng2/files/karma.conf.js b/packages/angular-cli/blueprints/ng2/files/karma.conf.js index 5c349bd00abd..3e9878cbc3ea 100644 --- a/packages/angular-cli/blueprints/ng2/files/karma.conf.js +++ b/packages/angular-cli/blueprints/ng2/files/karma.conf.js @@ -27,7 +27,7 @@ module.exports = function (config) { config: './angular-cli.json', environment: 'dev' }, - reporters: ['progress', 'karma-remap-istanbul'], + reporters: config.angularCli.codeCoverage ? ['progress', 'karma-remap-istanbul'] : ['progress'], port: 9876, colors: true, logLevel: config.LOG_INFO, diff --git a/packages/angular-cli/commands/test.ts b/packages/angular-cli/commands/test.ts index 74049b943c1c..2ac4f304d9c7 100644 --- a/packages/angular-cli/commands/test.ts +++ b/packages/angular-cli/commands/test.ts @@ -5,6 +5,8 @@ import {CliConfig} from '../models/config'; const NgCliTestCommand = TestCommand.extend({ availableOptions: [ { name: 'watch', type: Boolean, default: true, aliases: ['w'] }, + { name: 'code-coverage', type: Boolean, default: false, aliases: ['cc'] }, + { name: 'lint', type: Boolean, default: false, aliases: ['l'] }, { name: 'browsers', type: String }, { name: 'colors', type: Boolean }, { name: 'log-level', type: String }, diff --git a/packages/angular-cli/models/webpack-build-test.js b/packages/angular-cli/models/webpack-build-test.js index 9d3262f30138..c23801c3c3f0 100644 --- a/packages/angular-cli/models/webpack-build-test.js +++ b/packages/angular-cli/models/webpack-build-test.js @@ -4,9 +4,43 @@ const path = require('path'); const webpack = require('webpack'); const atl = require('awesome-typescript-loader'); -const getWebpackTestConfig = function (projectRoot, environment, appConfig) { +const getWebpackTestConfig = function (projectRoot, environment, appConfig, testConfig) { const appRoot = path.resolve(projectRoot, appConfig.root); + const extraRules = []; + const extraPlugins = []; + + if (testConfig.codeCoverage) { + extraRules.push({ + test: /\.(js|ts)$/, loader: 'sourcemap-istanbul-instrumenter-loader', + enforce: 'post', + exclude: [ + /\.(e2e|spec)\.ts$/, + /node_modules/ + ], + query: { 'force-sourcemap': true } + }); + } + + if (testConfig.lint) { + extraRules.push({ + test: /\.ts$/, + enforce: 'pre', + loader: 'tslint-loader', + exclude: [ + path.resolve(projectRoot, 'node_modules') + ] + }); + extraPlugins.push(new webpack.LoaderOptionsPlugin({ + options: { + tslint: { + emitErrors: false, + failOnHint: false, + resourcePath: `./${appConfig.root}` + } + } + })) + } return { devtool: 'inline-source-map', @@ -28,21 +62,12 @@ const getWebpackTestConfig = function (projectRoot, environment, appConfig) { }, module: { rules: [ - { - test: /\.ts$/, - enforce: 'pre', - loader: 'tslint-loader', - exclude: [ - path.resolve(projectRoot, 'node_modules') - ] - }, { test: /\.js$/, enforce: 'pre', loader: 'source-map-loader', exclude: [ - path.resolve(projectRoot, 'node_modules/rxjs'), - path.resolve(projectRoot, 'node_modules/@angular') + /node_modules/ ] }, { @@ -63,23 +88,14 @@ const getWebpackTestConfig = function (projectRoot, environment, appConfig) { ], exclude: [/\.e2e\.ts$/] }, - { - test: /\.(js|ts)$/, loader: 'sourcemap-istanbul-instrumenter-loader', - enforce: 'post', - exclude: [ - /\.(e2e|spec)\.ts$/, - /node_modules/ - ], - query: { 'force-sourcemap': true } - }, { test: /\.json$/, loader: 'json-loader' }, - { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, + { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, { test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] }, { test: /\.scss$|\.sass$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000' }, { test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(appRoot, appConfig.index)] } - ] + ].concat(extraRules) }, plugins: [ new webpack.SourceMapDevToolPlugin({ @@ -94,20 +110,11 @@ const getWebpackTestConfig = function (projectRoot, environment, appConfig) { .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')), path.resolve(appRoot, appConfig.environments[environment]) ), - new webpack.LoaderOptionsPlugin({ - options: { - tslint: { - emitErrors: false, - failOnHint: false, - resourcePath: `./${appConfig.root}` - } - } - }), new webpack.ContextReplacementPlugin( /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/, appRoot ) - ], + ].concat(extraPlugins), node: { fs: 'empty', global: true, diff --git a/packages/angular-cli/plugins/karma.js b/packages/angular-cli/plugins/karma.js index 69bf559031be..3ea8a2a0efa5 100644 --- a/packages/angular-cli/plugins/karma.js +++ b/packages/angular-cli/plugins/karma.js @@ -3,7 +3,6 @@ const getWebpackTestConfig = require('../models/webpack-build-test').getWebpackT const CliConfig = require('../models/config').CliConfig; const init = (config) => { - // load Angular CLI config if (!config.angularCli || !config.angularCli.config) { throw new Error('Missing \'angularCli.config\' entry in Karma config'); @@ -11,9 +10,13 @@ const init = (config) => { const angularCliConfig = require(path.join(config.basePath, config.angularCli.config)); const appConfig = angularCliConfig.apps[0]; const environment = config.angularCli.environment || 'dev'; + const testConfig = { + codeCoverage: config.angularCli.codeCoverage || false, + lint: config.angularCli.lint || false, + } // add webpack config - const webpackConfig = getWebpackTestConfig(config.basePath, environment, appConfig); + const webpackConfig = getWebpackTestConfig(config.basePath, environment, appConfig, testConfig); const webpackMiddlewareConfig = { noInfo: true, // Hide webpack output because its noisy. stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors. diff --git a/packages/angular-cli/tasks/test.ts b/packages/angular-cli/tasks/test.ts index d406df43e0c3..e539c075199a 100644 --- a/packages/angular-cli/tasks/test.ts +++ b/packages/angular-cli/tasks/test.ts @@ -20,6 +20,11 @@ export default Task.extend({ options.browsers = options.browsers.split(','); } + options.angularCli = { + codeCoverage: options.codeCoverage, + lint: options.lint, + }; + // Assign additional karmaConfig options to the local ngapp config options.configFile = karmaConfig; diff --git a/tests/e2e/tests/misc/coverage.ts b/tests/e2e/tests/misc/coverage.ts index 42d4f6e1d805..11af7537a7fb 100644 --- a/tests/e2e/tests/misc/coverage.ts +++ b/tests/e2e/tests/misc/coverage.ts @@ -3,7 +3,7 @@ import {ng} from '../../utils/process'; export default function() { - return ng('test', '--watch=false') + return ng('test', '--watch=false', '--code-coverage') .then(() => expectFileToExist('coverage/src/app')) .then(() => expectFileToExist('coverage/coverage.lcov')); }