Skip to content

Commit 3403ca1

Browse files
addaleaxbcoe
authored andcommitted
fix: adds CLI integration testing, where there was no integration testing before.
1 parent 545cf91 commit 3403ca1

File tree

11 files changed

+214
-1
lines changed

11 files changed

+214
-1
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"clean": "rimraf ./.nyc_output ./node_modules/.cache ./.self_coverage ./test/fixtures/.nyc_output ./test/fixtures/node_modules/.cache *covered.js ./lib/*covered.js",
1010
"build": "node ./build-tests",
1111
"instrument": "node ./build-self-coverage.js",
12-
"run-tests": "tap --no-cov -b ./test/build/*.js ./test/src/source-map-cache.js",
12+
"run-tests": "tap --no-cov -b ./test/build/*.js ./test/src/source-map-cache.js ./test/src/nyc-bin.js",
1313
"report": "istanbul report --include=./.self_coverage/*.json lcov text",
1414
"cover": "npm run clean && npm run build && npm run instrument && npm run run-tests && npm run report",
1515
"dev": "npm run clean && npm run build && npm run run-tests",
@@ -106,6 +106,7 @@
106106
"standard": "^6.0.8",
107107
"standard-version": "^1.1.0",
108108
"tap": "^5.7.1",
109+
"which": "^1.2.4",
109110
"zero-fill": "^2.2.3"
110111
},
111112
"repository": {

test/fixtures/cli/fakebin/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node
2+
npm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// shebang gets added before this line
2+
var which = require('which')
3+
var assert = require('assert')
4+
var foreground = require('foreground-child')
5+
6+
// strip first PATH folder
7+
process.env.PATH = process.env.PATH.replace(/^.+?[:;]/, '')
8+
9+
foreground('npm', process.argv.slice(2))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var a = 0
2+
3+
throw new Error
4+
5+
if (a === 0) {
6+
a++;
7+
a--;
8+
a++;
9+
}

test/fixtures/cli/half-covered.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var a = 0
2+
3+
a++
4+
5+
if (a === 0) {
6+
a++;
7+
a--;
8+
a++;
9+
}

test/fixtures/cli/package.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"private": true
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var a = 0
2+
3+
a++
4+
5+
if (a === 0) {
6+
a++;
7+
a--;
8+
a++;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"test": "npm run test:deeper",
5+
"test:deeper": "npm run test:even-deeper",
6+
"test:even-deeper": "node ./half-covered.js"
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var a = 0
2+
3+
a++
4+
5+
if (a === 0) {
6+
a++;
7+
a--;
8+
a++;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"test": "node ./half-covered.js"
5+
}
6+
}

test/src/nyc-bin.js

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/* global describe, it */
2+
3+
var path = require('path')
4+
var fs = require('fs')
5+
var spawn = require('child_process').spawn
6+
var isWindows = require('is-windows')()
7+
var fixturesCLI = path.resolve(__dirname, '../fixtures/cli')
8+
var fakebin = path.resolve(fixturesCLI, 'fakebin')
9+
var bin = path.resolve(__dirname, '../../bin/nyc')
10+
11+
require('chai').should()
12+
require('tap').mochaGlobals()
13+
14+
describe('the nyc cli', function () {
15+
var env = { PATH: process.env.PATH }
16+
17+
describe('--check-coverage', function () {
18+
it('fails when the expected coverage is below a threshold', function (done) {
19+
var args = [bin, '--check-coverage', '--lines', '51', process.execPath, './half-covered.js']
20+
var message = 'ERROR: Coverage for lines (50%) does not meet global threshold (51%)'
21+
22+
var proc = spawn(process.execPath, args, {
23+
cwd: fixturesCLI,
24+
env: env
25+
})
26+
27+
var stderr = ''
28+
proc.stderr.on('data', function (chunk) {
29+
stderr += chunk
30+
})
31+
32+
proc.on('close', function (code) {
33+
code.should.not.equal(0)
34+
stderr.trim().should.equal(message)
35+
done()
36+
})
37+
})
38+
39+
it('succeeds when the expected coverage is above a threshold', function (done) {
40+
var args = [bin, '--check-coverage', '--lines', '49', process.execPath, './half-covered.js']
41+
42+
var proc = spawn(process.execPath, args, {
43+
cwd: fixturesCLI,
44+
env: env
45+
})
46+
47+
proc.on('close', function (code) {
48+
code.should.equal(0)
49+
done()
50+
})
51+
})
52+
53+
// https://github.com/bcoe/nyc/issues/209
54+
it('fails in any case when the underlying test failed', function (done) {
55+
var args = [bin, '--check-coverage', '--lines', '49', process.execPath, './half-covered-failing.js']
56+
57+
var proc = spawn(process.execPath, args, {
58+
cwd: fixturesCLI,
59+
env: env
60+
})
61+
62+
proc.on('close', function (code) {
63+
code.should.not.equal(0)
64+
done()
65+
})
66+
})
67+
})
68+
69+
// https://github.com/bcoe/nyc/issues/190
70+
describe('running "npm test"', function () {
71+
it('can run "npm test" which directly invokes a test file', function (done) {
72+
var args = [bin, 'npm', 'test']
73+
var directory = path.resolve(fixturesCLI, 'run-npm-test')
74+
var proc = spawn(process.execPath, args, {
75+
cwd: directory,
76+
env: env
77+
})
78+
79+
proc.on('close', function (code) {
80+
code.should.equal(0)
81+
done()
82+
})
83+
})
84+
85+
it('can run "npm test" which indirectly invokes a test file', function (done) {
86+
var args = [bin, 'npm', 'test']
87+
var directory = path.resolve(fixturesCLI, 'run-npm-test-recursive')
88+
var proc = spawn(process.execPath, args, {
89+
cwd: directory,
90+
env: env
91+
})
92+
93+
proc.on('close', function (code) {
94+
code.should.equal(0)
95+
done()
96+
})
97+
})
98+
99+
function writeFakeNPM (shebang) {
100+
var targetPath = path.resolve(fakebin, 'npm')
101+
var source = fs.readFileSync(path.resolve(fakebin, 'npm-template.js'))
102+
fs.writeFileSync(targetPath, '#!' + shebang + '\n' + source)
103+
fs.chmodSync(targetPath, 493) // 0o755
104+
}
105+
106+
it('can run "npm test", absolute shebang edition', function (done) {
107+
if (isWindows) return done()
108+
109+
writeFakeNPM(process.execPath)
110+
111+
var args = [bin, 'npm', 'test']
112+
var directory = path.resolve(fixturesCLI, 'run-npm-test-recursive')
113+
var proc = spawn(process.execPath, args, {
114+
cwd: directory,
115+
env: {
116+
PATH: fakebin + ':' + env.PATH
117+
}
118+
})
119+
120+
proc.on('close', function (code) {
121+
code.should.equal(0)
122+
done()
123+
})
124+
})
125+
126+
it('can run "npm test", weird bash+dirname shebang edition', function (done) {
127+
if (isWindows) return done()
128+
129+
// This string is taken verbatim from tools/install.py in Node core v5.x
130+
writeFakeNPM('/bin/sh\n// 2>/dev/null; exec "`dirname "$0"`/node" "$0" "$@"')
131+
fs.symlinkSync(process.execPath, path.resolve(fakebin, 'node'))
132+
133+
var args = [bin, 'npm', 'test']
134+
var directory = path.resolve(fixturesCLI, 'run-npm-test-recursive')
135+
var proc = spawn(process.execPath, args, {
136+
cwd: directory,
137+
env: {
138+
PATH: fakebin + ':' + env.PATH
139+
}
140+
})
141+
142+
proc.on('close', function (code) {
143+
code.should.equal(0)
144+
done()
145+
})
146+
})
147+
})
148+
})

0 commit comments

Comments
 (0)