monocart-coverage-reports 2.0.3 → 2.0.5
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 +118 -64
- package/lib/converter/ast.js +1 -0
- package/lib/converter/collect-source-maps.js +23 -58
- package/lib/converter/converter.js +5 -4
- package/lib/converter/find-original-range.js +13 -18
- package/lib/index.js +1 -3
- package/lib/packages/monocart-coverage-v8.js +1 -1
- package/lib/utils/decode-mappings-worker.js +9 -0
- package/lib/utils/decode-mappings.js +24 -38
- package/lib/v8/v8.js +4 -4
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -4,15 +4,31 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/monocart-coverage-reports)
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
> Code coverage tool to generate [V8](https://v8.dev/blog/javascript-code-coverage) or [Istanbul](https://istanbul.js.org/)
|
|
7
|
+
> Code coverage tool to generate native [V8](https://v8.dev/blog/javascript-code-coverage) reports or [Istanbul](https://istanbul.js.org/) reports.
|
|
8
|
+
|
|
9
|
+
* [Preview Reports](#preview-reports)
|
|
10
|
+
* [Usage](#usage)
|
|
11
|
+
* [Default Options](#default-options)
|
|
12
|
+
* [Multiple Reports](#multiple-reports)
|
|
13
|
+
- [V8 reports](#v8-reports)
|
|
14
|
+
- [Istanbul reports](#istanbul-reports)
|
|
15
|
+
* [Multiprocessing Support](#multiprocessing-support)
|
|
16
|
+
* [Compare Reports](#compare-reports)
|
|
17
|
+
* [Compare Workflows](#compare-workflows)
|
|
18
|
+
* [Collecting Istanbul Coverage Data](#collecting-istanbul-coverage-data)
|
|
19
|
+
* [Collecting V8 Coverage Data](#collecting-v8-coverage-data)
|
|
20
|
+
* [Node.js V8 Coverage Report for Server Side](#nodejs-v8-coverage-report-for-server-side)
|
|
21
|
+
* [Using `entryFilter` and `sourceFilter` to filter the results for V8 report](#using-entryfilter-and-sourcefilter-to-filter-the-results-for-v8-report)
|
|
22
|
+
* [How to convert V8 to Istanbul](#how-to-convert-v8-to-istanbul)
|
|
23
|
+
- [Using `v8-to-istanbul`](#using-v8-to-istanbul)
|
|
24
|
+
- [How Monocart Works](#how-monocart-works)
|
|
25
|
+
* [Chromium Coverage API](#chromium-coverage-api)
|
|
26
|
+
* [Istanbul Introduction](#istanbul-introduction)
|
|
27
|
+
* [Thanks](#thanks)
|
|
8
28
|
|
|
9
29
|
## Preview Reports
|
|
10
|
-
- [V8](https://cenfun.github.io/monocart-coverage-reports/v8)
|
|
11
|
-
- [V8
|
|
12
|
-
- [V8 Rollup](https://cenfun.github.io/monocart-coverage-reports/v8-rollup)
|
|
13
|
-
- [V8 lcov.info](https://cenfun.github.io/monocart-coverage-reports/v8/lcov.info)
|
|
14
|
-
- [V8 Node env](https://cenfun.github.io/monocart-coverage-reports/v8-node-env)
|
|
15
|
-
- [V8 Node Inspector](https://cenfun.github.io/monocart-coverage-reports/v8-node-ins)
|
|
30
|
+
- [V8](https://cenfun.github.io/monocart-coverage-reports/v8) - Example for browser, build with webpack, and also [Rollup](https://cenfun.github.io/monocart-coverage-reports/v8-rollup) and [Esbuild](https://cenfun.github.io/monocart-coverage-reports/v8-esbuild)
|
|
31
|
+
- [V8 Node](https://cenfun.github.io/monocart-coverage-reports/v8-node-env) - Example for Node.js using env, and also [V8 API](https://cenfun.github.io/monocart-coverage-reports/v8-node-api), [Inspector](https://cenfun.github.io/monocart-coverage-reports/v8-node-ins) and [CDP](https://cenfun.github.io/monocart-coverage-reports/v8-node-cdp)
|
|
16
32
|
- [V8 Minify](https://cenfun.github.io/monocart-coverage-reports/v8-minify)
|
|
17
33
|
- [V8 to Istanbul](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/istanbul)
|
|
18
34
|
- [Istanbul](https://cenfun.github.io/monocart-coverage-reports/istanbul/)
|
|
@@ -105,7 +121,6 @@ console.log(coverageResults.summary);
|
|
|
105
121
|
## Compare Reports
|
|
106
122
|
| | Istanbul | V8 | V8 to Istanbul |
|
|
107
123
|
| :--------------| :------ | :------ | :---------------------- |
|
|
108
|
-
| Instrumenting code | Required | No | No |
|
|
109
124
|
| Coverage data | Istanbul (Object) | V8 (Array) | V8 (Array) |
|
|
110
125
|
| Output | [Istanbul reports](#istanbul-reports) | [V8 reports](#v8-reports) | [Istanbul reports](#istanbul-reports) |
|
|
111
126
|
| - Bytes | ❌ | ✅ | ❌ |
|
|
@@ -121,70 +136,58 @@ console.log(coverageResults.summary);
|
|
|
121
136
|
|
|
122
137
|
## Compare Workflows
|
|
123
138
|
- Istanbul Workflows
|
|
124
|
-
- 1,
|
|
125
|
-
- 2,
|
|
126
|
-
- 3, Generating coverage report.
|
|
139
|
+
- 1, [Collecting Istanbul coverage data](#collecting-istanbul-coverage-data)
|
|
140
|
+
- 2, Adding coverage data and generating coverage report
|
|
127
141
|
|
|
128
142
|
- V8 Workflows
|
|
129
|
-
- 1,
|
|
130
|
-
-
|
|
131
|
-
- 3, Generating coverage report.
|
|
143
|
+
- 1, [Collecting V8 coverage data](#collecting-v8-coverage-data)
|
|
144
|
+
- 3, Adding coverage data and generating coverage report
|
|
132
145
|
|
|
133
|
-
##
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
- [
|
|
137
|
-
- [
|
|
146
|
+
## Collecting Istanbul Coverage Data
|
|
147
|
+
- Instrumenting source code
|
|
148
|
+
> Before collecting Istanbul coverage data, It requires your source code is instrumented with Istanbul
|
|
149
|
+
- Webpack: [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul), example: [webpack.config-istanbul.js](https://github.com/cenfun/monocart-coverage-reports/blob/main/test/webpack.config-istanbul.js)
|
|
150
|
+
- Rollup: [rollup-plugin-istanbul](https://github.com/artberri/rollup-plugin-istanbul)
|
|
151
|
+
- Vite: [vite-plugin-istanbul](https://github.com/ifaxity/vite-plugin-istanbul)
|
|
152
|
+
- Browser
|
|
153
|
+
> Collecting coverage data from `window.__coverage__`, example: [test-istanbul.js](https://github.com/cenfun/monocart-coverage-reports/blob/main/test/test-istanbul.js)
|
|
154
|
+
- Node.js
|
|
155
|
+
> Collecting coverage data from `global.__coverage__`
|
|
156
|
+
|
|
157
|
+
## Collecting V8 Coverage Data
|
|
158
|
+
- For source code: enable `sourcemap` and do not compress/minify:
|
|
159
|
+
- Webpack: with `source-map` [devtool](https://webpack.js.org/configuration/devtool/) and `development` [mode](https://webpack.js.org/configuration/mode/), example [webpack.config-v8.js](https://github.com/cenfun/monocart-coverage-reports/blob/main/test/webpack.config-v8.js)
|
|
160
|
+
- Rollup: [options](https://rollupjs.org/configuration-options/) `sourcemap: true`
|
|
161
|
+
- Browser (Chromium Only)
|
|
162
|
+
> Collecting coverage data with [Chromium Coverage API](#chromium-coverage-api), see [example](https://github.com/cenfun/monocart-coverage-reports/blob/main/test/test-v8.js)
|
|
163
|
+
- Node.js
|
|
164
|
+
> see [Node.js V8 Coverage Report for Server Side](#nodejs-v8-coverage-report-for-server-side)
|
|
138
165
|
|
|
139
166
|
|
|
140
167
|
## Node.js V8 Coverage Report for Server Side
|
|
141
|
-
There are two ways to collect native V8 coverage data and generate coverage report:
|
|
142
168
|
- Using Node.js env [NODE_V8_COVERAGE](https://nodejs.org/docs/latest/api/cli.html#node_v8_coveragedir)=`dir`
|
|
143
|
-
-
|
|
144
|
-
-
|
|
169
|
+
- Before running your Node.js application, set env `NODE_V8_COVERAGE`=`dir`. After the application runs and exits, the coverage data will be saved to the `dir` directory in JSON file format
|
|
170
|
+
- Read the json file(s) from the `dir` and generate coverage report
|
|
171
|
+
- example:
|
|
145
172
|
> cross-env NODE_V8_COVERAGE=`.temp/v8-coverage` node [./test/test-node-env.js](./test/test-node-env.js) && node [./test/generate-node-report.js](./test/generate-node-report.js)
|
|
146
|
-
|
|
147
|
-
- Using [
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
```
|
|
162
|
-
- 2, Taking coverage data and adding to the report after your application runs.
|
|
163
|
-
```js
|
|
164
|
-
const takeV8Coverage = (session) => {
|
|
165
|
-
return new Promise((resolve) => {
|
|
166
|
-
session.post('Profiler.takePreciseCoverage', (error, coverage) => {
|
|
167
|
-
if (error) {
|
|
168
|
-
console.log(error);
|
|
169
|
-
resolve();
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
resolve(coverage.result);
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
};
|
|
176
|
-
const coverageList = await takeV8Coverage(session);
|
|
177
|
-
// filter node internal files
|
|
178
|
-
coverageList = coverageList.filter((entry) => entry.url && !entry.url.startsWith('node:'));
|
|
179
|
-
await new CoverageReport(coverageOptions).add(coverageList);
|
|
180
|
-
```
|
|
181
|
-
- 3, Generating coverage report. see example: [./test/test-node-ins.js](./test/test-node-ins.js)
|
|
182
|
-
```js
|
|
183
|
-
await new CoverageReport(coverageOptions).generate();
|
|
184
|
-
```
|
|
173
|
+
|
|
174
|
+
- Using [V8](https://nodejs.org/docs/latest/api/v8.html#v8takecoverage) API
|
|
175
|
+
- Writing the coverage started by NODE_V8_COVERAGE to disk on demand with `v8.takeCoverage()` and stopping with `v8.stopCoverage()`.
|
|
176
|
+
- example:
|
|
177
|
+
> cross-env NODE_V8_COVERAGE=`.temp/v8-coverage` node [./test/test-node-api.js](./test/test-node-api.js)
|
|
178
|
+
|
|
179
|
+
- Using [Inspector](https://nodejs.org/docs/latest/api/inspector.html) API (or module [collect-v8-coverage](https://github.com/SimenB/collect-v8-coverage))
|
|
180
|
+
- Connecting to the V8 inspector and enable V8 coverage.
|
|
181
|
+
- Taking coverage data and adding to the report after your application runs.
|
|
182
|
+
- example: [./test/test-node-ins.js](./test/test-node-ins.js)
|
|
183
|
+
|
|
184
|
+
- Using [CDP](https://chromedevtools.github.io/devtools-protocol/) API
|
|
185
|
+
- Enabling [Node Debugging](https://nodejs.org/en/guides/debugging-getting-started/)
|
|
186
|
+
- Collecting coverage data with CDP API.
|
|
187
|
+
- example: [./test/test-node-cdp.js](./test/test-node-cdp.js)
|
|
185
188
|
|
|
186
189
|
## Using `entryFilter` and `sourceFilter` to filter the results for V8 report
|
|
187
|
-
When
|
|
190
|
+
When V8 coverage data collected, it actually contains the data of all entry files, for example:
|
|
188
191
|
```
|
|
189
192
|
1, dist/main.js
|
|
190
193
|
2, dist/vendor.js
|
|
@@ -213,12 +216,63 @@ const coverageOptions = {
|
|
|
213
216
|
};
|
|
214
217
|
```
|
|
215
218
|
|
|
216
|
-
## Istanbul
|
|
219
|
+
## How to convert V8 to Istanbul
|
|
220
|
+
### Using [v8-to-istanbul](https://github.com/istanbuljs/v8-to-istanbul)
|
|
221
|
+
It is a popular library which is used to convert V8 coverage format to istanbul's coverage format. Most test frameworks are using it, such as [Jest](https://github.com/jestjs/jest/), [Vitest](https://github.com/vitest-dev/vitest), but it has two major problems:
|
|
222
|
+
- 1, The source mapping does not work well if the position is between the two consecutive mappings. for example:
|
|
223
|
+
```js
|
|
224
|
+
const a = tf ? 'true' : 'false';
|
|
225
|
+
^ ^ ^
|
|
226
|
+
m1 p m2
|
|
227
|
+
```
|
|
228
|
+
> `m1` and `m2` are two consecutive mappings, `p` is the position we looking for. However, we can only get the position of the `m1` if we don't fix it to `p`. Especially the generated code is different from the original code, such as minified, compressed or converted, then it becomes very difficult to find the middle position between two mappings.
|
|
229
|
+
|
|
230
|
+
- 2, The coverage of functions and branches is incorrect. V8 only provided coverage at functions and it's blocks. But if a function is uncovered (count = 0), there is no information for it's blocks and sub-level functions.
|
|
231
|
+
And also there are some problems about counting the functions and branches:
|
|
232
|
+
```js
|
|
233
|
+
functions.forEach(block => {
|
|
234
|
+
block.ranges.forEach((range, i) => {
|
|
235
|
+
if (block.isBlockCoverage) {
|
|
236
|
+
// v8-to-istanbul: count range as branch here.
|
|
237
|
+
// Problem: not every block is branch, and the first block is actually function.
|
|
238
|
+
if (block.functionName && i === 0) {
|
|
239
|
+
// v8-to-istanbul: count range as function here.
|
|
240
|
+
// Problem: there is no function name if the function is anonymous or expression.
|
|
241
|
+
}
|
|
242
|
+
} else if (block.functionName) {
|
|
243
|
+
// v8-to-istanbul: count range as function here.
|
|
244
|
+
// Problem: same as above function.
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
// Problem: When the function or parent-level function is uncovered, then its sub-level functions will never be counted.
|
|
249
|
+
```
|
|
250
|
+
see source code [v8-to-istanbul.js](https://github.com/istanbuljs/v8-to-istanbul/blob/master/lib/v8-to-istanbul.js)
|
|
251
|
+
|
|
252
|
+
### How Monocart Works
|
|
253
|
+
We have removed `v8-to-istanbul` because of the two major problems and implemented new converter:
|
|
254
|
+
- 1, Trying to fix the middle position if not found the exact mapping.
|
|
255
|
+
- 2, Finding all functions and branches by parsing the source code [AST](https://github.com/acornjs/acorn), however the V8 cannot provide effective branch coverage information, so the branches is still not perfect.
|
|
256
|
+
|
|
257
|
+
| AST | V8 |
|
|
258
|
+
| :--------------| :------ |
|
|
259
|
+
| AssignmentPattern | 🛇 Not Support |
|
|
260
|
+
| ConditionalExpression | ✔ Not Perfect |
|
|
261
|
+
| IfStatement | ✔ Not Perfect |
|
|
262
|
+
| LogicalExpression | ✔ Not Perfect |
|
|
263
|
+
| SwitchStatement | ✔ Not Perfect |
|
|
264
|
+
|
|
265
|
+
## Chromium Coverage API
|
|
266
|
+
- [V8 coverage report](https://v8.dev/blog/javascript-code-coverage) - Native support for JavaScript code coverage to V8. (Chromium only)
|
|
267
|
+
- [Puppeteer Coverage Class](https://pptr.dev/api/puppeteer.coverage)
|
|
268
|
+
- [Playwright Coverage Class](https://playwright.dev/docs/api/class-coverage)
|
|
269
|
+
- [DevTools Protocol for Coverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#method-startPreciseCoverage)
|
|
270
|
+
|
|
271
|
+
## Istanbul Introduction
|
|
217
272
|
- [Istanbul coverage report](https://istanbul.js.org/) - Instrumenting source codes and generating coverage reports
|
|
218
273
|
- [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul)
|
|
219
274
|
- [istanbul-reports](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib)
|
|
220
275
|
- [Code Coverage Introduction](https://docs.cypress.io/guides/tooling/code-coverage)
|
|
221
276
|
|
|
222
|
-
|
|
223
277
|
## Thanks
|
|
224
278
|
- Special thanks to [@edumserrano](https://github.com/edumserrano)
|
package/lib/converter/ast.js
CHANGED
|
@@ -162,6 +162,7 @@ const getJsAstInfo = (item, coverageList) => {
|
|
|
162
162
|
allowReturnOutsideFunction: true,
|
|
163
163
|
allowImportExportEverywhere: true,
|
|
164
164
|
allowSuperOutsideMethod: true,
|
|
165
|
+
allowAwaitOutsideFunction: true,
|
|
165
166
|
// first line: #!/usr/bin/env node
|
|
166
167
|
allowHashBang: true
|
|
167
168
|
};
|
|
@@ -79,56 +79,27 @@ const resolveSourceMap = (data) => {
|
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const concurrency = new Concurrency();
|
|
85
|
-
for (const item of v8list) {
|
|
86
|
-
|
|
87
|
-
const { type, source } = item;
|
|
88
|
-
|
|
89
|
-
// only for js
|
|
90
|
-
if (type === 'js') {
|
|
91
|
-
const converter = convertSourceMap.fromSource(source);
|
|
92
|
-
if (converter) {
|
|
93
|
-
item.sourceMap = resolveSourceMap(converter.sourcemap);
|
|
94
|
-
count += 1;
|
|
95
|
-
// source map comments is inline source map, remove it because it is big
|
|
96
|
-
item.source = convertSourceMap.removeComments(source);
|
|
97
|
-
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
const sourceMapUrl = getSourceMapUrl(source, item.url);
|
|
101
|
-
if (sourceMapUrl) {
|
|
102
|
-
// console.log('========================', sourceMapUrl);
|
|
103
|
-
item.sourceMapUrl = sourceMapUrl;
|
|
104
|
-
concurrency.addItem(item);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
await concurrency.start(async (item) => {
|
|
109
|
-
const data = await loadSourceMap(item.sourceMapUrl);
|
|
110
|
-
if (data) {
|
|
111
|
-
item.sourceMap = resolveSourceMap(data);
|
|
112
|
-
count += 1;
|
|
113
|
-
// source map comments is a link, no need remove
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
return count;
|
|
82
|
+
const saveSourceFile = async (filePath, data) => {
|
|
83
|
+
await Util.writeFile(filePath, JSON.stringify(data));
|
|
118
84
|
};
|
|
119
85
|
|
|
120
|
-
const
|
|
86
|
+
const collectSourceMaps = async (v8list, options) => {
|
|
87
|
+
|
|
121
88
|
let count = 0;
|
|
122
89
|
const concurrency = new Concurrency();
|
|
123
90
|
for (const item of v8list) {
|
|
124
91
|
|
|
125
92
|
const {
|
|
126
|
-
type, url, source,
|
|
93
|
+
type, url, id, source, sourceMap
|
|
127
94
|
} = item;
|
|
128
95
|
|
|
129
|
-
//
|
|
96
|
+
// source and sourceMap will be saved as separated file (could be cached)
|
|
97
|
+
// just keep functions coverage ( could be multiple times, will be merged )
|
|
98
|
+
// so remove source and sourceMap
|
|
130
99
|
delete item.source;
|
|
100
|
+
delete item.sourceMap;
|
|
131
101
|
|
|
102
|
+
// source and sourceMap already saved
|
|
132
103
|
const sourcePath = Util.resolveCacheSourcePath(options.cacheDir, id);
|
|
133
104
|
if (fs.existsSync(sourcePath)) {
|
|
134
105
|
continue;
|
|
@@ -137,18 +108,23 @@ const collectFileSourceMaps = async (v8list, options) => {
|
|
|
137
108
|
const sourceData = {
|
|
138
109
|
url,
|
|
139
110
|
id,
|
|
140
|
-
|
|
111
|
+
// source,
|
|
112
|
+
source: convertSourceMap.removeComments(source),
|
|
113
|
+
// could be existed
|
|
114
|
+
sourceMap
|
|
141
115
|
};
|
|
142
116
|
|
|
143
|
-
// only for js
|
|
144
|
-
if (type === 'js') {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
117
|
+
// check sourceMap only for js
|
|
118
|
+
if (type === 'js' && !sourceData.sourceMap) {
|
|
119
|
+
// from inline sync
|
|
120
|
+
const smc = convertSourceMap.fromSource(source);
|
|
121
|
+
if (smc) {
|
|
122
|
+
sourceData.sourceMap = resolveSourceMap(smc.sourcemap);
|
|
148
123
|
count += 1;
|
|
149
124
|
await saveSourceFile(sourcePath, sourceData);
|
|
150
125
|
continue;
|
|
151
126
|
}
|
|
127
|
+
// from url async
|
|
152
128
|
const sourceMapUrl = getSourceMapUrl(source, item.url);
|
|
153
129
|
if (sourceMapUrl) {
|
|
154
130
|
concurrency.addItem({
|
|
@@ -160,10 +136,12 @@ const collectFileSourceMaps = async (v8list, options) => {
|
|
|
160
136
|
}
|
|
161
137
|
}
|
|
162
138
|
|
|
139
|
+
// no need check sourceMap
|
|
163
140
|
await saveSourceFile(sourcePath, sourceData);
|
|
164
141
|
|
|
165
142
|
}
|
|
166
143
|
|
|
144
|
+
// from url concurrency
|
|
167
145
|
await concurrency.start(async (item) => {
|
|
168
146
|
const sourceData = item.sourceData;
|
|
169
147
|
const data = await loadSourceMap(item.sourceMapUrl);
|
|
@@ -175,19 +153,6 @@ const collectFileSourceMaps = async (v8list, options) => {
|
|
|
175
153
|
});
|
|
176
154
|
|
|
177
155
|
return count;
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
const saveSourceFile = async (filePath, data) => {
|
|
181
|
-
await Util.writeFile(filePath, JSON.stringify(data));
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const collectSourceMaps = (v8list, options, inlineSourceMap) => {
|
|
185
|
-
|
|
186
|
-
if (inlineSourceMap) {
|
|
187
|
-
return collectInlineSourceMaps(v8list);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return collectFileSourceMaps(v8list, options);
|
|
191
156
|
|
|
192
157
|
};
|
|
193
158
|
|
|
@@ -475,7 +475,7 @@ const generateCoverageForDist = (item, state) => {
|
|
|
475
475
|
|
|
476
476
|
// ========================================================================================================
|
|
477
477
|
|
|
478
|
-
const decodeSourceMappings = async (
|
|
478
|
+
const decodeSourceMappings = async (state, originalDecodedMap) => {
|
|
479
479
|
|
|
480
480
|
const generatedLocator = state.locator;
|
|
481
481
|
|
|
@@ -566,7 +566,7 @@ const getOriginalDecodedMappings = (originalDecodedMap, sourceIndex, locator) =>
|
|
|
566
566
|
return decodedMappings;
|
|
567
567
|
};
|
|
568
568
|
|
|
569
|
-
const initOriginalList = (
|
|
569
|
+
const initOriginalList = (state, originalDecodedMap, options) => {
|
|
570
570
|
|
|
571
571
|
// source filter
|
|
572
572
|
let sourceFilter = options.sourceFilter;
|
|
@@ -580,6 +580,7 @@ const initOriginalList = (item, state, originalDecodedMap, options) => {
|
|
|
580
580
|
const originalMap = new Map();
|
|
581
581
|
|
|
582
582
|
const { sources, sourcesContent } = state.sourceMap;
|
|
583
|
+
|
|
583
584
|
sources.forEach((sourcePath, sourceIndex) => {
|
|
584
585
|
|
|
585
586
|
// filter
|
|
@@ -860,12 +861,12 @@ const unpackSourceMap = async (item, state, options) => {
|
|
|
860
861
|
const time_start_decode = Date.now();
|
|
861
862
|
const originalDecodedMap = new Map();
|
|
862
863
|
// for find-original-range
|
|
863
|
-
state.decodedMappings = await decodeSourceMappings(
|
|
864
|
+
state.decodedMappings = await decodeSourceMappings(state, originalDecodedMap);
|
|
864
865
|
// only debug level
|
|
865
866
|
Util.logTime(`decode source mappings: ${sourcePath}`, time_start_decode);
|
|
866
867
|
|
|
867
868
|
// filter original list and init list
|
|
868
|
-
const originalMap = initOriginalList(
|
|
869
|
+
const originalMap = initOriginalList(state, originalDecodedMap, options);
|
|
869
870
|
|
|
870
871
|
originalDecodedMap.clear();
|
|
871
872
|
|
|
@@ -227,11 +227,15 @@ const getOriginalStartPosition = (originalText, generatedText, generatedPos) =>
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// ============================
|
|
230
|
-
//
|
|
231
|
-
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
|
|
230
|
+
// right matched
|
|
231
|
+
|
|
232
|
+
// originalText: "'true' : ",
|
|
233
|
+
// generatedText: '"true" : '
|
|
234
|
+
|
|
235
|
+
const generatedRight = generatedText.slice(generatedPos);
|
|
236
|
+
if (originalText.endsWith(generatedRight)) {
|
|
237
|
+
return originalText.length - generatedRight.length;
|
|
238
|
+
}
|
|
235
239
|
|
|
236
240
|
// ============================
|
|
237
241
|
// starts with original text (few case possible useless)
|
|
@@ -350,7 +354,7 @@ const fixStartColumn = (startMapping, range, state, originalState) => {
|
|
|
350
354
|
|
|
351
355
|
const originalPos = getOriginalStartPosition(originalText, generatedText, generatedPos);
|
|
352
356
|
|
|
353
|
-
// if (originalState.sourcePath.endsWith('
|
|
357
|
+
// if (originalState.sourcePath.endsWith('conditional.js') && range.startOffset === 2153) {
|
|
354
358
|
// console.log('====================================================================');
|
|
355
359
|
// console.log('fix startMapping', originalState.sourcePath);
|
|
356
360
|
// console.log(startMapping);
|
|
@@ -481,12 +485,6 @@ const findStartMapping = (range, state, originalMap) => {
|
|
|
481
485
|
};
|
|
482
486
|
}
|
|
483
487
|
|
|
484
|
-
// if (startMapping.sourceIndex === 1) {
|
|
485
|
-
// console.log('=========================================================');
|
|
486
|
-
// console.log('find next start');
|
|
487
|
-
// console.log(startMapping, nextMapping, range);
|
|
488
|
-
// }
|
|
489
|
-
|
|
490
488
|
// exact and column
|
|
491
489
|
Object.assign(startMapping, nextMapping, {
|
|
492
490
|
exact: true,
|
|
@@ -559,13 +557,10 @@ const findOriginalRange = (range, state, originalMap) => {
|
|
|
559
557
|
const { startMapping, originalState } = startResult;
|
|
560
558
|
|
|
561
559
|
// ==================================================================================
|
|
562
|
-
// if (originalState.sourcePath.endsWith('
|
|
563
|
-
// originalState.
|
|
564
|
-
// console.log('============================================================');
|
|
565
|
-
// console.log(originalState.sourcePath);
|
|
560
|
+
// if (originalState.sourcePath.endsWith('conditional.js') && range.startOffset === 2153) {
|
|
561
|
+
// console.log('============================================================', originalState.sourcePath);
|
|
566
562
|
// console.log(range);
|
|
567
|
-
//
|
|
568
|
-
// originalState.showLog = false;
|
|
563
|
+
// console.log(startMapping);
|
|
569
564
|
// }
|
|
570
565
|
// ==================================================================================
|
|
571
566
|
|
package/lib/index.js
CHANGED
|
@@ -63,9 +63,7 @@ class CoverageReport {
|
|
|
63
63
|
|
|
64
64
|
if (Array.isArray(data)) {
|
|
65
65
|
results.type = 'v8';
|
|
66
|
-
|
|
67
|
-
const inlineSourceMap = false;
|
|
68
|
-
results.data = await initV8ListAndSourcemap(data, this.options, inlineSourceMap);
|
|
66
|
+
results.data = await initV8ListAndSourcemap(data, this.options);
|
|
69
67
|
} else {
|
|
70
68
|
results.type = 'istanbul';
|
|
71
69
|
results.data = data;
|