Skip to content

Commit

Permalink
handle more exit codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Coe committed May 12, 2015
1 parent 25fcac7 commit 2611ba4
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 67 deletions.
7 changes: 6 additions & 1 deletion bin/nyc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env node

var NYC = require('../')
var NYC = require('../'),
yargs = require('yargs')
.usage('$0 [file-to-instrument]')
.example('$0 ./node_modules/.bin/mocha', 'run mocha test-suite and output JSON files with coverage information')

;(new NYC()).wrap()

Expand All @@ -17,4 +20,6 @@ if (process.argv[1]) {
delete require('module')._cache[process.argv[1]]
process.argv[1] = require('path').resolve(process.argv[1])
require('module').runMain()
} else {
yargs.showHelp()
}
54 changes: 35 additions & 19 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,41 @@ NYC.prototype._wrapRequire = function () {

module._compile(stripBom(content), filename)
}
}

// ouptut temp coverage reports as processes exit.
process.on('exit', function () {
if (!global.__coverage__) return
NYC.prototype._wrapExit = function () {
var _this = this,
outputCoverage = function (arg) {
if (!global.__coverage__) return

fs.writeFileSync(
path.resolve(_this.tmpDirectory(), './', process.pid + '.json'),
JSON.stringify(global.__coverage__),
'utf-8'
)
fs.writeFileSync(
path.resolve(_this.tmpDirectory(), './', process.pid + '.json'),
JSON.stringify(global.__coverage__),
'utf-8'
)
}

// output temp coverage reports as processes exit.
;['exit', 'SIGTERM', 'SIGINT', 'SIGHUP'].forEach(function (signal) {
process.on(signal, function () {
outputCoverage()
if (signal === 'SIGTERM') process.exit()
})
})
}

NYC.prototype.wrap = function () {
spawnWrap([this.subprocessBin], {NYC_CWD: this.cwd})
this._wrapRequire()
this._wrapExit()
return this
}

NYC.prototype.report = function (_collector, _reporter) {
var _this = this,
collector = _collector || new istanbul.Collector(),
reporter = _reporter || new istanbul.Reporter(),
files = fs.readdirSync(_this.tmpDirectory()),
reports = _.map(files, function (f) {
return JSON.parse(fs.readFileSync(
path.resolve(_this.tmpDirectory(), './', f),
'utf-8'
))
})
var collector = _collector || new istanbul.Collector(),
reporter = _reporter || new istanbul.Reporter()

reports.forEach(function (report) {
this._loadReports().forEach(function (report) {
collector.add(report)
})

Expand All @@ -94,6 +98,18 @@ NYC.prototype.report = function (_collector, _reporter) {
reporter.write(collector, true, function () {})
}

NYC.prototype._loadReports = function () {
var _this = this,
files = fs.readdirSync(this.tmpDirectory())

return _.map(files, function (f) {
return JSON.parse(fs.readFileSync(
path.resolve(_this.tmpDirectory(), './', f),
'utf-8'
))
})
}

NYC.prototype.tmpDirectory = function () {
return path.resolve(this.cwd, './', this.tempDirectory)
}
Expand Down
4 changes: 0 additions & 4 deletions node_modules/spawn-wrap/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
"config": {
"nyc": {
"exclude": [
"node_modules/",
"test/"
"node_modules/"
]
}
},
Expand Down
15 changes: 0 additions & 15 deletions test/fixtures/a.js

This file was deleted.

1 change: 1 addition & 0 deletions test/fixtures/sighup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
process.kill(process.pid, 'SIGHUP')
1 change: 1 addition & 0 deletions test/fixtures/sigint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
process.kill(process.pid, 'SIGINT')
1 change: 1 addition & 0 deletions test/fixtures/sigterm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
process.kill(process.pid, 'SIGTERM')
80 changes: 54 additions & 26 deletions test/nyc-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* global describe, it, afterEach, beforeEach */
/* global describe, it, afterEach, before */

require('chai').should()

var fs = require('fs'),
var _ = require('lodash'),
fs = require('fs'),
spawn = require('child_process').spawn,
NYC = require('../'),
path = require('path'),
Expand All @@ -12,12 +13,13 @@ describe('nyc', function () {
var fixtures = path.resolve(__dirname, './fixtures')

describe('cwd', function () {

afterEach(function () {
delete process.env.NYC_CWD
rimraf.sync(path.resolve(fixtures, './nyc_output'))
})

it('sets cwd to process.cwd() if no environment variable set', function () {
it('sets cwd to process.cwd() if no environment variable is set', function () {
var nyc = new NYC()

nyc.cwd.should.eql(process.cwd())
Expand All @@ -32,8 +34,8 @@ describe('nyc', function () {
})
})

describe('exclude', function () {
it('loads exclude patterns from package.json in cwd', function () {
describe('config', function () {
it("loads 'exclude' patterns from package.json", function () {
var nyc = new NYC({
cwd: path.resolve(__dirname, './fixtures')
})
Expand All @@ -43,24 +45,26 @@ describe('nyc', function () {
})

describe('wrap', function () {
afterEach(function () {
delete global.__coverage__['./a.js']
})
var nyc

it('wraps modules with coverage counters when they are required', function () {
(new NYC({
cwd: path.resolve(__dirname, './fixtures')
before(function () {
nyc = (new NYC({
cwd: process.cwd()
})).wrap()

var A = require('./fixtures/a')
A.should.match(/__cov_/)
})

it('wraps spawn and writes coverage report for subprocesses', function (done) {
(new NYC({
cwd: process.cwd()
})).wrap()
it('wraps modules with coverage counters when they are required', function () {
// clear the module cache so that
// we pull index.js in again and wrap it.
var name = require.resolve('../')
delete require.cache[name]

// when we require index.js it shoudl be wrapped.
var index = require('../')
index.should.match(/__cov_/)
})

it('writes coverage report when process exits', function (done) {
var proc = spawn('./bin/nyc.js', ['index.js'], {
cwd: process.cwd(),
env: process.env,
Expand All @@ -72,18 +76,42 @@ describe('nyc', function () {
return done()
})
})
})

describe('report', function () {
beforeEach(function () {
rimraf.sync(path.resolve(fixtures, './nyc_output'))
function testSignal (signal, done) {
var proc = spawn('./bin/nyc.js', ['./test/fixtures/' + signal + '.js'], {
cwd: process.cwd(),
env: process.env,
stdio: [process.stdin, process.stdout, process.stderr]
})

proc.on('close', function () {
var reports = _.filter(nyc._loadReports(), function (report) {
return report['./test/fixtures/' + signal + '.js']
})
reports.length.should.equal(1)
return done()
})
}

it('writes coverage report when process is killed with SIGTERM', function (done) {
testSignal('sigterm', done)
})

it('writes coverage report when process is killed with SIGHUP', function (done) {
testSignal('sighup', done)
})

it('runs reports for JSON in output directory', function (done) {
it('writes coverage report when process is killed with SIGINT', function (done) {
testSignal('sigint', done)
})
})

describe('report', function () {
it('runs reports for all JSON in output directory', function (done) {
var nyc = new NYC({
cwd: fixtures
}),
proc = spawn('../../bin/nyc.js', ['a.js'], {
proc = spawn('../../bin/nyc.js', ['sigterm.js'], {
cwd: fixtures,
env: process.env,
stdio: [process.stdin, process.stdout, process.stderr]
Expand All @@ -94,8 +122,8 @@ describe('nyc', function () {
{
add: function (report) {
// the subprocess we ran should have created
// a coverage report on ./a.js.
Object.keys(report).should.include('./a.js')
// a coverage report on ./sigterm.js.
Object.keys(report).should.include('./sigterm.js')
}
},
{
Expand Down

0 comments on commit 2611ba4

Please sign in to comment.