-
Notifications
You must be signed in to change notification settings - Fork 94
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
feat: adds --all functionality #158
Changes from 5 commits
4ffb5c7
99a6601
38199f1
674be8f
9b5763e
65a5453
2156f19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ node_modules | |
.nyc_output | ||
coverage | ||
tmp | ||
.idea |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,16 @@ c8 node foo.js | |
|
||
The above example will output coverage metrics for `foo.js`. | ||
|
||
## Checking for "full" source coverage using `--all` | ||
|
||
By default v8 will only give us coverage for files that were loaded by the engine. If there are source files in your | ||
project that are flexed in production but not in your tests your coverage numbers will not reflect this. For example, | ||
if you your project's `main.js` loads `a.js` and `b.js` but your unit tests only load `a.js` your total coverage | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
could show as `100%` for `a.js` when in fact both `main.js` and `b.js` are uncovered. | ||
|
||
By supplying `--all` to c8 all files in `cwd` obeying the `--include` and `--exclude` flags will be loaded into the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c8, ,obeying....flags, |
||
report. If any of those files remain uncovered they will be factored into the report with a default of 0% coverage. | ||
|
||
## c8 report | ||
|
||
run `c8 report` to regenerate reports after `c8` has already been run. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,9 @@ const furi = require('furi') | |
const libCoverage = require('istanbul-lib-coverage') | ||
const libReport = require('istanbul-lib-report') | ||
const reports = require('istanbul-reports') | ||
const { readdirSync, readFileSync } = require('fs') | ||
const { isAbsolute, resolve } = require('path') | ||
const { readdirSync, readFileSync, statSync } = require('fs') | ||
const { isAbsolute, resolve, extname } = require('path') | ||
const getSourceMapFromFile = require('./source-map-from-file') | ||
// TODO: switch back to @c88/v8-coverage once patch is landed. | ||
const v8toIstanbul = require('v8-to-istanbul') | ||
const isCjsEsmBridgeCov = require('./is-cjs-esm-bridge') | ||
|
@@ -19,7 +20,8 @@ class Report { | |
watermarks, | ||
omitRelative, | ||
wrapperLength, | ||
resolve: resolvePaths | ||
resolve: resolvePaths, | ||
all | ||
}) { | ||
this.reporter = reporter | ||
this.reportsDirectory = reportsDirectory | ||
|
@@ -33,6 +35,8 @@ class Report { | |
this.omitRelative = omitRelative | ||
this.sourceMapCache = {} | ||
this.wrapperLength = wrapperLength | ||
this.all = all | ||
this.src = process.cwd() | ||
} | ||
|
||
async run () { | ||
|
@@ -56,8 +60,8 @@ class Report { | |
// use-case. | ||
if (this._allCoverageFiles) return this._allCoverageFiles | ||
|
||
const map = libCoverage.createCoverageMap() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lost the |
||
const v8ProcessCov = this._getMergedProcessCov() | ||
const map = libCoverage.createCoverageMap({}) | ||
const resultCountPerPath = new Map() | ||
const possibleCjsEsmBridges = new Map() | ||
|
||
|
@@ -94,7 +98,6 @@ class Report { | |
map.merge(converter.toIstanbul()) | ||
} | ||
} | ||
|
||
this._allCoverageFiles = map | ||
return this._allCoverageFiles | ||
} | ||
|
@@ -139,14 +142,50 @@ class Report { | |
_getMergedProcessCov () { | ||
const { mergeProcessCovs } = require('@bcoe/v8-coverage') | ||
const v8ProcessCovs = [] | ||
const fileIndex = new Map() // Map<string, bool> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Scrutinizing this a bit now - this should be a |
||
for (const v8ProcessCov of this._loadReports()) { | ||
if (this._isCoverageObject(v8ProcessCov)) { | ||
if (v8ProcessCov['source-map-cache']) { | ||
Object.assign(this.sourceMapCache, v8ProcessCov['source-map-cache']) | ||
} | ||
v8ProcessCovs.push(this._normalizeProcessCov(v8ProcessCov)) | ||
v8ProcessCovs.push(this._normalizeProcessCov(v8ProcessCov, fileIndex)) | ||
} | ||
} | ||
|
||
if (this.all) { | ||
const emptyReports = [] | ||
v8ProcessCovs.unshift({ | ||
result: emptyReports | ||
}) | ||
const workingDir = process.cwd() | ||
this.exclude.globSync(workingDir).forEach((f) => { | ||
const fullPath = resolve(workingDir, f) | ||
if (!fileIndex.has(fullPath)) { | ||
const ext = extname(f) | ||
if (ext === '.js' || ext === '.ts' || ext === '.mjs') { | ||
const stat = statSync(f) | ||
const sourceMap = getSourceMapFromFile(f) | ||
if (sourceMap !== undefined) { | ||
this.sourceMapCache[`file://${fullPath}`] = { data: JSON.parse(readFileSync(sourceMap).toString()) } | ||
} | ||
emptyReports.push({ | ||
scriptId: 0, | ||
url: resolve(f), | ||
functions: [{ | ||
functionName: '(empty-report)', | ||
ranges: [{ | ||
startOffset: 0, | ||
endOffset: stat.size, | ||
count: 0 | ||
}], | ||
isBlockCoverage: true | ||
}] | ||
}) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
return mergeProcessCovs(v8ProcessCovs) | ||
} | ||
|
||
|
@@ -196,12 +235,13 @@ class Report { | |
* @return {v8ProcessCov} Normalized V8 process coverage. | ||
* @private | ||
*/ | ||
_normalizeProcessCov (v8ProcessCov) { | ||
_normalizeProcessCov (v8ProcessCov, fileIndex) { | ||
const result = [] | ||
for (const v8ScriptCov of v8ProcessCov.result) { | ||
if (/^file:\/\//.test(v8ScriptCov.url)) { | ||
try { | ||
v8ScriptCov.url = furi.toSysPath(v8ScriptCov.url) | ||
fileIndex.set(v8ScriptCov.url, true) | ||
} catch (err) { | ||
console.warn(err) | ||
continue | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const { isAbsolute, join, dirname } = require('path') | ||
const { readFileSync } = require('fs') | ||
/** | ||
* Extract the sourcemap url from a source file | ||
* reference: https://sourcemaps.info/spec.html | ||
* @param {String} file - compilation target file | ||
* @returns {String} full path to source map file | ||
* @private | ||
*/ | ||
function getSourceMapFromFile (file) { | ||
const fileBody = readFileSync(file).toString() | ||
const sourceMapLineRE = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)\s*$/mg | ||
const results = fileBody.match(sourceMapLineRE) | ||
if (results !== null) { | ||
const sourceMap = results[results.length - 1].split('=')[1] | ||
if (isAbsolute(sourceMap)) { | ||
return sourceMap | ||
} else { | ||
const base = dirname(file) | ||
return join(base, sourceMap) | ||
} | ||
} | ||
} | ||
|
||
module.exports = getSourceMapFromFile |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,4 +61,4 @@ | |
"bin", | ||
"LICENSE" | ||
] | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default function Unloaded(){ | ||
return 'Never loaded :(' | ||
} | ||
|
||
console.log("This file shouldn't have been evaluated") |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export default function getString(i){ | ||
if (typeof i === 'number'){ | ||
if (isNaN(i)){ | ||
return 'NaN' | ||
} | ||
else if (i === 0){ | ||
return 'zero' | ||
} | ||
else if (i > 0){ | ||
return 'positive' | ||
} | ||
else { | ||
return 'negative' | ||
} | ||
} | ||
else { | ||
return 'wat?' | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import getString from "./loaded" | ||
console.log(getString(0)) | ||
console.log(getString(1)) | ||
console.log(getString(-1)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default function Unloaded(){ | ||
return 'Never loaded :(' | ||
} | ||
|
||
console.log("This file shouldn't have been evaluated") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export default function getString(i){ | ||
if (typeof i === 'number'){ | ||
if (isNaN(i)){ | ||
return 'NaN' | ||
} | ||
else if (i === 0){ | ||
return 'zero' | ||
} | ||
else if (i > 0){ | ||
return 'positive' | ||
} | ||
else { | ||
return 'negative' | ||
} | ||
} | ||
else { | ||
return 'wat?' | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import getString from "./loaded" | ||
console.log(getString(0)) | ||
console.log(getString(1)) | ||
console.log(getString(-1)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = function Unloaded(){ | ||
return 'Never loaded :(' | ||
} | ||
|
||
console.log("This file shouldn't have been evaluated") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module.exports = function getString(i){ | ||
if (typeof i === 'number'){ | ||
if (isNaN(i)){ | ||
return 'NaN' | ||
} | ||
else if (i === 0){ | ||
return 'zero' | ||
bcoe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
else if (i > 0){ | ||
return 'positive' | ||
} | ||
else { | ||
return 'negative' | ||
} | ||
} | ||
else { | ||
return 'wat?' | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
const loaded = require('./loaded.js'); | ||
console.log(loaded(0)) | ||
console.log(loaded(1)) | ||
console.log(loaded(-1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
your tests,