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

Add baseline switch to nyc instrument command #1261

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions docs/instrument.md
Expand Up @@ -18,6 +18,9 @@ nyc instrument <input> [output]
The `[output]` directory is optional and can be located anywhere, if not set the instrumented code will be sent to `stdout`.
For example, `nyc instrument . ./output` will produce instrumented versions of any source files it finds in `.` and store them in `./output`.

The `--baseline` option will save a baseline coverage file to `<temp-dir>/baseline/coverage.json`.
Include this file when reporting to highlight files with no test coverage.

The `--delete` option will remove the existing output directory before instrumenting.

The `--in-place` option will allow you to run the instrument command.
Expand Down
28 changes: 18 additions & 10 deletions index.js
Expand Up @@ -48,6 +48,7 @@ class NYC {

this.subprocessBin = config.subprocessBin || path.resolve(__dirname, './bin/nyc.js')
this._tempDirectory = config.tempDirectory || config.tempDir || './.nyc_output'
this._baselineDirectoryName = 'baseline'
this._instrumenterLib = require(config.instrumenter || './lib/instrumenters/istanbul')
this._reportDir = config.reportDir || 'coverage'
this._sourceMap = typeof config.sourceMap === 'boolean' ? config.sourceMap : true
Expand Down Expand Up @@ -170,7 +171,7 @@ class NYC {
return source
}

async addAllFiles () {
async addAllFiles (coverageFilename) {
this._loadAdditionalModules()

this.fakeRequire = true
Expand All @@ -190,7 +191,7 @@ class NYC {
})
this.fakeRequire = false

this.writeCoverageFile()
this.writeCoverageFile(coverageFilename)
}

async instrumentAllFiles (input, output) {
Expand Down Expand Up @@ -335,6 +336,10 @@ class NYC {
await mkdirp(this.cacheDirectory)
}

if (this.config.baseline) {
await mkdirp(this.baselineDirectory())
}

await mkdirp(this.processInfo.directory)
}

Expand Down Expand Up @@ -374,26 +379,25 @@ class NYC {
return this
}

writeCoverageFile () {
var coverage = coverageFinder()
writeCoverageFile (filename = this.processInfo.uuid) {
const coverage = coverageFinder()

// Remove any files that should be excluded but snuck into the coverage
Object.keys(coverage).forEach(function (absFile) {
Object.keys(coverage).forEach(absFile => {
if (!this.exclude.shouldInstrument(absFile)) {
delete coverage[absFile]
}
}, this)
})

if (this.cache) {
Object.keys(coverage).forEach(function (absFile) {
Object.keys(coverage).forEach(absFile => {
if (this.hashCache[absFile] && coverage[absFile]) {
coverage[absFile].contentHash = this.hashCache[absFile]
}
}, this)
})
}

var id = this.processInfo.uuid
var coverageFilename = path.resolve(this.tempDirectory(), id + '.json')
const coverageFilename = path.resolve(this.tempDirectory(), `${filename}.json`)

fs.writeFileSync(
coverageFilename,
Expand Down Expand Up @@ -516,6 +520,10 @@ class NYC {
return path.resolve(this.cwd, this._tempDirectory)
}

baselineDirectory () {
return path.resolve(this.cwd, this._tempDirectory, this._baselineDirectoryName)
}

reportDirectory () {
return path.resolve(this.cwd, this._reportDir)
}
Expand Down
9 changes: 9 additions & 0 deletions lib/commands/instrument.js
Expand Up @@ -59,5 +59,14 @@ exports.handler = cliWrapper(async argv => {
})
}

if (argv.baseline) {
if (argv.clean) {
await nyc.reset()
} else {
await nyc.createTempDirectory()
}
await nyc.addAllFiles('baseline/coverage')
}

await nyc.instrumentAllFiles(argv.input, argv.output)
})
49 changes: 49 additions & 0 deletions test/instrument.js
Expand Up @@ -353,3 +353,52 @@ t.test('aborts if trying to clean outside working directory', async t => {
t.strictEqual(status, 1)
t.match(stderr, /attempt to delete/)
})

t.test('can produce baseline coverage if `--baseline` is set', async t => {
const { status } = await runNYC({
args: [
'instrument',
'--baseline',
'./input-dir',
'./output-dir'
],
cwd: subdir
})

t.strictEqual(status, 0)
const target = path.resolve(subdir, 'output-dir', 'index.js')
t.match(await fs.readFile(target, 'utf8'), /console.log\('Hello, World!'\)/)
const baseline = path.resolve(fixturesCLI, '.nyc_output', 'baseline', 'coverage.json')
t.match(await fs.readFile(baseline, 'utf8'), /statementMap/)
})

t.test('can skip cleaning if `--no-clean` is set during baseline', async t => {
const args = [
'instrument',
'--baseline',
'./input-dir',
'./output-dir'
]
const cwd = subdir

const { status: cleanStatus } = await runNYC({ args, cwd })

t.strictEqual(cleanStatus, 0)
const target = path.resolve(subdir, 'output-dir', 'index.js')
t.match(await fs.readFile(target, 'utf8'), /console.log\('Hello, World!'\)/)
const baseline = path.resolve(fixturesCLI, '.nyc_output', 'baseline', 'coverage.json')
t.match(await fs.readFile(baseline, 'utf8'), /statementMap/)

args.splice(2, 0, '--no-clean')
const { status: noCleanStatus } = await runNYC({ args, cwd })

t.strictEqual(noCleanStatus, 0)

const baselineDir = path.resolve(fixturesCLI, '.nyc_output', 'baseline')
const processinfoDir = path.resolve(fixturesCLI, '.nyc_output', 'processinfo')

const baselineFiles = await fs.readdir(baselineDir)
const processinfoFiles = await fs.readdir(processinfoDir)
t.equal(baselineFiles.length, 1)
t.equal(processinfoFiles.length, 2)
})