c8 9.1.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/lib/commands/report.js +2 -1
- package/lib/parse-args.js +5 -0
- package/lib/report.js +141 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -43,6 +43,7 @@ Here is a list of common options. Run `c8 --help` for the full list and document
|
|
|
43
43
|
| `--per-file` | check thresholds per file | `boolean` | `false` |
|
|
44
44
|
| `--temp-directory` | directory V8 coverage data is written to and read from | `string` | `process.env.NODE_V8_COVERAGE` |
|
|
45
45
|
| `--clean` | should temp files be deleted before script execution | `boolean` | `true` |
|
|
46
|
+
| `--experimental-monocart` | see [section below](#using-monocart-coverage-reports-experimental) for more info | `boolean` | `false` |
|
|
46
47
|
|
|
47
48
|
## Checking for "full" source coverage using `--all`
|
|
48
49
|
|
|
@@ -119,6 +120,23 @@ The `--100` flag can be set for the `check-coverage` as well:
|
|
|
119
120
|
c8 check-coverage --100
|
|
120
121
|
```
|
|
121
122
|
|
|
123
|
+
## Using Monocart coverage reports (experimental)
|
|
124
|
+
Monocart is an alternate library for outputting [v8 code coverage](https://v8.dev/blog/javascript-code-coverage) data as Istanbul reports.
|
|
125
|
+
|
|
126
|
+
Monocart also provides reporters based directly on v8's byte-offset-based output. Such as, `console-details` and `v8`. This removes a complex transformation step and may be less bug prone for some environments.
|
|
127
|
+
|
|
128
|
+
**Example usage:**
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
c8 --experimental-monocart --reporter=v8 --reporter=console-details node foo.js
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
NOTE: Monocart requires additional `monocart-coverage-reports` to be installed:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
npm i monocart-coverage-reports --save-dev
|
|
138
|
+
```
|
|
139
|
+
|
|
122
140
|
## Ignoring Uncovered Lines, Functions, and Blocks
|
|
123
141
|
|
|
124
142
|
Sometimes you might find yourself wanting to ignore uncovered portions of your
|
package/lib/commands/report.js
CHANGED
|
@@ -36,7 +36,8 @@ exports.outputReport = async function (argv) {
|
|
|
36
36
|
src: argv.src,
|
|
37
37
|
skipFull: argv.skipFull,
|
|
38
38
|
excludeNodeModules: argv.excludeNodeModules,
|
|
39
|
-
mergeAsync: argv.mergeAsync
|
|
39
|
+
mergeAsync: argv.mergeAsync,
|
|
40
|
+
monocartArgv: (argv.experimentalMonocart || process.env.EXPERIMENTAL_MONOCART) ? argv : null
|
|
40
41
|
})
|
|
41
42
|
await report.run()
|
|
42
43
|
if (argv.checkCoverage) await checkCoverages(argv, report)
|
package/lib/parse-args.js
CHANGED
|
@@ -158,6 +158,11 @@ function buildYargs (withCommands = false) {
|
|
|
158
158
|
describe: 'supplying --merge-async will merge all v8 coverage reports asynchronously and incrementally. ' +
|
|
159
159
|
'This is to avoid OOM issues with Node.js runtime.'
|
|
160
160
|
})
|
|
161
|
+
.option('experimental-monocart', {
|
|
162
|
+
default: false,
|
|
163
|
+
type: 'boolean',
|
|
164
|
+
describe: 'Use Monocart coverage reports'
|
|
165
|
+
})
|
|
161
166
|
.pkgConf('c8')
|
|
162
167
|
.demandCommand(1)
|
|
163
168
|
.check((argv) => {
|
package/lib/report.js
CHANGED
|
@@ -36,7 +36,8 @@ class Report {
|
|
|
36
36
|
allowExternal = false,
|
|
37
37
|
skipFull,
|
|
38
38
|
excludeNodeModules,
|
|
39
|
-
mergeAsync
|
|
39
|
+
mergeAsync,
|
|
40
|
+
monocartArgv
|
|
40
41
|
}) {
|
|
41
42
|
this.reporter = reporter
|
|
42
43
|
this.reporterOptions = reporterOptions || {}
|
|
@@ -60,6 +61,7 @@ class Report {
|
|
|
60
61
|
this.src = this._getSrc(src)
|
|
61
62
|
this.skipFull = skipFull
|
|
62
63
|
this.mergeAsync = mergeAsync
|
|
64
|
+
this.monocartArgv = monocartArgv
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
_getSrc (src) {
|
|
@@ -73,6 +75,9 @@ class Report {
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
async run () {
|
|
78
|
+
if (this.monocartArgv) {
|
|
79
|
+
return this.runMonocart()
|
|
80
|
+
}
|
|
76
81
|
const context = libReport.createContext({
|
|
77
82
|
dir: this.reportsDirectory,
|
|
78
83
|
watermarks: this.watermarks,
|
|
@@ -89,6 +94,141 @@ class Report {
|
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
|
|
97
|
+
async importMonocart () {
|
|
98
|
+
return import('monocart-coverage-reports')
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async getMonocart () {
|
|
102
|
+
let MCR
|
|
103
|
+
try {
|
|
104
|
+
MCR = await this.importMonocart()
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.error('--experimental-monocart requires the plugin monocart-coverage-reports. Run: "npm i monocart-coverage-reports --save-dev"')
|
|
107
|
+
process.exit(1)
|
|
108
|
+
}
|
|
109
|
+
return MCR
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async runMonocart () {
|
|
113
|
+
const MCR = await this.getMonocart()
|
|
114
|
+
if (!MCR) {
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const argv = this.monocartArgv
|
|
119
|
+
const exclude = this.exclude
|
|
120
|
+
|
|
121
|
+
function getEntryFilter () {
|
|
122
|
+
return argv.entryFilter || argv.filter || function (entry) {
|
|
123
|
+
return exclude.shouldInstrument(fileURLToPath(entry.url))
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function getSourceFilter () {
|
|
128
|
+
return argv.sourceFilter || argv.filter || function (sourcePath) {
|
|
129
|
+
if (argv.excludeAfterRemap) {
|
|
130
|
+
// console.log(sourcePath)
|
|
131
|
+
return exclude.shouldInstrument(sourcePath)
|
|
132
|
+
}
|
|
133
|
+
return true
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getReports () {
|
|
138
|
+
const reports = Array.isArray(argv.reporter) ? argv.reporter : [argv.reporter]
|
|
139
|
+
const reporterOptions = argv.reporterOptions || {}
|
|
140
|
+
|
|
141
|
+
return reports.map((reportName) => {
|
|
142
|
+
const reportOptions = {
|
|
143
|
+
...reporterOptions[reportName]
|
|
144
|
+
}
|
|
145
|
+
if (reportName === 'text') {
|
|
146
|
+
reportOptions.skipEmpty = false
|
|
147
|
+
reportOptions.skipFull = argv.skipFull
|
|
148
|
+
reportOptions.maxCols = process.stdout.columns || 100
|
|
149
|
+
}
|
|
150
|
+
return [reportName, reportOptions]
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// --all: add empty coverage for all files
|
|
155
|
+
function getAllOptions () {
|
|
156
|
+
if (!argv.all) {
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const src = argv.src
|
|
161
|
+
const workingDirs = Array.isArray(src) ? src : (typeof src === 'string' ? [src] : [process.cwd()])
|
|
162
|
+
return {
|
|
163
|
+
dir: workingDirs,
|
|
164
|
+
filter: (filePath) => {
|
|
165
|
+
return exclude.shouldInstrument(filePath)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function initPct (summary) {
|
|
171
|
+
Object.keys(summary).forEach(k => {
|
|
172
|
+
if (summary[k].pct === '') {
|
|
173
|
+
summary[k].pct = 100
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
return summary
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// adapt coverage options
|
|
180
|
+
const coverageOptions = {
|
|
181
|
+
logging: argv.logging,
|
|
182
|
+
name: argv.name,
|
|
183
|
+
|
|
184
|
+
reports: getReports(),
|
|
185
|
+
|
|
186
|
+
outputDir: argv.reportsDir,
|
|
187
|
+
baseDir: argv.baseDir,
|
|
188
|
+
|
|
189
|
+
entryFilter: getEntryFilter(),
|
|
190
|
+
sourceFilter: getSourceFilter(),
|
|
191
|
+
|
|
192
|
+
inline: argv.inline,
|
|
193
|
+
lcov: argv.lcov,
|
|
194
|
+
|
|
195
|
+
all: getAllOptions(),
|
|
196
|
+
|
|
197
|
+
clean: argv.clean,
|
|
198
|
+
|
|
199
|
+
// use default value for istanbul
|
|
200
|
+
defaultSummarizer: 'pkg',
|
|
201
|
+
|
|
202
|
+
onEnd: (coverageResults) => {
|
|
203
|
+
// for check coverage
|
|
204
|
+
this._allCoverageFiles = {
|
|
205
|
+
files: () => {
|
|
206
|
+
return coverageResults.files.map(it => it.sourcePath)
|
|
207
|
+
},
|
|
208
|
+
fileCoverageFor: (file) => {
|
|
209
|
+
const fileCoverage = coverageResults.files.find(it => it.sourcePath === file)
|
|
210
|
+
return {
|
|
211
|
+
toSummary: () => {
|
|
212
|
+
return initPct(fileCoverage.summary)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
getCoverageSummary: () => {
|
|
217
|
+
return initPct(coverageResults.summary)
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const coverageReport = new MCR.CoverageReport(coverageOptions)
|
|
223
|
+
coverageReport.cleanCache()
|
|
224
|
+
|
|
225
|
+
// read v8 coverage data from tempDirectory
|
|
226
|
+
await coverageReport.addFromDir(argv.tempDirectory)
|
|
227
|
+
|
|
228
|
+
// generate report
|
|
229
|
+
await coverageReport.generate()
|
|
230
|
+
}
|
|
231
|
+
|
|
92
232
|
async getCoverageMapFromAllCoverageFiles () {
|
|
93
233
|
// the merge process can be very expensive, and it's often the case that
|
|
94
234
|
// check-coverage is called immediately after a report. We memoize the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c8",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"description": "output coverage reports using Node.js' built in coverage",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"istanbul-lib-coverage": "^3.2.0",
|
|
41
41
|
"istanbul-lib-report": "^3.0.1",
|
|
42
42
|
"istanbul-reports": "^3.1.6",
|
|
43
|
-
"test-exclude": "^
|
|
43
|
+
"test-exclude": "^7.0.1",
|
|
44
44
|
"v8-to-istanbul": "^9.0.0",
|
|
45
45
|
"yargs": "^17.7.2",
|
|
46
46
|
"yargs-parser": "^21.1.1"
|
|
@@ -55,8 +55,11 @@
|
|
|
55
55
|
"ts-node": "^10.7.0",
|
|
56
56
|
"typescript": "^5.0.0"
|
|
57
57
|
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"monocart-coverage-reports": "^2.8.3"
|
|
60
|
+
},
|
|
58
61
|
"engines": {
|
|
59
|
-
"node": ">=
|
|
62
|
+
"node": ">=18"
|
|
60
63
|
},
|
|
61
64
|
"files": [
|
|
62
65
|
"index.js",
|