Skip to content

Commit

Permalink
chore: 100% coverage (#1195)
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyfarrell committed Oct 7, 2019
1 parent fd40d49 commit 2735ee2
Show file tree
Hide file tree
Showing 17 changed files with 174 additions and 33 deletions.
3 changes: 2 additions & 1 deletion bin/nyc.js
Expand Up @@ -43,6 +43,7 @@ async function main () {
NYC_CWD: process.cwd()
}

/* istanbul ignore else */
if (argv['babel-cache'] === false) {
// babel's cache interferes with some configurations, so is
// disabled by default. opt in by setting babel-cache=true.
Expand Down Expand Up @@ -103,6 +104,6 @@ async function main () {

/* istanbul ignore next: the error branch should be unreachable */
main().catch(error => {
console.log('nyc error:', error)
console.error(error.message)
process.exit(1)
})
6 changes: 2 additions & 4 deletions index.js
Expand Up @@ -48,8 +48,7 @@ function coverageFinder () {

class NYC {
constructor (config) {
config = config || {}
this.config = config
this.config = { ...config }

this.subprocessBin = config.subprocessBin || path.resolve(__dirname, './bin/nyc.js')
this._tempDirectory = config.tempDirectory || config.tempDir || './.nyc_output'
Expand Down Expand Up @@ -151,7 +150,7 @@ class NYC {
compact: this.config.compact,
preserveComments: this.config.preserveComments,
esModules: this.config.esModules,
plugins: this.config.parserPlugins
parserPlugins: this.config.parserPlugins
})
}

Expand Down Expand Up @@ -365,7 +364,6 @@ class NYC {

writeCoverageFile () {
var coverage = coverageFinder()
if (!coverage) return

// Remove any files that should be excluded but snuck into the coverage
Object.keys(coverage).forEach(function (absFile) {
Expand Down
8 changes: 8 additions & 0 deletions lib/commands/instrument.js
@@ -1,6 +1,7 @@
const NYC = require('../../index.js')
const path = require('path')
const { promisify } = require('util')
const resolveFrom = require('resolve-from')
const rimraf = promisify(require('rimraf'))
const { cliWrapper, setupOptions } = require('./helpers.js')

Expand Down Expand Up @@ -49,5 +50,12 @@ exports.handler = cliWrapper(async argv => {
}

const nyc = new NYC(argv)
if (!argv.useSpawnWrap) {
nyc.require.forEach(requireModule => {
const mod = resolveFrom.silent(nyc.cwd, requireModule) || requireModule
require(mod)
})
}

await nyc.instrumentAllFiles(argv.input, argv.output)
})
1 change: 1 addition & 0 deletions lib/fs-promises.js
Expand Up @@ -44,6 +44,7 @@ const fns = [
'writeFile'
]
fns.forEach(fn => {
/* istanbul ignore else: all functions exist on OSX */
if (fs[fn]) {
module.exports[fn] = promisify(fs[fn])
}
Expand Down
5 changes: 1 addition & 4 deletions lib/instrumenters/istanbul.js
Expand Up @@ -5,9 +5,6 @@ function InstrumenterIstanbul (options) {
const convertSourceMap = require('convert-source-map')
const mergeSourceMap = require('merge-source-map')

const { plugins } = options
const configPlugins = plugins ? { plugins } : {}

const instrumenter = createInstrumenter({
autoWrap: true,
coverageVariable: '__coverage__',
Expand All @@ -17,7 +14,7 @@ function InstrumenterIstanbul (options) {
produceSourceMap: options.produceSourceMap,
ignoreClassMethods: options.ignoreClassMethods,
esModules: options.esModules,
...configPlugins
parserPlugins: options.parserPlugins
})

return {
Expand Down
15 changes: 6 additions & 9 deletions lib/wrap.js
@@ -1,9 +1,10 @@
const NYC = require('../index.js')

let config = {}
if (process.env.NYC_CONFIG) {
config = JSON.parse(process.env.NYC_CONFIG)
}
const config = JSON.parse(
process.env.NYC_CONFIG ||
/* istanbul ignore next */ '{}'
)

config.isChildProcess = true

config._processInfo = {
Expand All @@ -18,11 +19,7 @@ if (process.env.NYC_PROCESSINFO_EXTERNAL_ID) {
}

if (process.env.NYC_CONFIG_OVERRIDE) {
const override = JSON.parse(process.env.NYC_CONFIG_OVERRIDE)
config = {
...config,
...override
}
Object.assign(config, JSON.parse(process.env.NYC_CONFIG_OVERRIDE))
process.env.NYC_CONFIG = JSON.stringify(config)
}

Expand Down
22 changes: 22 additions & 0 deletions nyc.config.js
@@ -0,0 +1,22 @@
'use strict'

const isWindows = require('is-windows')()

module.exports = {
exclude: [
'coverage',
'self-coverage',
'test/fixtures/coverage.js',
'test/build/*',
'test/src/*',
'test/nyc.js',
'test/process-args.js',
'test/fixtures/_generateCoverage.js'
],
/* Unknown why we don't get 100% coverage on Windows. */
'check-coverage': !isWindows,
branches: 100,
functions: 100,
lines: 100,
statements: 100
}
13 changes: 0 additions & 13 deletions package.json
Expand Up @@ -22,19 +22,6 @@
"bin/*.js",
"lib/**/*.js"
],
"nyc": {
"exclude": [
"node_modules",
"coverage",
"self-coverage",
"test/fixtures/coverage.js",
"test/build/*",
"test/src/*",
"test/nyc.js",
"test/process-args.js",
"test/fixtures/_generateCoverage.js"
]
},
"standard": {
"ignore": [
"**/fixtures/**",
Expand Down
10 changes: 10 additions & 0 deletions tap-snapshots/test-nyc-integration.js-TAP.test.js
Expand Up @@ -930,6 +930,16 @@ exports[`test/nyc-integration.js TAP reports error if input is not a directory >
`

exports[`test/nyc-integration.js TAP run-in-context provide coverage for vm.runInContext > stdout 1`] = `
---------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
---------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
in-context.js | 100 | 100 | 100 | 100 |
---------------|---------|----------|---------|---------|-------------------
`

exports[`test/nyc-integration.js TAP setting instrument to "false" configures noop instrumenter > must match snapshot 1`] = `
[
[
Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/hooks/run-in-context.js
@@ -0,0 +1,9 @@
'use strict'
const path = require('path')
const vm = require('vm')

vm.runInContext(
'(() => 10)();',
vm.createContext({}),
path.resolve(__dirname, 'in-context.js')
)
4 changes: 4 additions & 0 deletions test/fixtures/nyc.config.js
@@ -0,0 +1,4 @@
'use strict'

// This just blocks fixtures from seeing the root nyc.config.js
module.exports = {}
3 changes: 3 additions & 0 deletions test/fixtures/parser-plugins/no-plugins.json
@@ -0,0 +1,3 @@
{
"parser-plugins": []
}
7 changes: 7 additions & 0 deletions test/fixtures/parser-plugins/package.json
@@ -0,0 +1,7 @@
{
"nyc": {
"parser-plugins": [
"v8intrinsic"
]
}
}
2 changes: 2 additions & 0 deletions test/fixtures/parser-plugins/v8.js
@@ -0,0 +1,2 @@
function fn() {}
%GetOptimizationStatus(fn)
68 changes: 67 additions & 1 deletion test/nyc-integration.js
Expand Up @@ -167,6 +167,16 @@ t.test('hooks provide coverage for requireJS and AMD modules', t => testSuccess(
cwd: path.resolve(__dirname, './fixtures/hooks')
}))

t.test('run-in-context provide coverage for vm.runInContext', t => testSuccess(t, {
args: [
'--hook-run-in-context',
'--hook-require=false',
process.execPath,
'./run-in-context.js'
],
cwd: path.resolve(__dirname, './fixtures/hooks')
}))

t.test('does not interpret args intended for instrumented bin', async t => {
const { status, stderr, stdout } = await runNYC({
tempDir: t.tempDir,
Expand Down Expand Up @@ -215,6 +225,18 @@ t.test('nyc instrument single file to console', async t => {
t.match(originalText.stdout, `path:${JSON.stringify(path.resolve(fixturesCLI, 'half-covered.js'))}`)
})

t.test('nyc instrument disabled instrument', async t => {
const { status, stderr, stdout } = await runNYC({
tempDir: t.tempDir,
args: ['instrument', '--instrument=false', 'half-covered.js']
})

t.is(status, 0)
t.is(stderr, '')
t.match(stdout, 'var a = 0')
t.notMatch(stdout, 'cov_')
})

t.test('nyc instrument a directory of files', async t => {
const { status, stderr, originalText } = await runNYC({
tempDir: t.tempDir,
Expand Down Expand Up @@ -570,7 +592,6 @@ t.test('combines multiple coverage reports', async t => {
})

const mergedCoverage = require('./fixtures/cli/coverage')
console.log(Object.keys(mergedCoverage))
// the combined reports should have 100% function
// branch and statement coverage.
t.strictDeepEqual(
Expand Down Expand Up @@ -600,3 +621,48 @@ t.test('--all instruments unknown extensions as js', t => testSuccess(t, {
cwd: path.resolve(fixturesCLI, '../conf-multiple-extensions'),
args: ['--all', process.execPath, './run.js']
}))

t.test('instrument with invalid --require fails when using node-preload', async t => {
const { status, stderr, stdout } = await runNYC({
tempDir: t.tempDir,
args: [
'--require=@istanbuljs/this-module-does-not-exist',
'instrument',
'./skip-full.js'
]
})

t.is(status, 1)
t.match(stderr, /Cannot find module '@istanbuljs\/this-module-does-not-exist'/)
t.is(stdout, '')
})

t.test('invalid --require fails when using node-preload', async t => {
const { status, stderr, stdout } = await runNYC({
tempDir: t.tempDir,
args: [
'--require=@istanbuljs/this-module-does-not-exist',
'./skip-full.js'
]
})

t.is(status, 1)
t.match(stderr, /Cannot find module '@istanbuljs\/this-module-does-not-exist'/)
t.is(stdout, '')
})

t.test('invalid --require fails when using spawn-wrap', async t => {
const { status, stderr, stdout } = await runNYC({
tempDir: t.tempDir,
args: [
'--use-spawn-wrap=true',
'--require=@istanbuljs/this-module-does-not-exist',
'instrument',
'./skip-full.js'
]
})

t.is(status, 1)
t.match(stderr, /Cannot find module '@istanbuljs\/this-module-does-not-exist'/)
t.is(stdout, '')
})
29 changes: 29 additions & 0 deletions test/parser-plugins.js
@@ -0,0 +1,29 @@
'use strict'

const path = require('path')

const t = require('tap')

const { runNYC } = require('./helpers')

const cwd = path.resolve(__dirname, './fixtures/parser-plugins')

t.test('parser plugin set', async t => {
const { status, stdout, stderr } = await runNYC({
args: ['instrument', 'v8.js'],
cwd
})
t.strictEqual(status, 0)
t.strictEqual(stderr, '')
t.match(stdout, /function cov_/)
})

t.test('parser plugin unset', async t => {
const { status, stdout, stderr } = await runNYC({
args: ['instrument', '--nycrc-path=no-plugins.json', 'v8.js'],
cwd
})
t.strictEqual(status, 0)
t.strictEqual(stderr, '')
t.notMatch(stdout, /function cov_/)
})
2 changes: 1 addition & 1 deletion test/process-args.js
Expand Up @@ -5,7 +5,7 @@ const yargs = require('yargs/yargs')

const processArgs = require('../self-coverage/lib/process-args')

const nycBin = require.resolve('../bin/nyc.js')
const nycBin = require.resolve('../self-coverage/bin/nyc.js')

test('hideInstrumenterArgs removes dashed options that proceed bin', async t => {
process.argv = [
Expand Down

0 comments on commit 2735ee2

Please sign in to comment.