Skip to content

Commit

Permalink
Merge pull request #89 from jamestalmage/recast-forking
Browse files Browse the repository at this point in the history
Fork per test.

Closes #80 
Closes #85
  • Loading branch information
jamestalmage committed Dec 14, 2015
2 parents 36a4b4d + 3eb8cbf commit bec1f9e
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 44 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
coverage
node_modules
!node_modules/spawn-wrap
test/build/
.self_coverage
*.covered.js
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ node_js:
- iojs
env:
- secure: "SVg7NpV0Sru296kdp+eFl07RFjtJy242fWQ1KDCUdk/1EtZEOzBoSKP7Tn3zX/VLBieexL0T31EwYvRztnL97Sr8VgpYU0z95vCPO8FrixElJR6NH3dqrKeNzC3xOYdV0fy2b4UMlPJOI0aYDT1KHm1aWtkb2J8zqII+XbMtlDaelfHCDxa2+RBII9nYYDP62z+0chQFS6MGPSNwve3G2emYHZpYP5iTFmOzaFUCAjLskKvnnsY0jyx5XssqAo17747WKZl5SDgN8YHZIwhE5tB9m9j3MGjJhwdsR3kmq2om0GD1tQFFAXzWhWad3zNBUE4fLqswgASi39o5NIEzvSRzpw77ttOkkIFGem0l421Zi25W8x5n6GZvP06Y47ddmjNBlniwIzG4fb3dbIByCy/g5SjUYmfnke7stXXBKsPv0eEadlLGFWnG5RIfnyGjvUgQ//QXSAnBBzYF9IK+KUdU8c9kHF6kPybsGEzjQoX+4EJL6kZ4sNX9qxjHERUr4Jb6rAMOnKI9VtCBNqwcCC3nV5DDWHS86hKwbuTbBFkszP7majOi0kUQJTO/tZGwVVcphSDwhL5QkmMepLOqXyRICdUcB2ffXHYhZLiZPofYdom8csaDolqFkotJEBj3GM3gwHvUC3i1vxshxtjF6NHjanhpiIpHLRCs6R1RESE="

after_script:
- 'cat ./coverage/lcov.info | ./node_modules/.bin/coveralls'
13 changes: 7 additions & 6 deletions bin/nyc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#!/usr/bin/env node
var foreground = require('foreground-child')
var NYC = require('../')
var NYC
try {
NYC = require('../index.covered.js')
} catch (e) {
NYC = require('../index.js')
}

var path = require('path')
var sw = require('spawn-wrap')

Expand All @@ -9,11 +15,6 @@ if (process.env.NYC_CWD) {
require: process.env.NYC_REQUIRE ? process.env.NYC_REQUIRE.split(',') : []
})).wrap()

// make sure we can run coverage on
// our own index.js, I like turtles.
var name = require.resolve('../')
delete require.cache[name]

sw.runMain()
} else {
var yargs = require('yargs')
Expand Down
22 changes: 22 additions & 0 deletions build-self-coverage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var istanbul = require('istanbul')
var fs = require('fs')
var path = require('path')

;[
'index.js',
'lib/source-map-cache.js'
].forEach(function (name) {
var indexPath = path.join(__dirname, name)
var source = fs.readFileSync(indexPath, 'utf8')

var instrumentor = new istanbul.Instrumenter({
coverageVariable: '___nyc_self_coverage___',
esModules: true,
noAutoWrap: true
})

var instrumentedSource = instrumentor.instrumentSync(source, indexPath)

var outputPath = path.join(__dirname, name.replace(/\.js$/, '.covered.js'))
fs.writeFileSync(outputPath, instrumentedSource)
})
40 changes: 40 additions & 0 deletions build-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict'

var fs = require('fs')
var path = require('path')
var del = require('del')
var mkdirp = require('mkdirp')
var forkingTap = require('forking-tap')
var zeroFill = require('zero-fill')
var sanitizeFilename = require('sanitize-filename')

// Delete previous files.
process.chdir(__dirname)
del.sync(['test/build'])
mkdirp.sync(path.join(__dirname, 'test/build'))

var testDir = path.join(__dirname, 'test/src')
var buildDir = path.join(__dirname, 'test/build')
var originalTestsFilename = path.join(testDir, 'nyc-test.js')
var originalTestSource = fs.readFileSync(originalTestsFilename, 'utf8')
var individualTests = forkingTap(originalTestSource, {
filename: originalTestsFilename,
attachComment: true
})

individualTests.forEach(function (test, i) {
var filename = ['built', zeroFill(3, i)]
.concat(test.nestedName)
.join('-') + '.js'

// file names with spaces are legal, but annoying to use w/ CLI commands
filename = filename.replace(/\s/g, '_')

// istanbul freaks out if the there are `'` characters in the file name
filename = filename.replace(/'/g, '')

// remove any illegal chars
filename = sanitizeFilename(filename)

fs.writeFileSync(path.join(buildDir, filename), test.code)
})
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ var onExit = require('signal-exit')
var stripBom = require('strip-bom')
var SourceMapCache = require('./lib/source-map-cache')

/* istanbul ignore next */
if (/index\.covered\.js$/.test(__filename)) {
require('./lib/self-coverage-helper')
}

function NYC (opts) {
_.extend(this, {
subprocessBin: path.resolve(
Expand Down
20 changes: 20 additions & 0 deletions lib/self-coverage-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* global ___nyc_self_coverage___ */

var path = require('path')
var fs = require('fs')
var mkdirp = require('mkdirp')
var onExit = require('signal-exit')

onExit(function () {
var coverage = global.___nyc_self_coverage___
if (typeof ___nyc_self_coverage___ === 'object') coverage = ___nyc_self_coverage___
if (!coverage) return

var selfCoverageDir = path.join(__dirname, '../.self_coverage')
mkdirp.sync(selfCoverageDir)
fs.writeFileSync(
path.join(selfCoverageDir, process.pid + '.json'),
JSON.stringify(coverage),
'utf-8'
)
})
22 changes: 19 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@
"main": "index.js",
"scripts": {
"pretest": "standard",
"test": "tap --coverage ./test/*.js"
"test": "npm run cover",
"clean": "rm -rf ./.nyc_output ./.self_coverage ./test/fixtures/.nyc_output ./test/build && rm -f *covered.js ./lib/*covered.js",
"build": "node ./build-tests",
"instrument": "node ./build-self-coverage.js",
"run-tests": "tap -b ./test/build/*.js ./test/src/source-map-cache.js",
"report": "istanbul report --include=./.self_coverage/*.json lcov text",
"cover": "npm run clean && npm run build && npm run instrument && npm run run-tests && npm run report",
"dev": "npm run clean && npm run build && npm run run-tests"
},
"bin": {
"nyc": "./bin/nyc.js"
Expand All @@ -17,15 +24,18 @@
"bin",
"coverage",
"test/fixtures/coverage.js",
"test/build/*",
"test/nyc-test.js",
"test/source-map-cache.js",
"index.covered.js",
"test/fixtures/_generateCoverage.js"
]
}
},
"standard": {
"ignore": [
"**/fixtures/**"
"**/fixtures/**",
"**/test/build/*"
]
},
"keywords": [
Expand Down Expand Up @@ -63,10 +73,16 @@
},
"devDependencies": {
"chai": "^3.0.0",
"coveralls": "^2.11.4",
"del": "^2.2.0",
"forking-tap": "^0.1.1",
"sanitize-filename": "^1.5.3",
"sinon": "^1.15.3",
"source-map-fixtures": "^0.2.0",
"source-map-support": "^0.4.0",
"standard": "^5.2.1",
"tap": "^1.3.4"
"tap": "^1.3.4",
"zero-fill": "^2.2.1"
},
"bundleDependencies": [
"spawn-wrap"
Expand Down
70 changes: 39 additions & 31 deletions test/nyc-test.js → test/src/nyc-test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
/* global describe, it */

require('source-map-support').install()
var _ = require('lodash')
var fs = require('fs')
var NYC = require('../')
var NYC

try {
NYC = require('../../index.covered.js')
} catch (e) {
NYC = require('../../')
}

var path = require('path')
var rimraf = require('rimraf')
var sinon = require('sinon')
var spawn = require('child_process').spawn
var fixtures = path.resolve(__dirname, '../fixtures')
var bin = path.resolve(__dirname, '../../bin/nyc')

require('chai').should()
require('tap').mochaGlobals()

describe('nyc', function () {
var fixtures = path.resolve(__dirname, './fixtures')

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

it('sets cwd to process.cwd() if no environment variable is set', function () {
Expand All @@ -28,19 +36,19 @@ describe('nyc', function () {
})

it('uses NYC_CWD environment variable for cwd if it is set', function () {
process.env.NYC_CWD = path.resolve(__dirname, './fixtures')
process.env.NYC_CWD = path.resolve(__dirname, '../fixtures')

var nyc = new NYC()

nyc.cwd.should.equal(path.resolve(__dirname, './fixtures'))
nyc.cwd.should.equal(path.resolve(__dirname, '../fixtures'))
afterEach()
})
})

describe('config', function () {
it("loads 'exclude' patterns from package.json", function () {
var nyc = new NYC({
cwd: path.resolve(__dirname, './fixtures')
cwd: path.resolve(__dirname, '../fixtures')
})

nyc.exclude.length.should.eql(5)
Expand Down Expand Up @@ -107,7 +115,7 @@ describe('nyc', function () {
})
var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

var relPath = '../../nyc/node_modules/glob/glob.js'
var relPath = '../../../nyc/node_modules/glob/glob.js'
var fullPath = '/Users/user/nyc/node_modules/glob/glob.js'

shouldInstrumentFile(fullPath, relPath).should.equal(false)
Expand Down Expand Up @@ -144,11 +152,11 @@ describe('nyc', function () {

// clear the module cache so that
// we pull index.js in again and wrap it.
var name = require.resolve('../')
var name = require.resolve('../../')
delete require.cache[name]

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

Expand All @@ -165,14 +173,14 @@ describe('nyc', function () {

// clear the module cache so that
// we pull index.js in again and wrap it.
var name = require.resolve('../')
var name = require.resolve('../../')
delete require.cache[name]

// install the custom require hook
require.extensions['.js'] = hook

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

// and the hook should have been called
Expand All @@ -182,18 +190,18 @@ describe('nyc', function () {

function testSignal (signal, done) {
var nyc = (new NYC({
cwd: process.cwd()
})).wrap()
cwd: fixtures
}))

var proc = spawn(process.execPath, ['./test/fixtures/' + signal + '.js'], {
cwd: process.cwd(),
env: process.env,
stdio: 'inherit'
var proc = spawn(process.execPath, [bin, './' + signal + '.js'], {
cwd: fixtures,
env: {},
stdio: 'ignore'
})

proc.on('close', function () {
var reports = _.filter(nyc._loadReports(), function (report) {
return report['./test/fixtures/' + signal + '.js']
return report['./' + signal + '.js']
})
reports.length.should.equal(1)
return done()
Expand Down Expand Up @@ -224,14 +232,14 @@ describe('nyc', function () {
describe('report', function () {
it('runs reports for all JSON in output directory', function (done) {
var nyc = new NYC({
cwd: process.cwd()
cwd: fixtures
})
var proc = spawn(process.execPath, ['./test/fixtures/sigint.js'], {
cwd: process.cwd(),
env: process.env,
stdio: 'inherit'

var proc = spawn(process.execPath, [bin, './sigint.js'], {
cwd: fixtures,
env: {},
stdio: 'ignore'
})
var start = fs.readdirSync(nyc.tmpDirectory()).length

proc.on('close', function () {
nyc.report(
Expand All @@ -240,7 +248,7 @@ describe('nyc', function () {
add: function (report) {
// the subprocess we ran should output reports
// for files in the fixtures directory.
Object.keys(report).should.match(/.\/test\/fixtures\//)
Object.keys(report).should.match(/.\/sigint\.js/)
}
},
{
Expand All @@ -251,7 +259,7 @@ describe('nyc', function () {
write: function () {
// we should have output a report for the new subprocess.
var stop = fs.readdirSync(nyc.tmpDirectory()).length
stop.should.be.gt(start)
stop.should.be.eql(1)
return done()
}
}
Expand Down Expand Up @@ -420,15 +428,15 @@ describe('nyc', function () {

it('tracks coverage appropriately once the file is required', function (done) {
var nyc = (new NYC({
cwd: process.cwd()
cwd: fixtures
})).wrap()
require('./fixtures/not-loaded')
require('../fixtures/not-loaded')

nyc.writeCoverageFile()
var reports = _.filter(nyc._loadReports(), function (report) {
return report['./test/fixtures/not-loaded.js']
return report['./not-loaded.js']
})
var report = reports[0]['./test/fixtures/not-loaded.js']
var report = reports[0]['./not-loaded.js']

reports.length.should.equal(1)
report.s['1'].should.equal(1)
Expand Down
Loading

0 comments on commit bec1f9e

Please sign in to comment.