Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use nyc instead of istanbul #63

Merged
merged 16 commits into from Jun 19, 2017
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
81 changes: 26 additions & 55 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,17 +21,13 @@ 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() {
Expand All @@ -40,18 +36,9 @@ class CovCommand extends Command {

* 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;

// istanbul coverage ignore
// ignore coverage
if (argv.x) {
this[EXCLUDES].add(argv.x);
argv.x = undefined;
Expand All @@ -61,29 +48,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);

process.env.NODE_ENV = 'test';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗯,不应该改变当前进程的,而是改变 mocha 那个进程的 ENV

const opt = {
cwd,
execArgv,
// resolve istanbul path for coffee
env: Object.assign({
istanbul_bin_path: covFile,
}, process.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 +77,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',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the --all flag to include files that have not been required in your tests.

应该不会慢吧?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

就是提前加载文件,没看到加载了额外的文件

'--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));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面可以用 const,然后这里 push(...arr)

return covArgs;
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/cmd/test.js
Expand Up @@ -38,12 +38,12 @@ class TestCommand extends Command {

* run(context) {
process.env.NODE_ENV = 'test';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

const testArgs = this.formatTestArgs(context);
const opt = {
env: Object.assign({}, process.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 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/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个是 bug

.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);
});
});
});