Skip to content

Commit

Permalink
feat: use nyc instead of istanbul (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 authored and popomore committed Jun 19, 2017
1 parent 0709d86 commit 3cf312c
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .autod.conf
Expand Up @@ -8,7 +8,7 @@ module.exports = {
'test/fixtures',
],
dep: [
'istanbul',
'nyc',
'mocha',
'co-mocha',
'intelli-espower-loader',
Expand Down
84 changes: 27 additions & 57 deletions lib/cmd/cov.js
Expand Up @@ -3,8 +3,8 @@

const debug = require('debug')('egg-bin:cov');
const path = require('path');
const mkdirp = require('mz-modules/mkdirp');
const rimraf = require('mz-modules/rimraf');
const testExclude = require('test-exclude');

const Command = require('./test');
const EXCLUDES = Symbol('cov#excludes');
Expand All @@ -21,37 +21,23 @@ class CovCommand extends Command {
description: 'istanbul coverage ignore, one or more fileset patterns',
type: 'string',
},
prerequire: {
description: 'prerequire files for coverage instrument',
type: 'boolean',
},
};

// you can add ignore dirs here
this[EXCLUDES] = new Set([
'examples/**',
'mocks_*/**',
]);
].concat(testExclude.defaultExclude));
}

get description() {
return 'Run test with coverage';
}

* run(context) {
const { cwd, argv, execArgv } = context;
const tmpDir = path.join(cwd, '.tmp');
yield mkdirp(tmpDir);

process.env.NODE_ENV = 'test';
process.env.TMPDIR = tmpDir;

if (argv.prerequire) {
process.env.EGG_BIN_PREREQUIRE = 'true';
}
delete argv.prerequire;
const { cwd, argv, execArgv, env } = context;

// istanbul coverage ignore
// ignore coverage
if (argv.x) {
this[EXCLUDES].add(argv.x);
argv.x = undefined;
Expand All @@ -61,29 +47,22 @@ class CovCommand extends Command {
this[EXCLUDES].add(exclude);
}

const covFile = require.resolve('istanbul/lib/cli.js');
const nycCli = require.resolve('nyc/bin/nyc.js');
const coverageDir = path.join(cwd, 'coverage');
yield rimraf(coverageDir);
const outputDir = path.join(cwd, 'node_modules/.nyc_output');
yield rimraf(outputDir);

const opt = {
cwd,
execArgv,
// resolve istanbul path for coffee
env: Object.assign({
istanbul_bin_path: covFile,
}, process.env),
env: Object.assign({ NODE_ENV: 'test' }, env),
};

// save coverage-xxxx.json to $PWD/coverage
const covArgs = this.getCovArgs(context);
debug('covArgs: %j', covArgs);
yield this.helper.forkNode(covFile, covArgs, opt);
yield rimraf(tmpDir);

// create coverage report
const reportArgs = this.getReportArgs(coverageDir);
debug('reportArgs: %j', reportArgs);
yield this.helper.forkNode(covFile, reportArgs, opt);
yield this.helper.forkNode(nycCli, covArgs, opt);
}

/**
Expand All @@ -97,42 +76,33 @@ class CovCommand extends Command {
/**
* get coverage args
* @param {Object} context - { cwd, argv, ...}
* @return {Array} args for istanbul
* @return {Array} args for nyc
* @protected
*/
getCovArgs(context) {
const covArgs = [
'cover',
'--report', 'none',
'--print', 'none',
'--include-pid',
let covArgs = [
// '--show-process-tree',
// instrument all files in nyc process and cache to disk,
// Then in mocha process, read instrumented files from cache.
//
// nyc
// `- egg-bin test
// `- mocha
'--all',
'--temp-directory', './node_modules/.nyc_output',
'-r', 'text-summary',
'-r', 'json-summary',
'-r', 'json',
'-r', 'lcov',
];

for (const exclude of this[EXCLUDES]) {
covArgs.push('-x');
covArgs.push(exclude);
}
const mochaFile = require.resolve('mocha/bin/_mocha');
const testArgs = this.formatTestArgs(context);
debug('testArgs: %j', testArgs);
return covArgs.concat(mochaFile, '--', ...testArgs);
}

/**
* get coverage report args
* @param {String} coverageDir - coverage result directory
* @return {Array} args for istanbul coverage report
* @protected
*/
getReportArgs(coverageDir) {
return [
'report',
'--root', coverageDir,
'text-summary',
'json-summary',
'json',
'lcov',
];
covArgs.push(require.resolve('mocha/bin/_mocha'));
covArgs = covArgs.concat(this.formatTestArgs(context));
return covArgs;
}
}

Expand Down
5 changes: 2 additions & 3 deletions lib/cmd/test.js
Expand Up @@ -37,13 +37,12 @@ class TestCommand extends Command {
}

* run(context) {
process.env.NODE_ENV = 'test';
const testArgs = this.formatTestArgs(context);
const opt = {
env: Object.assign({}, process.env),
env: Object.assign({ NODE_ENV: 'test' }, context.env),
execArgv: context.execArgv,
};
const mochaFile = require.resolve('mocha/bin/_mocha');
const testArgs = this.formatTestArgs(context);
debug('run test: %s %s', mochaFile, testArgs.join(' '));
yield this.helper.forkNode(mochaFile, testArgs, opt);
}
Expand Down
19 changes: 10 additions & 9 deletions package.json
Expand Up @@ -12,27 +12,28 @@
"co-mocha": "^1.2.0",
"common-bin": "^2.4.0",
"debug": "^2.6.8",
"detect-port": "^1.2.0",
"detect-port": "^1.2.1",
"egg-utils": "^2.2.0",
"globby": "^6.1.0",
"intelli-espower-loader": "^1.0.1",
"istanbul": "^1.1.0-alpha.1",
"mocha": "^3.4.2",
"mz-modules": "^1.0.0",
"power-assert": "^1.4.3",
"nyc": "^11.0.2",
"power-assert": "^1.4.4",
"test-exclude": "^4.1.1",
"ypkgfiles": "^1.4.0"
},
"devDependencies": {
"autod": "^2.8.0",
"babel": "^6.3.26",
"babel-preset-airbnb": "^1.0.1",
"babel-register": "^6.4.3",
"coffee": "^3.3.2",
"coffee": "^4.0.0",
"cross-env": "^3.1.3",
"egg-ci": "^1.7.0",
"enzyme": "^2.0.0",
"eslint": "^3.19.0",
"eslint-config-egg": "^4.2.0",
"eslint": "^3.0.0",
"eslint-config-egg": "^4.2.1",
"jsdom": "^8.0.1",
"mm": "^2.1.0",
"mz": "^2.6.0",
Expand All @@ -52,10 +53,10 @@
"author": "fengmk2 <fengmk2@gmail.com> (https://fengmk2.com)",
"scripts": {
"lint": "eslint .",
"pkgfiles": "node ./bin/egg-bin.js pkgfiles --check",
"pkgfiles": "node bin/egg-bin.js pkgfiles --check",
"test": "npm run lint -- --fix && npm run test-local",
"test-local": "node ./bin/egg-bin.js test -t 3600000",
"cov": "node ./bin/egg-bin.js cov -t 3600000",
"test-local": "node bin/egg-bin.js test -t 3600000",
"cov": "nyc -r lcov -r text-summary npm run test-local",
"ci": "npm run lint && npm run pkgfiles && npm run cov",
"autod": "autod"
},
Expand Down
20 changes: 10 additions & 10 deletions test/egg-bin.test.js
Expand Up @@ -10,26 +10,26 @@ describe('test/egg-bin.test.js', () => {
describe('global options', () => {
it('should show version', done => {
coffee.fork(eggBin, [ '--version' ], { cwd })
// .debug()
.expect('stdout', /\d+\.\d+\.\d+/)
.expect('code', 0)
.end(done);
.debug()
.expect('stdout', /\d+\.\d+\.\d+/)
.expect('code', 0)
.end(done);
});

it('should show help', done => {
coffee.fork(eggBin, [ '--help' ], { cwd })
// .debug()
.expect('stdout', /Usage: .*egg-bin.* \[command] \[options]/)
.expect('code', 0)
.end(done);
.expect('stdout', /Usage: .*egg-bin.* \[command] \[options]/)
.expect('code', 0)
.end(done);
});

it('should show help when command not exists', done => {
coffee.fork(eggBin, [ 'not-exists' ], { cwd })
// .debug()
.expect('stdout', /Usage: .*egg-bin.* \[command] \[options]/)
.expect('code', 0)
.end(done);
.expect('stdout', /Usage: .*egg-bin.* \[command] \[options]/)
.expect('code', 0)
.end(done);
});
});
});
37 changes: 4 additions & 33 deletions test/lib/cmd/cov.test.js
Expand Up @@ -14,23 +14,21 @@ describe('test/lib/cmd/cov.test.js', () => {

it('should success', done => {
mm(process.env, 'TESTS', 'test/**/*.test.js');
mm(process.env, 'NYC_CWD', cwd);
coffee.fork(eggBin, [ 'cov' ], { cwd })
.coverage(false)
// .debug()
.expect('stdout', /[\/|\\]test[\/|\\]fixtures[\/|\\]test-files[\/|\\]\.tmp true/)
.expect('stdout', /should success/)
.expect('stdout', /a\.test\.js/)
.expect('stdout', /b[\/|\\]b\.test\.js/)
.notExpect('stdout', /a.js/)
.expect('stdout', /Statements {3}: 80% \( 4[\/|\\]5 \)/)
// .expect('stdout', /Statements {3}: 80% \( 4[\/|\\]5 \)/)
.expect('code', 0)
.end(err => {
assert.ifError(err);
assert.ok(fs.existsSync(path.join(cwd, 'coverage/coverage-final.json')));
assert.ok(fs.existsSync(path.join(cwd, 'coverage/coverage-summary.json')));
assert.ok(fs.existsSync(path.join(cwd, 'coverage/lcov-report/index.html')));
assert.ok(fs.existsSync(path.join(cwd, 'coverage/lcov.info')));
assert.ok(!fs.existsSync(path.join(cwd, '.tmp')));
done();
});
});
Expand All @@ -39,48 +37,41 @@ describe('test/lib/cmd/cov.test.js', () => {
mm(process.env, 'TESTS', 'test/**/*.test.js');
mm(process.env, 'COV_EXCLUDES', 'ignore/*');
yield coffee.fork(eggBin, [ 'cov' ], { cwd })
.coverage(false)
// .debug()
.expect('stdout', /[\/|\\]test[\/|\\]fixtures[\/|\\]test-files[\/|\\]\.tmp true/)
.expect('stdout', /should success/)
.expect('stdout', /a\.test\.js/)
.expect('stdout', /b[\/|\\]b\.test\.js/)
.notExpect('stdout', /a.js/)
.expect('stdout', /Statements {3}: 75% \( 3[\/|\\]4 \)/)
// .expect('stdout', /Statements {3}: 75% \( 3[\/|\\]4 \)/)
.expect('code', 0)
.end();
assert(fs.existsSync(path.join(cwd, 'coverage/coverage-final.json')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov-report/index.html')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov.info')));
assert(!fs.existsSync(path.join(cwd, '.tmp')));
const lcov = fs.readFileSync(path.join(cwd, 'coverage/lcov.info'), 'utf8');
assert(!/ignore[\/|\\]a.js/.test(lcov));
});

it('should success with -x to ignore files', function* () {
yield coffee.fork(eggBin, [ 'cov', '-x', 'ignore/*', 'test/**/*.test.js' ], { cwd })
.coverage(false)
// .debug()
.expect('stdout', /[\/|\\]test[\/|\\]fixtures[\/|\\]test-files[\/|\\]\.tmp true/)
.expect('stdout', /should success/)
.expect('stdout', /a\.test\.js/)
.expect('stdout', /b[\/|\\]b\.test\.js/)
.notExpect('stdout', /a.js/)
.expect('stdout', /Statements {3}: 75% \( 3[\/|\\]4 \)/)
// .expect('stdout', /Statements {3}: 75% \( 3[\/|\\]4 \)/)
.expect('code', 0)
.end();
assert(fs.existsSync(path.join(cwd, 'coverage/coverage-final.json')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov-report/index.html')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov.info')));
assert(!fs.existsSync(path.join(cwd, '.tmp')));
const lcov = fs.readFileSync(path.join(cwd, 'coverage/lcov.info'), 'utf8');
assert(!/ignore[\/|\\]a.js/.test(lcov));
});

it('should fail when test fail', done => {
mm(process.env, 'TESTS', 'test/fail.js');
coffee.fork(eggBin, [ 'cov' ], { cwd })
.coverage(false)
// .debug()
.expect('stdout', /1\) should fail/)
.expect('stdout', /1 failing/)
Expand All @@ -91,7 +82,6 @@ describe('test/lib/cmd/cov.test.js', () => {
it('should fail when test fail with power-assert', done => {
mm(process.env, 'TESTS', 'test/power-assert-fail.js');
coffee.fork(eggBin, [ 'cov' ], { cwd })
.coverage(false)
// .debug()
.expect('stdout', /1\) should fail/)
.expect('stdout', /1 failing/)
Expand All @@ -103,7 +93,6 @@ describe('test/lib/cmd/cov.test.js', () => {
it('should warn when require intelli-espower-loader', done => {
mm(process.env, 'TESTS', 'test/power-assert-fail.js');
coffee.fork(eggBin, [ 'cov', '-r', 'intelli-espower-loader' ], { cwd })
.coverage(false)
// .debug()
.expect('stderr', /manually require `intelli-espower-loader`/)
.expect('stdout', /1\) should fail/)
Expand All @@ -113,29 +102,11 @@ describe('test/lib/cmd/cov.test.js', () => {
.end(done);
});

it('should set EGG_BIN_PREREQUIRE', function* () {
const cwd = path.join(__dirname, '../../fixtures/prerequire');
yield coffee.fork(eggBin, [ 'cov' ], { cwd })
.debug()
.coverage(false)
.expect('stdout', /EGG_BIN_PREREQUIRE undefined/)
.expect('code', 0)
.end();

yield coffee.fork(eggBin, [ 'cov', '--prerequire' ], { cwd })
.debug()
.coverage(false)
.expect('stdout', /EGG_BIN_PREREQUIRE true/)
.expect('code', 0)
.end();
});

it('should run cov when no test files', function* () {
mm(process.env, 'TESTS', 'noexist.js');
const cwd = path.join(__dirname, '../../fixtures/prerequire');
yield coffee.fork(eggBin, [ 'cov' ], { cwd })
// .debug()
.coverage(false)
.expect('code', 0)
.end();
});
Expand Down
8 changes: 4 additions & 4 deletions test/lib/cmd/debug.test.js
Expand Up @@ -47,10 +47,10 @@ describe('test/lib/cmd/debug.test.js', () => {
it('should auto detect available port', done => {
coffee.fork(eggBin, [ 'debug' ], { cwd })
// .debug()
.expect('stdout', /,"workers":1/)
.expect('stderr', /\[egg-bin] server port 7001 is in use/)
.expect('code', 0)
.end(done);
.expect('stdout', /,"workers":1/)
.expect('stderr', /\[egg-bin] server port 7001 is in use/)
.expect('code', 0)
.end(done);
});
});
});

0 comments on commit 3cf312c

Please sign in to comment.