Skip to content

Commit a9bdf0f

Browse files
authored
fix: upgrade to newer versions of source-map, signal-exit, and instrument (#389)
* feat: refactored config to fix precedence of config vs. args see #379 * fix: address standard nits * fix: remove cruft from package.json * fix: upgrade to newer versions of source-map, signal-exit, and instrument (somewhat frightening)
1 parent 99dbbb3 commit a9bdf0f

File tree

6 files changed

+206
-16
lines changed

6 files changed

+206
-16
lines changed

lib/config.js

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
var arrify = require('arrify')
2+
var path = require('path')
3+
var pkgUp = require('pkg-up')
4+
var testExclude = require('test-exclude')
5+
var Yargs = require('yargs/yargs')
6+
7+
// load config from a cascade of sources:
8+
// * command line arguments.
9+
// * package.json.
10+
// * .nycrc (coming soon)
11+
function Config (argv, cwd) {
12+
cwd = cwd || process.env.NYC_CWD || process.cwd()
13+
var pkgPath = pkgUp.sync(cwd)
14+
15+
if (pkgPath) {
16+
cwd = path.dirname(pkgPath)
17+
}
18+
19+
var config = Config.buildYargs(cwd)
20+
.default({
21+
cwd: cwd
22+
})
23+
.parse(argv || [])
24+
25+
// post-hoc, we convert several of the
26+
// configuration settings to arrays, providing
27+
// a consistent contract to index.js.
28+
config.require = arrify(config.require)
29+
config.extension = arrify(config.extension)
30+
config.exclude = arrify(config.exclude)
31+
config.include = arrify(config.include)
32+
config.cwd = cwd
33+
34+
return config
35+
}
36+
37+
// build a yargs object, omitting any settings
38+
// that would cause the application to exit early.
39+
Config.buildYargs = function (cwd) {
40+
return Yargs([])
41+
.usage('$0 [command] [options]\n\nrun your tests with the nyc bin to instrument them with coverage')
42+
.command('report', 'run coverage report for .nyc_output', function (yargs) {
43+
return yargs
44+
.usage('$0 report [options]')
45+
.option('reporter', {
46+
alias: 'r',
47+
describe: 'coverage reporter(s) to use',
48+
default: 'text'
49+
})
50+
.option('report-dir', {
51+
describe: 'directory to output coverage reports in',
52+
default: 'coverage'
53+
})
54+
.option('temp-directory', {
55+
describe: 'directory from which coverage JSON files are read',
56+
default: './.nyc_output'
57+
})
58+
.option('show-process-tree', {
59+
describe: 'display the tree of spawned processes',
60+
default: false,
61+
type: 'boolean'
62+
})
63+
.example('$0 report --reporter=lcov', 'output an HTML lcov report to ./coverage')
64+
})
65+
.command('check-coverage', 'check whether coverage is within thresholds provided', function (yargs) {
66+
return yargs
67+
.usage('$0 check-coverage [options]')
68+
.option('branches', {
69+
default: 0,
70+
description: 'what % of branches must be covered?'
71+
})
72+
.option('functions', {
73+
default: 0,
74+
description: 'what % of functions must be covered?'
75+
})
76+
.option('lines', {
77+
default: 90,
78+
description: 'what % of lines must be covered?'
79+
})
80+
.option('statements', {
81+
default: 0,
82+
description: 'what % of statements must be covered?'
83+
})
84+
.example('$0 check-coverage --lines 95', "check whether the JSON in nyc's output folder meets the thresholds provided")
85+
})
86+
.option('reporter', {
87+
alias: 'r',
88+
describe: 'coverage reporter(s) to use',
89+
default: 'text'
90+
})
91+
.option('report-dir', {
92+
describe: 'directory to output coverage reports in',
93+
default: 'coverage'
94+
})
95+
.option('silent', {
96+
alias: 's',
97+
default: false,
98+
type: 'boolean',
99+
describe: "don't output a report after tests finish running"
100+
})
101+
.option('all', {
102+
alias: 'a',
103+
default: false,
104+
type: 'boolean',
105+
describe: 'whether or not to instrument all files of the project (not just the ones touched by your test suite)'
106+
})
107+
.option('exclude', {
108+
alias: 'x',
109+
default: testExclude.defaultExclude,
110+
describe: 'a list of specific files and directories that should be excluded from coverage, glob patterns are supported, node_modules is always excluded'
111+
})
112+
.option('include', {
113+
alias: 'n',
114+
default: [],
115+
describe: 'a list of specific files that should be covered, glob patterns are supported'
116+
})
117+
.option('require', {
118+
alias: 'i',
119+
default: [],
120+
describe: 'a list of additional modules that nyc should attempt to require in its subprocess, e.g., babel-register, babel-polyfill.'
121+
})
122+
.option('cache', {
123+
alias: 'c',
124+
default: false,
125+
type: 'boolean',
126+
describe: 'cache instrumentation results for improved performance'
127+
})
128+
.option('extension', {
129+
alias: 'e',
130+
default: [],
131+
describe: 'a list of extensions that nyc should handle in addition to .js'
132+
})
133+
.option('check-coverage', {
134+
type: 'boolean',
135+
default: false,
136+
describe: 'check whether coverage is within thresholds provided'
137+
})
138+
.option('branches', {
139+
default: 0,
140+
description: 'what % of branches must be covered?'
141+
})
142+
.option('functions', {
143+
default: 0,
144+
description: 'what % of functions must be covered?'
145+
})
146+
.option('lines', {
147+
default: 90,
148+
description: 'what % of lines must be covered?'
149+
})
150+
.option('statements', {
151+
default: 0,
152+
description: 'what % of statements must be covered?'
153+
})
154+
.option('source-map', {
155+
default: true,
156+
type: 'boolean',
157+
description: 'should nyc detect and handle source maps?'
158+
})
159+
.option('instrument', {
160+
default: true,
161+
type: 'boolean',
162+
description: 'should nyc handle instrumentation?'
163+
})
164+
.option('hook-run-in-context', {
165+
default: true,
166+
type: 'boolean',
167+
description: 'should nyc wrap vm.runInThisContext?'
168+
})
169+
.option('show-process-tree', {
170+
describe: 'display the tree of spawned processes',
171+
default: false,
172+
type: 'boolean'
173+
})
174+
.pkgConf('nyc', cwd || process.cwd())
175+
.example('$0 npm test', 'instrument your tests with coverage')
176+
.example('$0 --require babel-core/register npm test', 'instrument your tests with coverage and babel')
177+
.example('$0 report --reporter=text-lcov', 'output lcov report after running your tests')
178+
.epilog('visit https://git.io/voHar for list of available reporters')
179+
.boolean('help')
180+
.boolean('h')
181+
.boolean('version')
182+
}
183+
184+
// decorate yargs with all the actions
185+
// that would make it exit: help, version, command.
186+
Config.decorateYargs = function (yargs) {
187+
return yargs
188+
.help('h')
189+
.alias('h', 'help')
190+
.version()
191+
.command(require('../lib/commands/instrument'))
192+
}
193+
194+
module.exports = Config

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,17 @@
8383
"glob": "^7.0.6",
8484
"istanbul-lib-coverage": "^1.0.0",
8585
"istanbul-lib-hook": "^1.0.0-alpha.4",
86-
"istanbul-lib-instrument": "^1.1.1",
86+
"istanbul-lib-instrument": "^1.1.3",
8787
"istanbul-lib-report": "^1.0.0-alpha.3",
88-
"istanbul-lib-source-maps": "^1.0.0",
88+
"istanbul-lib-source-maps": "^1.0.1",
8989
"istanbul-reports": "^1.0.0-alpha.8",
9090
"md5-hex": "^1.2.0",
9191
"micromatch": "^2.3.11",
9292
"mkdirp": "^0.5.0",
9393
"pkg-up": "^1.0.0",
9494
"resolve-from": "^2.0.0",
9595
"rimraf": "^2.5.4",
96-
"signal-exit": "^3.0.0",
96+
"signal-exit": "^3.0.1",
9797
"spawn-wrap": "^1.2.4",
9898
"test-exclude": "^2.1.2",
9999
"yargs": "^5.0.0",

test/fixtures/check-instrumented.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ function probe () {}
33
// When instrumented there will be references to variables like
44
// __cov_pwkoI2PYHp3LJXkn_erl1Q in the probe() source.
55
module.exports = function () {
6-
return /\b__cov_\B/.test(probe + '')
6+
return /\bcov_\B/.test(probe + '')
77
}

test/fixtures/conf-multiple-extensions/check-instrumented.es6

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ function probe () {}
33
// When instrumented there will be references to variables like
44
// __cov_pwkoI2PYHp3LJXkn_erl1Q in the probe() source.
55
module.exports = function () {
6-
return /\b__cov_\B/.test(probe + '')
6+
return /\bcov_\B/.test(probe + '')
77
}

test/fixtures/conf-multiple-extensions/check-instrumented.foo.bar

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ function probe () {}
33
// When instrumented there will be references to variables like
44
// __cov_pwkoI2PYHp3LJXkn_erl1Q in the probe() source.
55
module.exports = function () {
6-
return /\b__cov_\B/.test(probe + '')
6+
return /\bcov_\B/.test(probe + '')
77
}

test/src/nyc-test.js

+6-10
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,11 @@ describe('nyc', function () {
6666
describe('config', function () {
6767
it("loads 'exclude' patterns from package.json#nyc", function () {
6868
var nyc = new NYC(configUtil.loadConfig([], path.resolve(__dirname, '../fixtures')))
69-
7069
nyc.exclude.exclude.length.should.eql(4)
7170
})
7271

7372
it("loads 'extension' patterns from package.json#nyc", function () {
7473
var nyc = new NYC(configUtil.loadConfig([], path.resolve(__dirname, '../fixtures/conf-multiple-extensions')))
75-
7674
nyc.extensions.length.should.eql(3)
7775
})
7876

@@ -93,7 +91,6 @@ describe('nyc', function () {
9391

9492
it("ignores 'exclude' option if it's falsy", function () {
9593
var nyc1 = new NYC(configUtil.loadConfig([], path.resolve(__dirname, '../fixtures/conf-empty')))
96-
9794
nyc1.exclude.exclude.length.should.eql(7)
9895
})
9996

@@ -317,8 +314,8 @@ describe('nyc', function () {
317314
var report = reports[0][notLoadedPath]
318315

319316
reports.length.should.equal(1)
317+
report.s['0'].should.equal(0)
320318
report.s['1'].should.equal(0)
321-
report.s['2'].should.equal(0)
322319
return done()
323320
})
324321

@@ -338,12 +335,12 @@ describe('nyc', function () {
338335
reports.length.should.equal(1)
339336

340337
var report1 = reports[0][notLoadedPath1]
338+
report1.s['0'].should.equal(0)
341339
report1.s['1'].should.equal(0)
342-
report1.s['2'].should.equal(0)
343340

344341
var report2 = reports[0][notLoadedPath2]
342+
report2.s['0'].should.equal(0)
345343
report2.s['1'].should.equal(0)
346-
report2.s['2'].should.equal(0)
347344

348345
return done()
349346
})
@@ -364,8 +361,8 @@ describe('nyc', function () {
364361
var report = reports[0][notLoadedPath]
365362

366363
reports.length.should.equal(1)
364+
report.s['0'].should.equal(1)
367365
report.s['1'].should.equal(1)
368-
report.s['2'].should.equal(1)
369366

370367
return done()
371368
})
@@ -378,7 +375,6 @@ describe('nyc', function () {
378375
)
379376

380377
var nyc = (new NYC(configUtil.loadConfig(['--require', './test/fixtures/transpile-hook'], fixtures)))
381-
382378
nyc.reset()
383379
nyc.addAllFiles()
384380

@@ -389,7 +385,7 @@ describe('nyc', function () {
389385
var report = reports[0][needsTranspilePath]
390386

391387
reports.length.should.equal(1)
392-
report.s['1'].should.equal(0)
388+
report.s['0'].should.equal(0)
393389

394390
fs.unlinkSync(needsTranspilePath)
395391
return done()
@@ -418,7 +414,7 @@ describe('nyc', function () {
418414
var report = reports[0][needsTranspilePath]
419415

420416
reports.length.should.equal(1)
421-
report.s['1'].should.equal(0)
417+
report.s['0'].should.equal(0)
422418

423419
fs.unlinkSync(needsTranspilePath)
424420
return done()

0 commit comments

Comments
 (0)