Skip to content

Commit ff17bed

Browse files
committed
Implement --all functionality
Implements an `--all` flag for a src directory to consider for coverage. If supplied, c8 will glob the directory respecting the `--include` and `--exclude` parameters for src files. All source files will be included in the final report. If a file is not found in the v8 coverage output, it will be initialized with an empty v8 record and reported as 0 lines/branches/functions covered. Note: This uses the empty v8 approach instead of the empty report approach Fix html report --all should be boolean Update snapshot fix async function WIP - changing --all a bit to create a fake v8 coverage entry and additional args changes WIP - read source maps for faked entries WIP WIP Moved approach to empty v8 blocks
1 parent d0b2eaa commit ff17bed

23 files changed

+311
-19
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ node_modules
33
.nyc_output
44
coverage
55
tmp
6+
.idea

lib/commands/report.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ exports.outputReport = async function (argv) {
1919
watermarks: argv.watermarks,
2020
resolve: argv.resolve,
2121
omitRelative: argv.omitRelative,
22-
wrapperLength: argv.wrapperLength
22+
wrapperLength: argv.wrapperLength,
23+
all: argv.all
2324
})
2425
await report.run()
2526
if (argv.checkCoverage) checkCoverages(argv, report)

lib/parse-args.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ function buildYargs (withCommands = false) {
8383
type: 'boolean',
8484
describe: 'should temp files be deleted before script execution'
8585
})
86+
.options('all', {
87+
default: false,
88+
type: 'boolean',
89+
describe: 'supplying --all will cause c8 to consider all src files in the current working directory ' +
90+
'when the determining coverage. Respects include/exclude.'
91+
})
8692
.pkgConf('c8')
8793
.config(config)
8894
.demandCommand(1)

lib/report.js

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ const furi = require('furi')
33
const libCoverage = require('istanbul-lib-coverage')
44
const libReport = require('istanbul-lib-report')
55
const reports = require('istanbul-reports')
6-
const { readdirSync, readFileSync } = require('fs')
7-
const { isAbsolute, resolve } = require('path')
6+
const { readdirSync, readFileSync, statSync } = require('fs')
7+
const { isAbsolute, resolve, join, relative, extname, dirname } = require('path')
88
// TODO: switch back to @c88/v8-coverage once patch is landed.
99
const { mergeProcessCovs } = require('@bcoe/v8-coverage')
1010
const v8toIstanbul = require('v8-to-istanbul')
@@ -20,7 +20,8 @@ class Report {
2020
watermarks,
2121
omitRelative,
2222
wrapperLength,
23-
resolve: resolvePaths
23+
resolve: resolvePaths,
24+
all
2425
}) {
2526
this.reporter = reporter
2627
this.reportsDirectory = reportsDirectory
@@ -34,6 +35,8 @@ class Report {
3435
this.omitRelative = omitRelative
3536
this.sourceMapCache = {}
3637
this.wrapperLength = wrapperLength
38+
this.all = all
39+
this.src = process.cwd()
3740
}
3841

3942
async run () {
@@ -57,8 +60,8 @@ class Report {
5760
// use-case.
5861
if (this._allCoverageFiles) return this._allCoverageFiles
5962

63+
const map = libCoverage.createCoverageMap()
6064
const v8ProcessCov = this._getMergedProcessCov()
61-
const map = libCoverage.createCoverageMap({})
6265
const resultCountPerPath = new Map()
6366
const possibleCjsEsmBridges = new Map()
6467

@@ -95,11 +98,14 @@ class Report {
9598
map.merge(converter.toIstanbul())
9699
}
97100
}
98-
99101
this._allCoverageFiles = map
100102
return this._allCoverageFiles
101103
}
102104

105+
relativeToSrc (file) {
106+
return join(this.src, relative(this.src, file))
107+
}
108+
103109
/**
104110
* Returns source-map and fake source file, if cached during Node.js'
105111
* execution. This is used to support tools like ts-node, which transpile
@@ -128,6 +134,29 @@ class Report {
128134
return sources
129135
}
130136

137+
/**
138+
* //TODO: use https://www.npmjs.com/package/convert-source-map
139+
* // no need to roll this ourselves this is already in the dep tree
140+
* https://sourcemaps.info/spec.html
141+
* @param {String} compilation target file
142+
* @returns {String} full path to source map file
143+
* @private
144+
*/
145+
_getSourceMapFromFile (file) {
146+
const fileBody = readFileSync(file).toString()
147+
const sourceMapLineRE = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)\s*$/mg
148+
const results = fileBody.match(sourceMapLineRE)
149+
if (results !== null) {
150+
const sourceMap = results[results.length - 1].split('=')[1]
151+
if (isAbsolute(sourceMap)) {
152+
return sourceMap
153+
} else {
154+
const base = dirname(file)
155+
return join(base, sourceMap)
156+
}
157+
}
158+
}
159+
131160
/**
132161
* Returns the merged V8 process coverage.
133162
*
@@ -139,14 +168,50 @@ class Report {
139168
*/
140169
_getMergedProcessCov () {
141170
const v8ProcessCovs = []
171+
const fileIndex = new Map() // Map<string, bool>
142172
for (const v8ProcessCov of this._loadReports()) {
143173
if (this._isCoverageObject(v8ProcessCov)) {
144174
if (v8ProcessCov['source-map-cache']) {
145175
Object.assign(this.sourceMapCache, v8ProcessCov['source-map-cache'])
146176
}
147-
v8ProcessCovs.push(this._normalizeProcessCov(v8ProcessCov))
177+
v8ProcessCovs.push(this._normalizeProcessCov(v8ProcessCov, fileIndex))
148178
}
149179
}
180+
181+
if (this.all) {
182+
const emptyReports = []
183+
v8ProcessCovs.unshift({
184+
result: emptyReports
185+
})
186+
const workingDir = process.cwd()
187+
this.exclude.globSync(workingDir).forEach((f) => {
188+
const fullPath = resolve(workingDir, f)
189+
if (!fileIndex.has(fullPath)) {
190+
const ext = extname(f)
191+
if (ext === '.js' || ext === '.ts' || ext === '.mjs') {
192+
const stat = statSync(f)
193+
const sourceMap = this._getSourceMapFromFile(f)
194+
if (sourceMap !== undefined) {
195+
this.sourceMapCache[`file://${fullPath}`] = { data: JSON.parse(readFileSync(sourceMap).toString()) }
196+
}
197+
emptyReports.push({
198+
scriptId: 0,
199+
url: resolve(f),
200+
functions: [{
201+
functionName: '(empty-report)',
202+
ranges: [{
203+
startOffset: 0,
204+
endOffset: stat.size,
205+
count: 0
206+
}],
207+
isBlockCoverage: true
208+
}]
209+
})
210+
}
211+
}
212+
})
213+
}
214+
150215
return mergeProcessCovs(v8ProcessCovs)
151216
}
152217

@@ -196,12 +261,13 @@ class Report {
196261
* @return {v8ProcessCov} Normalized V8 process coverage.
197262
* @private
198263
*/
199-
_normalizeProcessCov (v8ProcessCov) {
264+
_normalizeProcessCov (v8ProcessCov, fileIndex) {
200265
const result = []
201266
for (const v8ScriptCov of v8ProcessCov.result) {
202267
if (/^file:\/\//.test(v8ScriptCov.url)) {
203268
try {
204269
v8ScriptCov.url = furi.toSysPath(v8ScriptCov.url)
270+
fileIndex.set(v8ScriptCov.url, true)
205271
} catch (err) {
206272
console.warn(err)
207273
continue

package-lock.json

Lines changed: 9 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"istanbul-reports": "^2.2.6",
4242
"rimraf": "^3.0.0",
4343
"test-exclude": "^5.2.3",
44-
"v8-to-istanbul": "^3.2.6",
44+
"v8-to-istanbul": "git+https://github.com/istanbuljs/v8-to-istanbul.git#empty-report",
4545
"yargs": "^14.0.0",
4646
"yargs-parser": "^15.0.0"
4747
},

test/fixtures/all/ts-compiled/dir/unloaded.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/all/ts-compiled/dir/unloaded.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default function Unloaded(){
2+
return 'Never loaded :('
3+
}
4+
5+
console.log("This file shouldn't have been evaluated")

test/fixtures/all/ts-compiled/loaded.js

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)