monocart-coverage-reports 2.9.1 → 2.9.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Monocart Coverage Reports
2
2
 
3
3
  [![](https://img.shields.io/npm/v/monocart-coverage-reports)](https://www.npmjs.com/package/monocart-coverage-reports)
4
- [![](https://badgen.net/npm/dw/monocart-coverage-reports)](https://www.npmjs.com/package/monocart-coverage-reports)
4
+ [![](https://devimg.vercel.app/npm/downloads/monocart-coverage-reports?label={total}%20downloads/month)](https://www.npmjs.com/package/monocart-coverage-reports)
5
5
  ![](https://img.shields.io/librariesio/github/cenfun/monocart-coverage-reports)
6
6
  ![](https://img.shields.io/github/license/cenfun/monocart-coverage-reports)
7
7
  ![](https://img.shields.io/github/actions/workflow/status/cenfun/monocart-coverage-reports/ci.yml)
@@ -585,6 +585,20 @@ const coverageOptions = {
585
585
  }
586
586
  };
587
587
  ```
588
+ Normalize the full path of the file:
589
+ ```js
590
+ const path = require("path")
591
+
592
+ // MCR coverage options
593
+ const coverageOptions = {
594
+ sourcePath: (filePath, info)=> {
595
+ if (!filePath.includes('/') && info.distFile) {
596
+ return `${path.dirname(info.distFile)}/${filePath}`;
597
+ }
598
+ return filePath;
599
+ }
600
+ }
601
+ ```
588
602
 
589
603
  ## Adding Empty Coverage for Untested Files
590
604
  By default the untested files will not be included in the coverage report, we can add empty coverage data for all files with option `all`, the untested files will show 0% coverage.
package/README.zh-Hans.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Monocart Coverage Reports
2
2
 
3
3
  [![](https://img.shields.io/npm/v/monocart-coverage-reports)](https://www.npmjs.com/package/monocart-coverage-reports)
4
- [![](https://badgen.net/npm/dw/monocart-coverage-reports)](https://www.npmjs.com/package/monocart-coverage-reports)
4
+ [![](https://devimg.vercel.app/npm/downloads/monocart-coverage-reports?label={total}%20downloads/month)](https://www.npmjs.com/package/monocart-coverage-reports)
5
5
  ![](https://img.shields.io/librariesio/github/cenfun/monocart-coverage-reports)
6
6
  ![](https://img.shields.io/github/license/cenfun/monocart-coverage-reports)
7
7
  ![](https://img.shields.io/github/actions/workflow/status/cenfun/monocart-coverage-reports/ci.yml)
@@ -588,6 +588,20 @@ const coverageOptions = {
588
588
  }
589
589
  };
590
590
  ```
591
+ 解决文件路径不完整的问题:
592
+ ```js
593
+ const path = require("path")
594
+
595
+ // MCR coverage options
596
+ const coverageOptions = {
597
+ sourcePath: (filePath, info)=> {
598
+ if (!filePath.includes('/') && info.distFile) {
599
+ return `${path.dirname(info.distFile)}/${filePath}`;
600
+ }
601
+ return filePath;
602
+ }
603
+ }
604
+ ```
591
605
 
592
606
  ## Adding Empty Coverage for Untested Files
593
607
  默认,未测试的文件是不会包含到覆盖率报告的,需要使用`all`选项来为这些文件添加一个空的覆盖率,也就是0%
@@ -4,6 +4,7 @@ const EC = require('eight-colors');
4
4
  const { fileURLToPath, pathToFileURL } = require('url');
5
5
  const Concurrency = require('../platform/concurrency.js');
6
6
  const { convertSourceMap } = require('../packages/monocart-coverage-vendor.js');
7
+ const { flattenSourceMaps } = require('./flatten-source-maps.js');
7
8
 
8
9
  const Util = require('../utils/util.js');
9
10
 
@@ -100,27 +101,68 @@ const resolveSourcesContent = (data, url) => {
100
101
  }
101
102
  };
102
103
 
104
+ const checkSourcesContent = (data) => {
105
+ const { sourcesContent, sources } = data;
106
+
107
+ if (!sourcesContent) {
108
+ data.sourcesContent = [];
109
+ return false;
110
+ }
111
+
112
+ // all should be string, could be [null]
113
+ const contents = sourcesContent.filter((content) => typeof content === 'string');
114
+ if (contents.length === sources.length) {
115
+ return true;
116
+ }
117
+
118
+ return false;
119
+ };
120
+
121
+ const resolveSectionedSourceMap = (data, url, sections) => {
122
+
123
+ let hasSourceContent = false;
124
+ sections.forEach((item) => {
125
+ // offset: { line: 1, column: 0 },
126
+ // map: { sources, sourcesContent }
127
+
128
+ const map = item.map;
129
+
130
+ if (checkSourcesContent(map)) {
131
+ hasSourceContent = true;
132
+ return;
133
+ }
134
+
135
+ const done = resolveSourcesContent(map, url);
136
+ if (done) {
137
+ hasSourceContent = true;
138
+ }
139
+
140
+ });
141
+
142
+ if (hasSourceContent) {
143
+ return flattenSourceMaps(data);
144
+ }
145
+ };
146
+
103
147
  const resolveSourceMap = (data, url) => {
104
148
  if (!data) {
105
149
  return;
106
150
  }
107
151
  const {
108
- sources, sourcesContent, mappings
152
+ sections, sources, mappings
109
153
  } = data;
110
154
 
155
+ if (sections) {
156
+ return resolveSectionedSourceMap(data, url, sections);
157
+ }
158
+
111
159
  if (!sources || !mappings) {
112
160
  return;
113
161
  }
114
162
 
115
163
  // check sources content
116
- if (sourcesContent) {
117
- // all should be string, could be [null]
118
- const contents = sourcesContent.filter((content) => typeof content === 'string');
119
- if (contents.length === sources.length) {
120
- return data;
121
- }
122
- } else {
123
- data.sourcesContent = [];
164
+ if (checkSourcesContent(data)) {
165
+ return data;
124
166
  }
125
167
 
126
168
  // load sources content by sources
@@ -841,9 +841,13 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
841
841
 
842
842
  const generatedLocator = state.locator;
843
843
 
844
- const { sources, mappings } = state.sourceMap;
844
+ const {
845
+ sources, mappings, decodedMappings
846
+ } = state.sourceMap;
847
+
848
+ const decodedList = decodedMappings || decode(mappings);
845
849
 
846
- const decodedList = decode(mappings);
850
+ // console.log(decodedList);
847
851
 
848
852
  sources.forEach((source, i) => {
849
853
  originalDecodedMap.set(i, []);
@@ -0,0 +1,166 @@
1
+ const { decode } = require('@jridgewell/sourcemap-codec');
2
+
3
+ function getLine(arr, index) {
4
+ for (let i = arr.length; i <= index; i++) {
5
+ arr[i] = [];
6
+ }
7
+ return arr[index];
8
+ }
9
+
10
+ function addMappings(options, sourcesOffset) {
11
+
12
+ const {
13
+ input,
14
+ lineOffset,
15
+ columnOffset,
16
+ stopLine,
17
+ stopColumn
18
+ } = options;
19
+
20
+ const decoded = decode(input.mappings);
21
+ const COLUMN = 0;
22
+ const SOURCES_INDEX = 1;
23
+ const SOURCE_LINE = 2;
24
+ const SOURCE_COLUMN = 3;
25
+
26
+ for (let i = 0; i < decoded.length; i++) {
27
+ const lineI = lineOffset + i;
28
+
29
+ if (lineI > stopLine) {
30
+ return;
31
+ }
32
+
33
+ const out = getLine(options.decodedMappings, lineI);
34
+ const cOffset = i === 0 ? columnOffset : 0;
35
+
36
+ const line = decoded[i];
37
+ for (let j = 0; j < line.length; j++) {
38
+ const seg = line[j];
39
+ const column = cOffset + seg[COLUMN];
40
+
41
+ if (lineI === stopLine && column >= stopColumn) {
42
+ return;
43
+ }
44
+
45
+ if (seg.length === 1) {
46
+ out.push([column]);
47
+ continue;
48
+ }
49
+
50
+ const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX];
51
+ const sourceLine = seg[SOURCE_LINE];
52
+ const sourceColumn = seg[SOURCE_COLUMN];
53
+ out.push([column, sourcesIndex, sourceLine, sourceColumn]);
54
+ }
55
+ }
56
+ }
57
+
58
+ function addSection(options) {
59
+
60
+ const { input } = options;
61
+
62
+ const { sections } = input;
63
+ if (sections) {
64
+ return flatten(options);
65
+ }
66
+
67
+ const sourcesOffset = options.sources.length;
68
+
69
+ if (!input.sourcesContent) {
70
+ input.sourcesContent = [];
71
+ }
72
+ input.sources.forEach((src, i) => {
73
+ options.sources.push(src);
74
+ options.sourcesContent.push(input.sourcesContent[i] || null);
75
+ });
76
+
77
+ addMappings(options, sourcesOffset);
78
+
79
+ }
80
+
81
+ function flatten(options) {
82
+
83
+ const {
84
+ input,
85
+ lineOffset,
86
+ columnOffset,
87
+ stopLine,
88
+ stopColumn
89
+ } = options;
90
+
91
+ const { sections } = input;
92
+
93
+ for (let i = 0, l = sections.length; i < l; i++) {
94
+ const { map, offset } = sections[i];
95
+
96
+ let sl = stopLine;
97
+ let sc = stopColumn;
98
+ if (i + 1 < sections.length) {
99
+ const nextOffset = sections[i + 1].offset;
100
+ sl = Math.min(stopLine, lineOffset + nextOffset.line);
101
+
102
+ if (sl === stopLine) {
103
+ sc = Math.min(stopColumn, columnOffset + nextOffset.column);
104
+ } else if (sl < stopLine) {
105
+ sc = columnOffset + nextOffset.column;
106
+ }
107
+ }
108
+
109
+ options.input = map;
110
+ options.lineOffset = lineOffset + offset.line;
111
+ options.columnOffset = columnOffset + offset.column;
112
+ options.stopLine = sl;
113
+ options.stopColumn = sc;
114
+
115
+ addSection(options);
116
+ }
117
+ }
118
+
119
+ const flattenSourceMaps = function(indexedMap, mapUrl) {
120
+
121
+ const sections = indexedMap.sections;
122
+ if (!sections) {
123
+ return indexedMap;
124
+ }
125
+
126
+ const decodedMappings = [];
127
+ const sources = [];
128
+ const sourcesContent = [];
129
+ const names = [];
130
+ const ignoreList = [];
131
+
132
+ const lineOffset = 0;
133
+ const columnOffset = 0;
134
+ const stopLine = Infinity;
135
+ const stopColumn = Infinity;
136
+
137
+ flatten({
138
+ input: indexedMap,
139
+
140
+ mapUrl,
141
+
142
+ decodedMappings,
143
+ sources,
144
+ sourcesContent,
145
+
146
+ names,
147
+ ignoreList,
148
+
149
+ lineOffset,
150
+ columnOffset,
151
+ stopLine,
152
+ stopColumn
153
+ });
154
+
155
+ indexedMap.sources = sources;
156
+ indexedMap.sourcesContent = sourcesContent;
157
+ indexedMap.decodedMappings = decodedMappings;
158
+
159
+ // console.log(decodedMappings);
160
+
161
+ return indexedMap;
162
+ };
163
+
164
+ module.exports = {
165
+ flattenSourceMaps
166
+ };