Skip to content

Commit

Permalink
wip! use tap.spawn() for each test
Browse files Browse the repository at this point in the history
  • Loading branch information
novemberborn committed Dec 9, 2015
1 parent 2df7abe commit 2221d23
Showing 1 changed file with 116 additions and 58 deletions.
174 changes: 116 additions & 58 deletions test/nyc-test.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,122 @@
/* global describe, it */

var _ = require('lodash')
var fs = require('fs')
var NYC = require('../')
var path = require('path')
var rimraf = require('rimraf')
var sinon = require('sinon')
var spawn = require('child_process').spawn
var tap = require('tap')
var tapMocha = require('tap/lib/mocha')

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'))
// All NYC instances that need to access disk should use fixturesDir as their
// working directory.
var fixturesDir = path.join(__dirname, 'fixtures')
// The instances use a .nyc_output directory within the fixturesDir. This makes
// it easier to clean up the data.
var tempDir = path.join(fixturesDir, '.nyc_output')
// Track all instances created in this process, to be cleaned up when the test
// is done.
var instances = []
// Wrapper to instantiate NYC, forcing the tempDirectory option.
function instantiate (opts) {
opts = _.assign({ tempDirectory: tempDir }, opts)
var nyc = new NYC(opts)
instances.push(nyc)
return nyc
}
// Deletes the .nyc_output directory. Overrides writeCoverageFile() on each
// instance in case it wants to write coverage when the process exits.
function cleanup () {
instances.forEach(function (nyc) {
nyc.writeCoverageFile = function () {}
})
instances = []
rimraf.sync(tempDir)
}

// If set, NYC_TEST_SPAWN contains the index of the test that should be
// executed. Otherwise the test runner should be initialized.
var spawnNthTest = parseInt(process.env.NYC_TEST_SPAWN || '-1', 10)
// Increased after every call to it() below, allows for the current test to be
// executed when in a tap.spawn() process.
var testCounter = 0
// Keep track of the nested tests. Deepest nested test is first.
var stack = [tap.current()]

// describe() and it() adopted from tap's mocha interface.
function describe (name, fn) {
if (spawnNthTest === -1) {
// Initialize the test runner.
var c = stack[0]
if (!fn) {
c.test(name)
} else {
c.test(name, function (tt) {
stack.unshift(tt)
fn()
stack.shift()
tt.end()
})
}
} else if (fn) {
// Execute the function in order to get to the test that needs to be executed.
fn()
}
}

function it (name, fn) {
if (spawnNthTest === -1) {
// Initialize the test runner. It'll have to run the current file through
// tap.spawn(), setting the NYC_TEST_SPAWN variable.
if (fn) {
stack[0].spawn(process.execPath, process.argv.slice(1), { env: { NYC_TEST_SPAWN: testCounter } }, '(in child process)')
} else {
tapMocha.it(name)
}
} else if (spawnNthTest === testCounter) {
// Execute this test.
tapMocha.it(name, function (done) {
try {
if (fn.length) {
fn(function (err) {
cleanup()
done(err)
})
} else {
fn()
cleanup()
done()
}
} catch (err) {
cleanup()
done(err)
}
})
}

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

describe('nyc', function () {
describe('cwd', function () {
it('sets cwd to process.cwd() if no environment variable is set', function () {
var nyc = instantiate()
nyc.cwd.should.eql(process.cwd())
afterEach()
})

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

var nyc = new NYC()
process.env.NYC_CWD = fixturesDir

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

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

nyc.exclude.length.should.eql(5)
})
Expand All @@ -65,7 +140,7 @@ describe('nyc', function () {

describe('shouldInstrumentFile', function () {
it('should exclude appropriately with defaults', function () {
var nyc = new NYC()
var nyc = instantiate()

// Root package contains config.exclude
// Restore exclude to default patterns
Expand All @@ -89,9 +164,7 @@ describe('nyc', function () {
})

it('should exclude appropriately with config.exclude', function () {
var nyc = new NYC({
cwd: fixtures
})
var nyc = instantiate({ cwd: fixturesDir })
var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

// config.excludes: "blarg", "blerg"
Expand All @@ -102,9 +175,7 @@ describe('nyc', function () {
})

it('should handle example symlinked node_module', function () {
var nyc = new NYC({
cwd: fixtures
})
var nyc = instantiate({ cwd: fixturesDir })
var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

var relPath = '../../nyc/node_modules/glob/glob.js'
Expand All @@ -121,7 +192,7 @@ describe('nyc', function () {
})

it('allows a file to be included rather than excluded', function () {
var nyc = new NYC()
var nyc = instantiate()

// Root package contains config.exclude
// Restore exclude to default patterns
Expand All @@ -137,10 +208,7 @@ describe('nyc', function () {

describe('wrap', function () {
it('wraps modules with coverage counters when they are required', function () {
var nyc = new NYC({
cwd: process.cwd()
})
nyc.wrap()
instantiate().wrap()

// clear the module cache so that
// we pull index.js in again and wrap it.
Expand All @@ -158,10 +226,7 @@ describe('nyc', function () {
module._compile(fs.readFileSync(filename, 'utf8'))
})

var nyc = new NYC({
cwd: process.cwd()
})
nyc.wrap()
instantiate().wrap()

// clear the module cache so that
// we pull index.js in again and wrap it.
Expand Down Expand Up @@ -209,9 +274,7 @@ describe('nyc', function () {
})

it('does not output coverage for files that have not been included, by default', function (done) {
var nyc = (new NYC({
cwd: process.cwd()
})).wrap()
var nyc = instantiate().wrap()

var reports = _.filter(nyc._loadReports(), function (report) {
return report['./test/fixtures/not-loaded.js']
Expand Down Expand Up @@ -292,8 +355,8 @@ describe('nyc', function () {
it('handles multiple reporters', function (done) {
var reporters = ['text-summary', 'text-lcov']
var incr = 0
var nyc = new NYC({
cwd: process.cwd(),
var nyc = instantiate({
cwd: fixturesDir,
reporter: reporters
})
var proc = spawn(process.execPath, ['./test/fixtures/sigint.js'], {
Expand Down Expand Up @@ -339,18 +402,14 @@ describe('nyc', function () {

it('it handles having no .istanbul.yml in the root directory', function (done) {
afterEach()
var nyc = new NYC()
nyc.wrap()
instantiate().wrap()
return done()
})

it('uses the values in .istanbul.yml to instantiate the instrumenter', function (done) {
writeConfig()

var nyc = new NYC({
istanbul: istanbul
})
nyc.wrap()
instantiate({ istanbul: istanbul }).wrap()

istanbul.config.loadFile.calledWithMatch('.istanbul.yml').should.equal(true)
istanbul.Instrumenter.calledWith({
Expand All @@ -365,11 +424,10 @@ describe('nyc', function () {
})

it('loads the .istanbul.yml configuration from NYC_CWD', function (done) {
var nyc = new NYC({
instantiate({
istanbul: istanbul,
cwd: './test/fixtures'
})
nyc.wrap()
}).wrap()

istanbul.config.loadFile.calledWithMatch(path.join('test', 'fixtures', '.istanbul.yml')).should.equal(true)
istanbul.Instrumenter.calledWith({
Expand All @@ -396,15 +454,15 @@ describe('nyc', function () {

var yargv = require('yargs').argv

var munged = (new NYC()).mungeArgs(yargv)
var munged = instantiate().mungeArgs(yargv)

munged.should.eql(['node', 'test/nyc-test.js'])
})
})

describe('addAllFiles', function () {
it('outputs an empty coverage report for all files that are not excluded', function (done) {
var nyc = (new NYC())
var nyc = instantiate()
nyc.addAllFiles()

var reports = _.filter(nyc._loadReports(), function (report) {
Expand All @@ -419,16 +477,16 @@ describe('nyc', function () {
})

it('tracks coverage appropriately once the file is required', function (done) {
var nyc = (new NYC({
cwd: process.cwd()
})).wrap()
var nyc = instantiate({
cwd: fixturesDir
}).wrap()
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

0 comments on commit 2221d23

Please sign in to comment.