monocart-coverage-reports 2.5.8 → 2.6.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/lib/index.js CHANGED
@@ -1,173 +1,183 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const defaultOptions = require('./default/options.js');
4
- const Util = require('./utils/util.js');
5
-
6
- const { initV8ListAndSourcemap } = require('./v8/v8.js');
7
- const { getInputData, generateCoverageReports } = require('./generate.js');
8
-
9
- class CoverageReport {
10
-
11
- constructor(options = {}) {
12
- this.cacheDirName = '.cache';
13
- this.options = {
14
- ... defaultOptions,
15
- ... options
16
- };
17
- }
18
-
19
- initOptions() {
20
-
21
- if (this.fixedOptions) {
22
- return;
23
- }
24
-
25
- // init logging for clean after generated
26
- this.logging = Util.initLoggingLevel(this.options.logging);
27
-
28
- // init outputDir
29
- const outputDir = `${this.options.outputDir || defaultOptions.outputDir}`;
30
- this.options.outputDir = outputDir;
31
-
32
- // cache dir, it is useful if runs in multiple processes.
33
- // cache coverage- data and source- files
34
- // it will be removed after generated if logging it not debug.
35
- const cacheDir = path.resolve(outputDir, this.cacheDirName);
36
- this.options.cacheDir = cacheDir;
37
-
38
- this.fixedOptions = true;
39
- }
40
-
41
- // add coverage data: {array} V8 format, {object} Istanbul format
42
- async add(data) {
43
-
44
- const time_start = Date.now();
45
-
46
- this.initOptions();
47
-
48
- if (!Util.checkCoverageData(data)) {
49
- Util.logError(`${this.options.name}: The added coverage data must be Array(V8) or Object(Istanbul)`);
50
- return;
51
- }
52
-
53
- const dataId = Util.uid();
54
- const dataName = `coverage-${dataId}.json`;
55
- const dataPath = path.resolve(this.options.cacheDir, dataName);
56
-
57
- const results = {
58
- id: dataId,
59
- path: dataPath
60
- };
61
-
62
- if (Array.isArray(data)) {
63
- results.type = 'v8';
64
- results.data = await initV8ListAndSourcemap(data, this.options);
65
- } else {
66
- results.type = 'istanbul';
67
- results.data = data;
68
- }
69
-
70
- // save data to cache dir
71
- const dataContent = JSON.stringify(results);
72
- await Util.writeFile(dataPath, dataContent);
73
-
74
- Util.logTime(`added coverage data: ${results.type}`, time_start);
75
-
76
- return results;
77
- }
78
-
79
- // generate report
80
- async generate() {
81
-
82
- const time_start = Date.now();
83
-
84
- this.initOptions();
85
-
86
- const {
87
- all, inputDir, cacheDir
88
- } = this.options;
89
-
90
- const inputDirs = Util.toList(inputDir, ',');
91
- if (this.hasCache()) {
92
- inputDirs.push(cacheDir);
93
- }
94
-
95
- const inputList = inputDirs.filter((dir) => {
96
- const hasDir = fs.existsSync(dir);
97
- if (!hasDir) {
98
- // could be empty
99
- Util.logInfo(`Not found coverage data dir: ${Util.relativePath(dir)}`);
100
- }
101
- return hasDir;
102
- });
103
-
104
- const { dataList, sourceCache } = await getInputData(inputList, all, cacheDir, (emptyData) => {
105
- return this.add(emptyData);
106
- });
107
-
108
- if (!dataList.length) {
109
- const dirs = inputList.map((dir) => Util.relativePath(dir));
110
- Util.logError(`Not found coverage data in dir(s): ${dirs.join(', ')}`);
111
- return;
112
- }
113
-
114
- // empty output dir except cache dir before generate reports
115
- const outputDir = this.options.outputDir;
116
-
117
- if (fs.existsSync(outputDir)) {
118
- // if assets dir is out of output dir will be ignore
119
- if (this.options.clean) {
120
- fs.readdirSync(outputDir).forEach((itemName) => {
121
- if (itemName === this.cacheDirName) {
122
- return;
123
- }
124
- Util.rmSync(path.resolve(outputDir, itemName));
125
- });
126
- }
127
- } else {
128
- fs.mkdirSync(outputDir, {
129
- recursive: true
130
- });
131
- }
132
-
133
- const coverageResults = await generateCoverageReports(dataList, sourceCache, this.options);
134
-
135
- if (this.logging !== 'debug') {
136
- Util.rmSync(cacheDir);
137
- }
138
-
139
- Util.logTime(`generated coverage reports: ${coverageResults.reportPath}`, time_start);
140
-
141
- const onEnd = this.options.onEnd;
142
- if (typeof onEnd === 'function') {
143
- await onEnd(coverageResults);
144
- }
145
-
146
- return coverageResults;
147
- }
148
-
149
- // check if cache dir exists
150
- hasCache() {
151
- this.initOptions();
152
- return fs.existsSync(this.options.cacheDir);
153
- }
154
-
155
- // cache clean
156
- cleanCache() {
157
- // clean previous artifacts
158
- if (this.hasCache()) {
159
- Util.rmSync(this.options.cacheDir);
160
- return true;
161
- }
162
- return false;
163
- }
164
-
165
- }
166
-
167
- /** create coverage report */
168
- const MCR = function(options) {
169
- return new CoverageReport(options);
170
- };
171
- MCR.CoverageReport = CoverageReport;
172
-
173
- module.exports = MCR;
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const defaultOptions = require('./default/options.js');
4
+ const Util = require('./utils/util.js');
5
+
6
+ const { initV8ListAndSourcemap } = require('./v8/v8.js');
7
+ const { getInputData, generateCoverageReports } = require('./generate.js');
8
+ const { getSnapshot, diffSnapshot } = require('./utils/snapshot.js');
9
+
10
+ class CoverageReport {
11
+
12
+ constructor(options = {}) {
13
+ this.cacheDirName = '.cache';
14
+ this.options = {
15
+ ... defaultOptions,
16
+ ... options
17
+ };
18
+
19
+ this.initOptions();
20
+ // If true, the API `cleanCache()` will execute automatically.
21
+ if (this.options.cleanCache) {
22
+ this.cleanCache();
23
+ }
24
+
25
+ }
26
+
27
+ initOptions() {
28
+
29
+ if (this.fixedOptions) {
30
+ return;
31
+ }
32
+
33
+ // init logging for clean after generated
34
+ this.logging = Util.initLoggingLevel(this.options.logging);
35
+
36
+ // init outputDir
37
+ const outputDir = `${this.options.outputDir || defaultOptions.outputDir}`;
38
+ this.options.outputDir = outputDir;
39
+
40
+ // cache dir, it is useful if runs in multiple processes.
41
+ // cache coverage- data and source- files
42
+ // it will be removed after generated if logging it not debug.
43
+ const cacheDir = path.resolve(outputDir, this.cacheDirName);
44
+ this.options.cacheDir = cacheDir;
45
+
46
+ this.fixedOptions = true;
47
+ }
48
+
49
+ // add coverage data: {array} V8 format, {object} Istanbul format
50
+ async add(data) {
51
+
52
+ const time_start = Date.now();
53
+
54
+ this.initOptions();
55
+
56
+ if (!Util.checkCoverageData(data)) {
57
+ Util.logError(`${this.options.name}: The added coverage data must be Array(V8) or Object(Istanbul)`);
58
+ return;
59
+ }
60
+
61
+ const dataId = Util.uid();
62
+ const dataName = `coverage-${dataId}.json`;
63
+ const dataPath = path.resolve(this.options.cacheDir, dataName);
64
+
65
+ const results = {
66
+ id: dataId,
67
+ path: dataPath
68
+ };
69
+
70
+ if (Array.isArray(data)) {
71
+ results.type = 'v8';
72
+ results.data = await initV8ListAndSourcemap(data, this.options);
73
+ } else {
74
+ results.type = 'istanbul';
75
+ results.data = data;
76
+ }
77
+
78
+ // save data to cache dir
79
+ const dataContent = JSON.stringify(results);
80
+ await Util.writeFile(dataPath, dataContent);
81
+
82
+ Util.logTime(`added coverage data: ${results.type}`, time_start);
83
+
84
+ return results;
85
+ }
86
+
87
+ // generate report
88
+ async generate() {
89
+
90
+ const time_start = Date.now();
91
+
92
+ this.initOptions();
93
+
94
+ const {
95
+ all, inputDir, cacheDir
96
+ } = this.options;
97
+
98
+ const inputDirs = Util.toList(inputDir, ',');
99
+ if (this.hasCache()) {
100
+ inputDirs.push(cacheDir);
101
+ }
102
+
103
+ const inputList = inputDirs.filter((dir) => {
104
+ const hasDir = fs.existsSync(dir);
105
+ if (!hasDir) {
106
+ // could be empty
107
+ Util.logInfo(`Not found coverage data dir: ${Util.relativePath(dir)}`);
108
+ }
109
+ return hasDir;
110
+ });
111
+
112
+ const { dataList, sourceCache } = await getInputData(inputList, all, cacheDir, (emptyData) => {
113
+ return this.add(emptyData);
114
+ });
115
+
116
+ if (!dataList.length) {
117
+ const dirs = inputList.map((dir) => Util.relativePath(dir));
118
+ Util.logError(`Not found coverage data in dir(s): ${dirs.join(', ')}`);
119
+ return;
120
+ }
121
+
122
+ // empty output dir except cache dir before generate reports
123
+ const outputDir = this.options.outputDir;
124
+
125
+ if (fs.existsSync(outputDir)) {
126
+ // if assets dir is out of output dir will be ignore
127
+ if (this.options.clean) {
128
+ fs.readdirSync(outputDir).forEach((itemName) => {
129
+ if (itemName === this.cacheDirName) {
130
+ return;
131
+ }
132
+ Util.rmSync(path.resolve(outputDir, itemName));
133
+ });
134
+ }
135
+ } else {
136
+ fs.mkdirSync(outputDir, {
137
+ recursive: true
138
+ });
139
+ }
140
+
141
+ const coverageResults = await generateCoverageReports(dataList, sourceCache, this.options);
142
+
143
+ if (this.logging !== 'debug') {
144
+ Util.rmSync(cacheDir);
145
+ }
146
+
147
+ Util.logTime(`generated coverage reports: ${coverageResults.reportPath}`, time_start);
148
+
149
+ const onEnd = this.options.onEnd;
150
+ if (typeof onEnd === 'function') {
151
+ await onEnd.call(this, coverageResults);
152
+ }
153
+
154
+ return coverageResults;
155
+ }
156
+
157
+ // check if cache dir exists
158
+ hasCache() {
159
+ this.initOptions();
160
+ return fs.existsSync(this.options.cacheDir);
161
+ }
162
+
163
+ // cache clean
164
+ cleanCache() {
165
+ // clean previous artifacts
166
+ if (this.hasCache()) {
167
+ Util.rmSync(this.options.cacheDir);
168
+ return true;
169
+ }
170
+ return false;
171
+ }
172
+
173
+ }
174
+
175
+ /** create coverage report */
176
+ const MCR = function(options) {
177
+ return new CoverageReport(options);
178
+ };
179
+ MCR.CoverageReport = CoverageReport;
180
+ MCR.getSnapshot = getSnapshot;
181
+ MCR.diffSnapshot = diffSnapshot;
182
+
183
+ module.exports = MCR;
package/lib/index.mjs CHANGED
@@ -1,3 +1,5 @@
1
- import MCR from './index.js';
2
- export default MCR;
3
- export const CoverageReport = MCR.CoverageReport;
1
+ import MCR from './index.js';
2
+ export default MCR;
3
+ export const CoverageReport = MCR.CoverageReport;
4
+ export const getSnapshot = MCR.getSnapshot;
5
+ export const diffSnapshot = MCR.diffSnapshot;
@@ -1,63 +1,70 @@
1
- const istanbulLibReport = require('istanbul-lib-report');
2
-
3
- const ReportBase = istanbulLibReport.ReportBase;
4
- class IstanbulSummary extends ReportBase {
5
-
6
- onStart(root, context) {
7
- this.context = context;
8
- this.summary = {};
9
- this.files = [];
10
- }
11
-
12
- addStatus(data) {
13
- Object.keys(data).forEach((k) => {
14
- const item = data[k];
15
- // low, medium, high, unknown
16
- item.status = this.context.classForPercent(k, item.pct);
17
- });
18
- }
19
-
20
- onSummary(node) {
21
- if (!node.isRoot()) {
22
- return;
23
- }
24
- this.summary = node.getCoverageSummary().data;
25
- this.addStatus(this.summary);
26
- }
27
-
28
- onDetail(node) {
29
- const fileSummary = node.getCoverageSummary().data;
30
- this.addStatus(fileSummary);
31
- const sourcePath = node.getQualifiedName();
32
- this.files.push({
33
- sourcePath,
34
- summary: fileSummary
35
- });
36
- }
37
-
38
- onEnd() {
39
- // console.log('onEnd');
40
- }
41
-
42
- getReport() {
43
-
44
- // remove branchesTrue
45
- delete this.summary.branchesTrue;
46
-
47
- // add uncovered
48
- Object.keys(this.summary).forEach((id) => {
49
- const item = this.summary[id];
50
- item.uncovered = item.total - item.covered;
51
- });
52
-
53
- // console.log(this.summary);
54
-
55
- return {
56
- summary: this.summary,
57
- files: this.files
58
- };
59
- }
60
- }
61
-
62
-
63
- module.exports = IstanbulSummary;
1
+ const istanbulLibReport = require('istanbul-lib-report');
2
+
3
+ const ReportBase = istanbulLibReport.ReportBase;
4
+ class IstanbulSummary extends ReportBase {
5
+
6
+ onStart(root, context) {
7
+ this.context = context;
8
+ this.summary = {};
9
+ this.files = [];
10
+ }
11
+
12
+ addStatus(data) {
13
+ Object.keys(data).forEach((k) => {
14
+ const item = data[k];
15
+ // low, medium, high, unknown
16
+ item.status = this.context.classForPercent(k, item.pct);
17
+ });
18
+ }
19
+
20
+ onSummary(node) {
21
+ if (!node.isRoot()) {
22
+ return;
23
+ }
24
+ this.summary = node.getCoverageSummary().data;
25
+ this.addStatus(this.summary);
26
+ }
27
+
28
+ onDetail(node) {
29
+ const fileSummary = node.getCoverageSummary().data;
30
+ this.addStatus(fileSummary);
31
+ const sourcePath = node.getQualifiedName();
32
+
33
+ const fileCoverage = node.getFileCoverage();
34
+ const lines = fileCoverage.getLineCoverage();
35
+
36
+ this.files.push({
37
+ sourcePath,
38
+ summary: fileSummary,
39
+ data: {
40
+ lines
41
+ }
42
+ });
43
+ }
44
+
45
+ onEnd() {
46
+ // console.log('onEnd');
47
+ }
48
+
49
+ getReport() {
50
+
51
+ // remove branchesTrue
52
+ delete this.summary.branchesTrue;
53
+
54
+ // add uncovered
55
+ Object.keys(this.summary).forEach((id) => {
56
+ const item = this.summary[id];
57
+ item.uncovered = item.total - item.covered;
58
+ });
59
+
60
+ // console.log(this.summary);
61
+
62
+ return {
63
+ summary: this.summary,
64
+ files: this.files
65
+ };
66
+ }
67
+ }
68
+
69
+
70
+ module.exports = IstanbulSummary;