monocart-coverage-reports 2.10.8 → 2.10.9-beta.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 CHANGED
@@ -609,26 +609,17 @@ const coverageOptions = {
609
609
  ```
610
610
 
611
611
  ## Adding Empty Coverage for Untested Files
612
- 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.
612
+ By default the untested files will not be included in the coverage report, we can add empty coverage for untested files with option `all`, the untested files will show 0% coverage.
613
613
  ```js
614
614
  const coverageOptions = {
615
- all: {
616
- dir: ['./src'],
617
- filter: (filePath) => {
618
- return true;
619
- }
620
- }
615
+ all: './src',
616
+
617
+ // or multiple dirs
618
+ all: ['./src', './lib'],
621
619
  };
622
620
  ```
623
- The filter also supports [`minimatch`](https://github.com/isaacs/minimatch) pattern:
621
+ The untested files will apply to the `sourceFilter`. And it also supports additional `filter` (return the file type for js or css coverage):
624
622
  ```js
625
- const coverageOptions = {
626
- all: {
627
- dir: ['./src'],
628
- filter: '**/*.js'
629
- }
630
- };
631
- // or multiple patterns
632
623
  const coverageOptions = {
633
624
  all: {
634
625
  dir: ['./src'],
@@ -636,7 +627,6 @@ const coverageOptions = {
636
627
  // exclude files
637
628
  '**/ignored-*.js': false,
638
629
  '**/*.html': false,
639
- '**/*.ts': false,
640
630
  // empty css coverage
641
631
  '**/*.scss': "css",
642
632
  '**/*': true
@@ -644,6 +634,32 @@ const coverageOptions = {
644
634
  }
645
635
  };
646
636
  ```
637
+ We can also compile these untested files, such as .ts, .jsx, or .vue, etc., so that they can be analyzed by the default AST parser, thus get more coverage metric data.
638
+ ```js
639
+ const path = require("path");
640
+ const swc = require("@swc/core");
641
+ const coverageOptions = {
642
+ all: {
643
+ dir: ['./src'],
644
+ transformer: async (entry) => {
645
+ const { code, map } = await swc.transform(entry.source, {
646
+ filename: path.basename(entry.url),
647
+ sourceMaps: true,
648
+ isModule: true,
649
+ jsc: {
650
+ parser: {
651
+ syntax: "typescript",
652
+ jsx: true
653
+ },
654
+ transform: {}
655
+ }
656
+ });
657
+ entry.source = code;
658
+ entry.sourceMap = JSON.parse(map);
659
+ }
660
+ }
661
+ };
662
+ ```
647
663
 
648
664
  ## onEnd Hook
649
665
  For example, checking thresholds:
package/README.zh-Hans.md CHANGED
@@ -615,23 +615,14 @@ const coverageOptions = {
615
615
  默认,未测试的文件是不会包含到覆盖率报告的,需要使用`all`选项来为这些文件添加一个空的覆盖率,也就是0%
616
616
  ```js
617
617
  const coverageOptions = {
618
- all: {
619
- dir: ['./src'],
620
- filter: (filePath) => {
621
- return true;
622
- }
623
- }
618
+ all: './src',
619
+
620
+ // 支持多个目录
621
+ all: ['./src', './lib'],
624
622
  };
625
623
  ```
626
- `filter`过滤也支持[`minimatch`](https://github.com/isaacs/minimatch)匹配:
624
+ 未测试的文件也适用于`sourceFilter`过滤器. 而且也可以指定自己的`filter`过滤器 (可以返回文件类型来支持js或css的覆盖率格式):
627
625
  ```js
628
- const coverageOptions = {
629
- all: {
630
- dir: ['./src'],
631
- filter: '**/*.js'
632
- }
633
- };
634
- // 多个匹配
635
626
  const coverageOptions = {
636
627
  all: {
637
628
  dir: ['./src'],
@@ -639,7 +630,6 @@ const coverageOptions = {
639
630
  // exclude files
640
631
  '**/ignored-*.js': false,
641
632
  '**/*.html': false,
642
- '**/*.ts': false,
643
633
  // empty css coverage
644
634
  '**/*.scss': "css",
645
635
  '**/*': true
@@ -647,6 +637,32 @@ const coverageOptions = {
647
637
  }
648
638
  };
649
639
  ```
640
+ 我们可能需要编译.ts, .jsx, .vue等等这样的文件, 这样才能被默认的AST解析器解析,以得到更多的覆盖率指标的数据
641
+ ```js
642
+ const path = require("path");
643
+ const swc = require("@swc/core");
644
+ const coverageOptions = {
645
+ all: {
646
+ dir: ['./src'],
647
+ transformer: async (entry) => {
648
+ const { code, map } = await swc.transform(entry.source, {
649
+ filename: path.basename(entry.url),
650
+ sourceMaps: true,
651
+ isModule: true,
652
+ jsc: {
653
+ parser: {
654
+ syntax: "typescript",
655
+ jsx: true
656
+ },
657
+ transform: {}
658
+ }
659
+ });
660
+ entry.source = code;
661
+ entry.sourceMap = JSON.parse(map);
662
+ }
663
+ }
664
+ };
665
+ ```
650
666
 
651
667
  ## onEnd Hook
652
668
  结束回调可以用来自定义业务需求,比如检测覆盖率是否达标,对比每个指标的thresholds,如果低于要求的值则可以抛出一个错误退出
@@ -146,8 +146,8 @@ const saveUntestedFileSource = async (entryFile, options) => {
146
146
 
147
147
  const getUntestedCoverageData = async (entryList, options, coverageType) => {
148
148
 
149
- // save all empty coverage
150
- const dataId = Util.uid();
149
+ // save all empty coverage, 20 - 5(empty)
150
+ const dataId = Util.uid(15, 'empty');
151
151
  const results = {
152
152
  id: dataId
153
153
  };
@@ -166,15 +166,14 @@ const getUntestedCoverageData = async (entryList, options, coverageType) => {
166
166
  for (const entry of entryList) {
167
167
 
168
168
  // for raw report: source file
169
+ // id, url, source, sourceMap
169
170
  await saveUntestedFileSource(entry, options);
170
171
 
171
- const { type, url } = entry;
172
-
173
172
  if (coverageType === 'istanbul') {
174
173
 
175
174
  // ===============================================
176
175
  const item = {
177
- path: fileURLToPath(url),
176
+ path: fileURLToPath(entry.url),
178
177
  statementMap: {},
179
178
  fnMap: {},
180
179
  branchMap: {},
@@ -189,20 +188,7 @@ const getUntestedCoverageData = async (entryList, options, coverageType) => {
189
188
  } else {
190
189
 
191
190
  // ===============================================
192
- if (type === 'js') {
193
- // empty js
194
- entry.functions = entry.functions || [{
195
- functionName: '',
196
- ranges: [{
197
- startOffset: 0,
198
- endOffset: entry.source.length,
199
- count: 0
200
- }]
201
- }];
202
- } else {
203
- // empty css
204
- entry.ranges = entry.ranges || [];
205
- }
191
+ Util.setEmptyV8Coverage(entry);
206
192
 
207
193
  const item = {
208
194
  ... entry
package/lib/utils/util.js CHANGED
@@ -272,6 +272,27 @@ const Util = {
272
272
  return handler;
273
273
  },
274
274
 
275
+ setEmptyV8Coverage: (entry) => {
276
+ if (entry.type === 'css') {
277
+ // empty css
278
+ if (!entry.ranges) {
279
+ entry.ranges = [];
280
+ }
281
+ } else {
282
+ // empty js
283
+ if (!entry.functions) {
284
+ entry.functions = [{
285
+ functionName: '',
286
+ ranges: [{
287
+ startOffset: 0,
288
+ endOffset: entry.source ? entry.source.length : 0,
289
+ count: 0
290
+ }]
291
+ }];
292
+ }
293
+ }
294
+ },
295
+
275
296
  saveSourceCacheFile: async (sourceData, options, fileCache) => {
276
297
  const { cacheName, cachePath } = Util.getCacheFileInfo('source', sourceData.id, options.cacheDir);
277
298
 
package/lib/v8/v8.js CHANGED
@@ -109,11 +109,11 @@ const initV8ListAndSourcemap = async (mcr, v8list) => {
109
109
  distFile: entry.distFile
110
110
  };
111
111
 
112
- // coverage
113
- if (data.type === 'js') {
114
- data.functions = entry.functions;
115
- } else {
112
+ // coverage info
113
+ if (data.type === 'css') {
116
114
  data.ranges = entry.ranges;
115
+ } else {
116
+ data.functions = entry.functions;
117
117
  }
118
118
 
119
119
  // resolve source path
@@ -213,10 +213,10 @@ const mergeV8Coverage = async (dataList, sourceCache, options) => {
213
213
  for (const id of mergeIds) {
214
214
  const itemList = mergeMap[id];
215
215
  const item = itemMap[id];
216
- if (item.type === 'js') {
217
- item.functions = await mergeJsFunctions(itemList);
218
- } else {
216
+ if (item.type === 'css') {
219
217
  item.ranges = await mergeCssRanges(itemList);
218
+ } else {
219
+ item.functions = await mergeJsFunctions(itemList);
220
220
  }
221
221
  }
222
222
 
@@ -236,16 +236,21 @@ const mergeV8Coverage = async (dataList, sourceCache, options) => {
236
236
  const mergedList = emptyList.concat(Object.values(itemMap));
237
237
 
238
238
  // try to load coverage and source by id
239
- for (const item of mergedList) {
240
- const { id } = item;
241
- const json = sourceCache.get(id);
239
+ for (const entry of mergedList) {
240
+ const json = sourceCache.get(entry.id);
242
241
  if (json) {
243
- item.source = json.source;
244
- item.sourceMap = json.sourceMap;
242
+ entry.source = json.source;
243
+ entry.sourceMap = json.sourceMap;
245
244
  } else {
246
- Util.logError(`Not found source data: ${Util.relativePath(item.sourcePath)}`);
247
- item.source = '';
245
+ Util.logError(`Not found source data: ${Util.relativePath(entry.sourcePath)}`);
246
+ entry.source = '';
247
+ }
248
+
249
+ // add empty coverage after source init
250
+ if (entry.empty) {
251
+ Util.setEmptyV8Coverage(entry);
248
252
  }
253
+
249
254
  }
250
255
 
251
256
  return mergedList;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monocart-coverage-reports",
3
- "version": "2.10.8",
3
+ "version": "2.10.9-beta.0",
4
4
  "description": "A code coverage tool to generate native V8 reports or Istanbul reports.",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -58,7 +58,8 @@
58
58
  "dev": "npx sf d app",
59
59
  "open": "node ./scripts/open.js",
60
60
  "eol": "git rm -rf --cached . && git reset --hard HEAD",
61
- "patch": "npm run build && npm run test && npx sf publish patch -r"
61
+ "patch": "npm version patch && npm run build && npm run test && npm publish",
62
+ "beta": "npm version prerelease --preid=beta && npm run build && npm run test && npm publish --tag beta"
62
63
  },
63
64
  "workspaces": [
64
65
  "test"