monocart-coverage-reports 2.0.6 → 2.0.8

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.
@@ -0,0 +1,39 @@
1
+ const Util = require('../utils/util.js');
2
+
3
+ const quickFindRange = (position, ranges) => {
4
+ let start = 0;
5
+ let end = ranges.length - 1;
6
+ while (end - start > 1) {
7
+ const i = Math.floor((start + end) * 0.5);
8
+ const item = ranges[i];
9
+ if (position < item.startOffset) {
10
+ end = i;
11
+ continue;
12
+ }
13
+ if (position > item.endOffset) {
14
+ start = i;
15
+ continue;
16
+ }
17
+ return ranges[i];
18
+ }
19
+ // last two items, less is start
20
+ const endItem = ranges[end];
21
+ if (position < endItem.startOffset) {
22
+ return ranges[start];
23
+ }
24
+ return ranges[end];
25
+ };
26
+
27
+
28
+ const findInRanges = (start, end, ranges) => {
29
+ if (!Util.isList(ranges)) {
30
+ return;
31
+ }
32
+ const range = quickFindRange(start, ranges);
33
+ if (start >= range.startOffset && end <= range.endOffset) {
34
+ return range;
35
+ }
36
+ };
37
+
38
+
39
+ module.exports = findInRanges;
@@ -0,0 +1,130 @@
1
+ const Util = require('../utils/util.js');
2
+
3
+ const getNextN = (content, currentLine, item, locator) => {
4
+
5
+ // v8 ignore next N
6
+ if (content) {
7
+ const n = parseInt(content);
8
+ if (n && n > 0) {
9
+ return n;
10
+ }
11
+ return 1;
12
+ }
13
+
14
+ // block comment not end of line, same line
15
+ if (item.block) {
16
+ // has code between comment and line end
17
+ const text = locator.getSlice(item.end, currentLine.end).trim();
18
+ if (text) {
19
+ return 0;
20
+ }
21
+ }
22
+
23
+ // v8 ignore next
24
+ return 1;
25
+ };
26
+
27
+ const addNextIgnore = (list, content, item, locator) => {
28
+
29
+ const { lineParser } = locator;
30
+
31
+ // findLine 0-base
32
+ const currentLine = lineParser.findLine(item.end);
33
+ const n = getNextN(content, currentLine, item, locator);
34
+
35
+ // console.log('current line', currentLine.line, 'lines', lines);
36
+
37
+ // getLine 1-base
38
+ const line = currentLine.line + 1;
39
+ const endLine = locator.getLine(line + n);
40
+ const endOffset = endLine ? endLine.end : locator.source.length;
41
+
42
+ const nextItem = {
43
+ type: 'next',
44
+ n,
45
+ startOffset: item.end,
46
+ endOffset
47
+ };
48
+
49
+ list.push(nextItem);
50
+ };
51
+
52
+ const getIgnoredRanges = (locator, options) => {
53
+ if (!options.v8Ignore) {
54
+ return;
55
+ }
56
+
57
+ const { lineParser } = locator;
58
+
59
+ const comments = lineParser.comments;
60
+ if (!Util.isList(comments)) {
61
+ return;
62
+ }
63
+
64
+ const list = [];
65
+ let ignoreStart = null;
66
+
67
+ comments.forEach((item) => {
68
+ const {
69
+ block, start, end, text
70
+ } = item;
71
+ let content = block ? text.slice(2, -2) : text.slice(2);
72
+ content = content.trim();
73
+
74
+ const v8IgnoreKey = 'v8 ignore';
75
+ if (!content.startsWith(v8IgnoreKey)) {
76
+ return;
77
+ }
78
+
79
+ content = content.slice(v8IgnoreKey.length).trim();
80
+
81
+ if (ignoreStart) {
82
+ // v8 ignore stop
83
+ if (content === 'stop') {
84
+ ignoreStart.endOffset = start;
85
+ ignoreStart = null;
86
+ }
87
+ return;
88
+ }
89
+
90
+ // v8 ignore start
91
+ if (content === 'start') {
92
+ // add first for sort by start
93
+ ignoreStart = {
94
+ type: 'start',
95
+ startOffset: end,
96
+ endOffset: end
97
+ };
98
+ list.push(ignoreStart);
99
+ return;
100
+ }
101
+
102
+ // v8 ignore next N
103
+ const nextKey = 'next';
104
+ if (content.startsWith(nextKey)) {
105
+ content = content.slice(nextKey.length).trim();
106
+ addNextIgnore(list, content, item, locator);
107
+ }
108
+
109
+ });
110
+
111
+ // ignore not stop
112
+ if (ignoreStart) {
113
+ ignoreStart.endOffset = locator.source.length;
114
+ ignoreStart = null;
115
+ }
116
+
117
+ if (!list.length) {
118
+ return;
119
+ }
120
+
121
+ // console.log('=============================================');
122
+ // console.log(list);
123
+
124
+ return list;
125
+ };
126
+
127
+
128
+ module.exports = {
129
+ getIgnoredRanges
130
+ };
@@ -43,6 +43,9 @@ module.exports = {
43
43
  // sourceFilter: (sourcePath) => sourcePath.search(/src\/.+/) !== -1,
44
44
  sourceFilter: null,
45
45
 
46
+ // [V8 only](Boolean) Enable/Disable ignoring uncovered codes with the special comments: /* v8 ignore next/next N/start/stop */
47
+ v8Ignore: true,
48
+
46
49
  // [Istanbul only] defaultSummarizer, sourceFinder
47
50
 
48
51
  // (Boolean) Generate lcov.info file, same as lcovonly report. Defaults to false.
package/lib/generate.js CHANGED
@@ -127,60 +127,6 @@ const getReportGroup = (reports, lcov, dataType) => {
127
127
 
128
128
  // ========================================================================================================
129
129
 
130
-
131
- const generateCoverageReports = async (dataList, options) => {
132
-
133
- // get first and check v8list or istanbul data
134
- const firstData = dataList[0];
135
- const dataType = firstData.type;
136
- // console.log('data type', dataType);
137
-
138
- // init reports
139
- options.reportGroup = getReportGroup(options.reports, options.lcov, dataType);
140
- // console.log('reportGroup', options.reportGroup);
141
-
142
- // v8list
143
- if (dataType === 'v8') {
144
- // merge v8list first
145
- const v8list = await mergeV8Coverage(dataList, options);
146
- // console.log('after merge', v8list.map((it) => it.url));
147
-
148
- const { coverageData, fileSources } = await convertV8List(v8list, options);
149
- return generateV8ListReports(v8list, coverageData, fileSources, options);
150
-
151
- }
152
-
153
- // istanbul data
154
- const istanbulData = mergeIstanbulCoverage(dataList, options);
155
- const { coverageData, fileSources } = initIstanbulData(istanbulData, options);
156
- return saveIstanbulReports(coverageData, fileSources, options);
157
-
158
- };
159
-
160
- // ========================================================================================================
161
-
162
-
163
- const getCoverageDataList = async (cacheDir) => {
164
- const files = fs.readdirSync(cacheDir).filter((f) => f.startsWith('coverage-'));
165
- if (!files.length) {
166
- return;
167
- }
168
-
169
- const dataList = [];
170
- for (const item of files) {
171
- const content = await Util.readFile(path.resolve(cacheDir, item));
172
- if (content) {
173
- dataList.push(JSON.parse(content));
174
- }
175
- }
176
-
177
- if (dataList.length) {
178
- return dataList;
179
- }
180
- };
181
-
182
- // ========================================================================================================
183
-
184
130
  const capitalizeFirstLetter = (string) => {
185
131
  return string.charAt(0).toUpperCase() + string.slice(1);
186
132
  };
@@ -216,6 +162,8 @@ const showConsoleSummary = (coverageResults, options) => {
216
162
  return;
217
163
  }
218
164
 
165
+ const { metrics } = consoleOptions;
166
+
219
167
  const {
220
168
  summary, name, type
221
169
  } = coverageResults;
@@ -223,12 +171,19 @@ const showConsoleSummary = (coverageResults, options) => {
223
171
  EC.logCyan(name);
224
172
  }
225
173
 
226
- const indicators = {
174
+ const allMetrics = {
227
175
  v8: ['bytes', 'functions', 'branches', 'lines'],
228
176
  istanbul: ['statements', 'functions', 'branches', 'lines']
229
177
  };
230
178
 
231
- const list = indicators[type] || indicators.v8;
179
+ let list = allMetrics[type];
180
+ if (Util.isList(metrics)) {
181
+ const newList = list.filter((k) => metrics.includes(k));
182
+ if (newList.length) {
183
+ list = newList;
184
+ }
185
+ }
186
+
232
187
  const rows = list.map((k) => {
233
188
  return {
234
189
  ... summary[k],
@@ -261,23 +216,76 @@ const showConsoleSummary = (coverageResults, options) => {
261
216
  formatter: nFormatter
262
217
  }];
263
218
 
264
- if (type === 'istanbul') {
265
- columns.splice(4, 0, {
266
- id: 'skipped',
267
- name: 'Skipped',
268
- align: 'right',
269
- formatter: nFormatter
270
- });
271
- }
272
-
273
219
  CG({
274
220
  columns,
275
221
  rows
276
222
  });
277
223
  };
278
224
 
225
+
226
+ // ========================================================================================================
227
+
228
+ const getCoverageResults = async (dataList, options) => {
229
+ // get first and check v8list or istanbul data
230
+ const firstData = dataList[0];
231
+ const dataType = firstData.type;
232
+ // console.log('data type', dataType);
233
+
234
+ // init reports
235
+ options.reportGroup = getReportGroup(options.reports, options.lcov, dataType);
236
+ // console.log('reportGroup', options.reportGroup);
237
+
238
+ // v8list
239
+ if (dataType === 'v8') {
240
+ // merge v8list first
241
+ const v8list = await mergeV8Coverage(dataList, options);
242
+ // console.log('after merge', v8list.map((it) => it.url));
243
+
244
+ const { coverageData, fileSources } = await convertV8List(v8list, options);
245
+ return generateV8ListReports(v8list, coverageData, fileSources, options);
246
+
247
+ }
248
+
249
+ // istanbul data
250
+ const istanbulData = mergeIstanbulCoverage(dataList, options);
251
+ const { coverageData, fileSources } = initIstanbulData(istanbulData, options);
252
+ return saveIstanbulReports(coverageData, fileSources, options);
253
+ };
254
+
255
+ const generateCoverageReports = async (dataList, options) => {
256
+ const coverageResults = await getCoverageResults(dataList, options);
257
+
258
+ // [ 'type', 'reportPath', 'name', 'watermarks', 'summary', 'files' ]
259
+ // console.log(Object.keys(coverageResults));
260
+
261
+ showConsoleSummary(coverageResults, options);
262
+
263
+ return coverageResults;
264
+ };
265
+
266
+ // ========================================================================================================
267
+
268
+
269
+ const getCoverageDataList = async (cacheDir) => {
270
+ const files = fs.readdirSync(cacheDir).filter((f) => f.startsWith('coverage-'));
271
+ if (!files.length) {
272
+ return;
273
+ }
274
+
275
+ const dataList = [];
276
+ for (const item of files) {
277
+ const content = await Util.readFile(path.resolve(cacheDir, item));
278
+ if (content) {
279
+ dataList.push(JSON.parse(content));
280
+ }
281
+ }
282
+
283
+ if (dataList.length) {
284
+ return dataList;
285
+ }
286
+ };
287
+
279
288
  module.exports = {
280
289
  getCoverageDataList,
281
- generateCoverageReports,
282
- showConsoleSummary
290
+ generateCoverageReports
283
291
  };
package/lib/index.d.ts CHANGED
@@ -23,12 +23,15 @@ export type ReportDescription =
23
23
  ['v8'] | ["v8", {
24
24
  outputFile?: string,
25
25
  inline?: boolean,
26
- assetsPath?: string
26
+ assetsPath?: string,
27
+ metrics?: Array<"bytes" | "functions" | "branches" | "lines">
27
28
  }] |
28
29
  ['v8-json'] | ["v8-json", {
29
30
  outputFile?: string
30
31
  }] |
31
- ['console-summary'] |
32
+ ['console-summary'] | ['console-summary', {
33
+ metrics?: Array<"bytes" | "functions" | "branches" | "lines" | "statements">
34
+ }] |
32
35
  ['clover'] | ['clover', {
33
36
  file?: string
34
37
  }] |
@@ -120,6 +123,9 @@ export type CoverageReportOptions = {
120
123
  // [V8 only](Function) A filter function to execute for each element in the sources which unpacked from the source map.
121
124
  sourceFilter?: (sourcePath: string) => boolean,
122
125
 
126
+ // [V8 only](Boolean) Enable/Disable ignoring uncovered codes with the special comments: /* v8 ignore next/next N/start/stop */
127
+ v8Ignore?: boolean,
128
+
123
129
  // [Istanbul only] defaultSummarizer, sourceFinder
124
130
 
125
131
  // (Boolean) Generate lcov.info file, same as lcovonly report. Defaults to false.
package/lib/index.js CHANGED
@@ -4,9 +4,7 @@ const defaultOptions = require('./default/options.js');
4
4
  const Util = require('./utils/util.js');
5
5
 
6
6
  const { initV8ListAndSourcemap } = require('./v8/v8.js');
7
- const {
8
- getCoverageDataList, generateCoverageReports, showConsoleSummary
9
- } = require('./generate.js');
7
+ const { getCoverageDataList, generateCoverageReports } = require('./generate.js');
10
8
 
11
9
  class CoverageReport {
12
10
 
@@ -109,8 +107,6 @@ class CoverageReport {
109
107
  Util.rmSync(cacheDir);
110
108
  }
111
109
 
112
- showConsoleSummary(coverageResults, this.options);
113
-
114
110
  const onEnd = this.options.onEnd;
115
111
  if (typeof onEnd === 'function') {
116
112
  await onEnd(coverageResults);
@@ -44,8 +44,7 @@ class IstanbulSummary extends ReportBase {
44
44
  // add uncovered
45
45
  Object.keys(this.summary).forEach((id) => {
46
46
  const item = this.summary[id];
47
- // NOTE: skipped
48
- item.uncovered = item.total - item.covered - item.skipped;
47
+ item.uncovered = item.total - item.covered;
49
48
  });
50
49
 
51
50
  // console.log(this.summary);
@@ -103,7 +103,7 @@ const saveIstanbulReports = (coverageData, fileSources, options) => {
103
103
  return Util.relativePath(htmlPath);
104
104
  });
105
105
 
106
- const report = {
106
+ const coverageResults = {
107
107
  type: 'istanbul',
108
108
  reportPath,
109
109
  name: options.name,
@@ -112,7 +112,7 @@ const saveIstanbulReports = (coverageData, fileSources, options) => {
112
112
  ... coverageReport.getReport()
113
113
  };
114
114
 
115
- return report;
115
+ return coverageResults;
116
116
  };
117
117
 
118
118
  const mergeIstanbulCoverage = (dataList, options) => {