monocart-coverage-reports 2.10.2 → 2.10.4

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
@@ -45,6 +45,7 @@
45
45
  - [VSCode](#vscode)
46
46
  - [Jest](#jest)
47
47
  - [Vitest](#vitest)
48
+ - [Node Test Runner](#node-test-runner)
48
49
  - [Puppeteer](#puppeteer)
49
50
  - [Cypress](#cypress)
50
51
  - [WebdriverIO](#webdriverio)
@@ -294,6 +295,7 @@ const [jsCoverage, cssCoverage] = await Promise.all([
294
295
  const coverageData = [... jsCoverage, ... cssCoverage];
295
296
 
296
297
  ```
298
+ Collect coverage with `@playwright/test` [`Automatic fixtures`](https://playwright.dev/docs/test-fixtures#automatic-fixtures), see example: [fixtures.ts](https://github.com/cenfun/playwright-coverage/blob/main/fixtures.ts)
297
299
  For more examples, see [./test/test-v8.js](./test/test-v8.js), and [anonymous](./test/test-anonymous.js), [css](./test/test-css.js)
298
300
 
299
301
 
@@ -987,6 +989,9 @@ c8 --experimental-monocart --reporter=v8 --reporter=console-details node foo.js
987
989
  - [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) - Vitest custom provider module for coverage reports
988
990
  - [merge-code-coverage-vitest](https://github.com/cenfun/merge-code-coverage-vitest) - Example for merging code coverage (Vitest unit + Playwright e2e sharding)
989
991
 
992
+ ### [Node Test Runner](https://nodejs.org/docs/latest/api/test.html)
993
+ - [node-monocart-coverage](https://github.com/cenfun/node-monocart-coverage) - Custom reporter for Node test runner for coverage
994
+
990
995
  ### [Puppeteer](https://github.com/puppeteer/puppeteer/)
991
996
  - [jest-puppeteer-coverage](https://github.com/cenfun/jest-puppeteer-coverage) - Example for Jest puppeteer coverage
992
997
  - [maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js) - Example for Jest (unit) + Puppeteer (e2e) + Codecov
package/README.zh-Hans.md CHANGED
@@ -45,6 +45,7 @@
45
45
  - [VSCode](#vscode)
46
46
  - [Jest](#jest)
47
47
  - [Vitest](#vitest)
48
+ - [Node Test Runner](#node-test-runner)
48
49
  - [Puppeteer](#puppeteer)
49
50
  - [Cypress](#cypress)
50
51
  - [WebdriverIO](#webdriverio)
@@ -117,10 +118,11 @@ mcr node my-app.js -r v8,console-details
117
118
  ![](./assets/v8.gif)
118
119
 
119
120
  - `v8-json`
120
- - 保存 `CoverageResults` 到一个json文件
121
121
  - 保存 `CoverageResults` 到一个json文件 (默认是 [`coverage-report.json`](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/coverage-report.json))
122
122
  - 用于VSCode扩展来显示原生V8代码覆盖率: [Monocart Coverage for VSCode](https://github.com/cenfun/monocart-coverage-vscode)
123
123
 
124
+ ![](./assets/mcv.gif)
125
+
124
126
  > 内置Istanbul报告 (V8和Istanbul格式数据都支持):
125
127
 
126
128
  - `clover`
@@ -295,6 +297,7 @@ const [jsCoverage, cssCoverage] = await Promise.all([
295
297
  const coverageData = [... jsCoverage, ... cssCoverage];
296
298
 
297
299
  ```
300
+ 使用 `@playwright/test` 的 [`Automatic fixtures`](https://playwright.dev/docs/test-fixtures#automatic-fixtures)收集覆盖率数据, 见例子: [fixtures.ts](https://github.com/cenfun/playwright-coverage/blob/main/fixtures.ts)
298
301
  参见例子 [./test/test-v8.js](./test/test-v8.js), and [anonymous](./test/test-anonymous.js), [css](./test/test-css.js)
299
302
 
300
303
 
@@ -990,6 +993,9 @@ c8 --experimental-monocart --reporter=v8 --reporter=console-details node foo.js
990
993
  - [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) - Vitest custom provider module for coverage reports
991
994
  - [merge-code-coverage-vitest](https://github.com/cenfun/merge-code-coverage-vitest) - Example for merging code coverage (Vitest unit + Playwright e2e sharding)
992
995
 
996
+ ### [Node Test Runner](https://nodejs.org/docs/latest/api/test.html)
997
+ - [node-monocart-coverage](https://github.com/cenfun/node-monocart-coverage) - Custom reporter for Node test runner for coverage
998
+
993
999
  ### [Puppeteer](https://github.com/puppeteer/puppeteer/)
994
1000
  - [jest-puppeteer-coverage](https://github.com/cenfun/jest-puppeteer-coverage) - Example for Jest puppeteer coverage
995
1001
  - [maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js) - Example for Jest (unit) + Puppeteer (e2e) + Codecov
@@ -1044,7 +1050,7 @@ const coverageOptions = {
1044
1050
  ]
1045
1051
  };
1046
1052
  ```
1047
- - Github actions example:
1053
+ - Github actions:
1048
1054
  ```yml
1049
1055
  - name: Codecov
1050
1056
  uses: codecov/codecov-action@v4
@@ -1080,7 +1086,7 @@ const coverageOptions = {
1080
1086
  lcov: true
1081
1087
  };
1082
1088
  ```
1083
- - Github actions example:
1089
+ - Github actions:
1084
1090
  ```yml
1085
1091
  - name: Coveralls
1086
1092
  uses: coverallsapp/github-action@v2
@@ -146,7 +146,9 @@ const createBranchGroup = (type, node, parents, branchMap) => {
146
146
  };
147
147
 
148
148
  const addBranch = (group, node, locationMap) => {
149
- const { start, end } = node;
149
+ const {
150
+ start, end, type
151
+ } = node;
150
152
 
151
153
  const branchKey = `${group.start}_${group.end}`;
152
154
 
@@ -159,6 +161,24 @@ const addBranch = (group, node, locationMap) => {
159
161
  count: 0
160
162
  };
161
163
 
164
+ if (type === 'SwitchCase') {
165
+
166
+ // console.log(node);
167
+
168
+ // check break
169
+ if (node.consequent) {
170
+ const breakItem = node.consequent.find((it) => it.type === 'BreakStatement');
171
+ if (breakItem) {
172
+ branchInfo.hasBreak = true;
173
+ }
174
+ }
175
+
176
+ // check default
177
+ if (!node.test) {
178
+ branchInfo.isDefault = true;
179
+ }
180
+ }
181
+
162
182
  group.locations.push(branchInfo);
163
183
 
164
184
  // update group end
@@ -183,12 +203,14 @@ const addNoneBranch = (group) => {
183
203
  const updateBlockLocations = (locations) => {
184
204
  const noBlockList = [];
185
205
  let blockCount = 0;
186
- locations.forEach((item) => {
206
+ locations.forEach((item, i) => {
187
207
  if (item.block) {
188
208
  item.count = item.block.count;
189
209
  blockCount += item.count;
190
210
  return;
191
211
  }
212
+ // for calculate mo break branches
213
+ item.index = i;
192
214
  noBlockList.push(item);
193
215
  });
194
216
 
@@ -240,13 +262,34 @@ const LogicalExpression = (group, parentCount) => {
240
262
  };
241
263
 
242
264
  const SwitchStatement = (group, parentCount) => {
243
- const { noBlockList, blockCount } = updateBlockLocations(group.locations);
265
+
266
+ const locations = group.locations;
267
+
268
+ const { noBlockList, blockCount } = updateBlockLocations(locations);
244
269
  if (!noBlockList.length) {
245
270
  return;
246
271
  }
247
- const count = parentCount - blockCount;
272
+
273
+ // calculate switch/case count
274
+ const countLeft = parentCount - blockCount;
248
275
  noBlockList.forEach((item) => {
249
- item.count = count;
276
+
277
+ let hasCount = false;
278
+
279
+ // check no break branches
280
+ for (let i = item.index - 1; i >= 0; i--) {
281
+ const b = locations[i];
282
+ if (b && !b.hasBreak && b.count > 0) {
283
+ item.count += b.count;
284
+ hasCount = true;
285
+ continue;
286
+ }
287
+ break;
288
+ }
289
+
290
+ if (!hasCount) {
291
+ item.count = countLeft;
292
+ }
250
293
  });
251
294
  };
252
295
 
@@ -868,8 +868,8 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
868
868
 
869
869
  const allDecodedMappings = [];
870
870
  decodedList.forEach((segments, generatedLine) => {
871
- let info = null;
872
- segments.forEach((segment) => {
871
+ const lastIndex = segments.length - 1;
872
+ segments.forEach((segment, i) => {
873
873
 
874
874
  // const COLUMN = 0;
875
875
  // const SOURCES_INDEX = 1;
@@ -889,7 +889,7 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
889
889
  column: generatedColumn
890
890
  });
891
891
 
892
- info = {
892
+ const info = {
893
893
  generatedOffset,
894
894
  generatedLine,
895
895
  generatedColumn,
@@ -900,12 +900,21 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
900
900
  nameIndex
901
901
  };
902
902
 
903
+ // first and last column
904
+ if (i === 0) {
905
+ info.first = true;
906
+ }
907
+ if (i === lastIndex) {
908
+ info.last = true;
909
+ }
910
+
903
911
  allDecodedMappings.push(info);
904
912
 
905
913
  originalDecodedMap.get(sourceIndex).push(info);
906
914
 
907
915
  });
908
916
 
917
+
909
918
  });
910
919
 
911
920
  // defaults to sort by generated offset, not need sort
@@ -407,16 +407,16 @@ const getFixedPosition = (info, direction) => {
407
407
 
408
408
  // ========================================================================================================
409
409
 
410
- const getOriginalEndOffset = (m, cache) => {
410
+ const getOriginalEndOffset = (m, originalState) => {
411
411
  if (!m.originalEndOffset) {
412
- const line = cache.originalState.locator.getLine(m.originalLine + 1);
412
+ const line = originalState.locator.getLine(m.originalLine + 1);
413
413
  m.originalEndOffset = line ? line.end : m.originalOffset;
414
414
  }
415
415
  return m.originalEndOffset;
416
416
  };
417
417
 
418
- const getOriginalText = (m1, m2, cache) => {
419
- const originalLocator = cache.originalState.locator;
418
+ const getOriginalText = (m1, m2, originalState, startNextLine) => {
419
+ const originalLocator = originalState.locator;
420
420
 
421
421
  const o1 = m1.originalOffset;
422
422
  const o2 = m2.originalOffset;
@@ -442,10 +442,22 @@ const getOriginalText = (m1, m2, cache) => {
442
442
  };
443
443
  }
444
444
 
445
+ // start from next line
446
+ if (startNextLine) {
447
+ const nextLine = originalState.locator.getLine(m1.originalLine + 2);
448
+ if (nextLine) {
449
+ // console.log(nextLine);
450
+ return {
451
+ originalOffset: nextLine.start + nextLine.indent,
452
+ originalText: nextLine.text.slice(nextLine.indent)
453
+ };
454
+ }
455
+ }
456
+
445
457
  // could be multiple lines for original text
446
458
  return {
447
459
  originalOffset: o1,
448
- originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, cache))
460
+ originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, originalState))
449
461
  };
450
462
  }
451
463
 
@@ -454,7 +466,7 @@ const getOriginalText = (m1, m2, cache) => {
454
466
  if (o1 === o2) {
455
467
  return {
456
468
  originalOffset: o1,
457
- originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, cache))
469
+ originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, originalState))
458
470
  };
459
471
  }
460
472
 
@@ -477,7 +489,7 @@ const getOriginalText = (m1, m2, cache) => {
477
489
  // should be wrong, ignore m2
478
490
  return {
479
491
  originalOffset: o1,
480
- originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, cache))
492
+ originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, originalState))
481
493
  };
482
494
 
483
495
  };
@@ -553,8 +565,19 @@ const getFixedOriginalStart = (start, mappings, state, cache, options) => {
553
565
  };
554
566
  }
555
567
 
568
+ // skip last mapping
569
+ let startNextLine = false;
570
+ if (m1.last) {
571
+ const locStart = state.locator.offsetToLocation(start);
572
+ // 1-base
573
+ const lineIndex = locStart.line - 1;
574
+ if (lineIndex > m1.generatedLine) {
575
+ startNextLine = true;
576
+ // console.log(originalState.sourcePath, start, m1, m2);
577
+ }
578
+ }
556
579
 
557
- const { originalText, originalOffset } = getOriginalText(m1, m2, cache);
580
+ const { originalText, originalOffset } = getOriginalText(m1, m2, originalState, startNextLine);
558
581
  const { generatedText, generatedPos } = getGeneratedText(m1, m2, state, start);
559
582
  const direction = 'start';
560
583
 
@@ -592,7 +615,7 @@ const getFixedOriginalEnd = (end, mappings, state, cache) => {
592
615
 
593
616
  // cross file until e1 line end (not file end)
594
617
  if (crossEnd) {
595
- const originalEndOffset = getOriginalEndOffset(m1, cache);
618
+ const originalEndOffset = getOriginalEndOffset(m1, originalState);
596
619
  return {
597
620
  originalEnd: originalEndOffset
598
621
  };
@@ -608,7 +631,7 @@ const getFixedOriginalEnd = (end, mappings, state, cache) => {
608
631
  }
609
632
 
610
633
 
611
- const { originalText, originalOffset } = getOriginalText(m1, m2, cache);
634
+ const { originalText, originalOffset } = getOriginalText(m1, m2, originalState);
612
635
  const { generatedText, generatedPos } = getGeneratedText(m1, m2, state, end);
613
636
  const direction = 'end';
614
637