|
1 | | -"use strict"; |
2 | | - |
3 | | -// src/coverage-reporter.cts |
4 | | -var fs = require("fs"); |
5 | | -var report = require("istanbul-lib-report"); |
6 | | -function isFull(metrics) { |
7 | | - return metrics.statements.pct === 100 && metrics.branches.pct === 100 && metrics.functions.pct === 100 && metrics.lines.pct === 100; |
8 | | -} |
9 | | -function getUncoveredLines(node) { |
10 | | - if (node.isSummary()) { |
11 | | - return []; |
12 | | - } |
13 | | - const metrics = node.getCoverageSummary(false); |
14 | | - const isEmpty = metrics.isEmpty(); |
15 | | - const lines = isEmpty ? 0 : metrics.lines.pct; |
16 | | - let coveredLines; |
17 | | - const fileCoverage = node.getFileCoverage(); |
18 | | - if (lines === 100) { |
19 | | - const branches = fileCoverage.getBranchCoverageByLine(); |
20 | | - coveredLines = Object.entries(branches).map(([key, { coverage }]) => [key, coverage === 100]); |
21 | | - } else { |
22 | | - coveredLines = Object.entries(fileCoverage.getLineCoverage()); |
23 | | - } |
24 | | - let newRange = true; |
25 | | - const ranges = coveredLines.reduce((acum, [line, hit]) => { |
26 | | - if (hit) { |
27 | | - newRange = true; |
28 | | - } else { |
29 | | - const linenum = parseInt(line); |
30 | | - if (newRange) { |
31 | | - acum.push([linenum]); |
32 | | - newRange = false; |
33 | | - } else { |
34 | | - acum[acum.length - 1][1] = linenum; |
35 | | - } |
36 | | - } |
37 | | - return acum; |
38 | | - }, []); |
39 | | - return ranges; |
40 | | -} |
41 | | -var headers = ["Statements", "Branches", "Functions", "Lines"]; |
42 | | -module.exports = class GithubActionsCoverageReporter extends report.ReportBase { |
43 | | - skipEmpty; |
44 | | - skipFull; |
45 | | - results = {}; |
46 | | - cw = null; |
47 | | - watermarks = {}; |
48 | | - constructor(opts) { |
49 | | - super(opts); |
50 | | - this.skipEmpty = Boolean(opts.skipEmpty); |
51 | | - this.skipFull = Boolean(opts.skipFull); |
52 | | - } |
53 | | - onStart(_node, context) { |
54 | | - if (!process.env.GITHUB_STEP_SUMMARY) { |
55 | | - console.log("Reporter not being executed in Github Actions environment"); |
56 | | - return; |
57 | | - } |
58 | | - this.cw = fs.createWriteStream(process.env.GITHUB_STEP_SUMMARY, { encoding: "utf-8", flags: "a" }); |
59 | | - this.watermarks = context.watermarks; |
60 | | - this.cw.write("<h2>Test Coverage</h2>"); |
61 | | - this.cw.write("<table><thead><tr>"); |
62 | | - for (const heading of ["File", ...headers, "Uncovered Lines"]) { |
63 | | - this.cw.write(`<th>${heading}</th>`); |
64 | | - } |
65 | | - this.cw.write("</tr></thead><tbody>"); |
66 | | - } |
67 | | - onSummary(node) { |
68 | | - const nodeName = node.getRelativeName() || "All Files"; |
69 | | - const rawMetrics = node.getCoverageSummary(false); |
70 | | - const isEmpty = rawMetrics.isEmpty(); |
71 | | - if (this.skipEmpty && isEmpty) { |
72 | | - return; |
73 | | - } |
74 | | - if (this.skipFull && isFull(rawMetrics)) { |
75 | | - return; |
76 | | - } |
77 | | - this.results[nodeName] = { |
78 | | - statements: isEmpty ? 0 : rawMetrics.statements.pct, |
79 | | - branches: isEmpty ? 0 : rawMetrics.branches.pct, |
80 | | - functions: isEmpty ? 0 : rawMetrics.functions.pct, |
81 | | - lines: isEmpty ? 0 : rawMetrics.lines.pct, |
82 | | - uncoveredLines: getUncoveredLines(node) |
83 | | - }; |
84 | | - } |
85 | | - onDetail(node) { |
86 | | - return this.onSummary(node); |
87 | | - } |
88 | | - formatter(pct, watermark) { |
89 | | - if (this.watermarks[watermark] === void 0) return `<td>${pct}%</td>`; |
90 | | - const [low, high] = this.watermarks[watermark]; |
91 | | - if (pct < low) { |
92 | | - return `<td><p style="color:red">${pct}%</p></td>`; |
93 | | - } |
94 | | - if (pct > high) { |
95 | | - return `<td><p style="color:green">${pct}%</p></td>`; |
96 | | - } |
97 | | - return `<td><p style="color:yellow">${pct}%</p></td>`; |
98 | | - } |
99 | | - onEnd() { |
100 | | - if (!this.cw) return; |
101 | | - const fileNames = Object.keys(this.results).sort(); |
102 | | - for (const fileName of fileNames) { |
103 | | - const metrics = this.results[fileName]; |
104 | | - this.cw.write(`<tr><td><code>${fileName}</code></td>`); |
105 | | - this.cw.write(this.formatter(metrics.statements, "statements")); |
106 | | - this.cw.write(this.formatter(metrics.branches, "branches")); |
107 | | - this.cw.write(this.formatter(metrics.functions, "functions")); |
108 | | - this.cw.write(this.formatter(metrics.lines, "lines")); |
109 | | - if (metrics.uncoveredLines.length > 0) { |
110 | | - this.cw.write("<td><details><summary>Expand</summary><ul>"); |
111 | | - for (const range of metrics.uncoveredLines) { |
112 | | - if (range.length === 1) { |
113 | | - this.cw.write(`<li>${range[0]}</li>`); |
114 | | - } else { |
115 | | - this.cw.write(`<li>${range[0]}-${range[1]}</li>`); |
116 | | - } |
117 | | - } |
118 | | - this.cw.write("</ul></details></td>"); |
119 | | - } else { |
120 | | - this.cw.write("<td></td>"); |
121 | | - } |
122 | | - this.cw.write("</tr>"); |
123 | | - } |
124 | | - this.cw.write("</tbody></table>"); |
125 | | - this.cw.close(); |
126 | | - } |
127 | | -}; |
| 1 | +"use strict";var m=require("fs"),h=require("istanbul-lib-report");function p(n){return n.statements.pct===100&&n.branches.pct===100&&n.functions.pct===100&&n.lines.pct===100}function f(n){if(n.isSummary())return[];let e=n.getCoverageSummary(!1),t=e.isEmpty()?0:e.lines.pct,r,l=n.getFileCoverage();if(t===100){let i=l.getBranchCoverageByLine();r=Object.entries(i).map(([a,{coverage:c}])=>[a,c===100])}else r=Object.entries(l.getLineCoverage());let o=!0;return r.reduce((i,[a,c])=>{if(c)o=!0;else{let u=parseInt(a);o?(i.push([u]),o=!1):i[i.length-1][1]=u}return i},[])}var d=["Statements","Branches","Functions","Lines"];module.exports=class extends h.ReportBase{skipEmpty;skipFull;results={};cw=null;watermarks={};constructor(e){super(e),this.skipEmpty=!!e.skipEmpty,this.skipFull=!!e.skipFull}onStart(e,s){if(!process.env.GITHUB_STEP_SUMMARY){console.log("Reporter not being executed in Github Actions environment");return}this.cw=m.createWriteStream(process.env.GITHUB_STEP_SUMMARY,{encoding:"utf-8",flags:"a"}),this.watermarks=s.watermarks,this.cw.write("<h2>Test Coverage</h2>"),this.cw.write("<table><thead><tr>");for(let t of["File",...d,"Uncovered Lines"])this.cw.write(`<th>${t}</th>`);this.cw.write("</tr></thead><tbody>")}onSummary(e){let s=e.getRelativeName()||"All Files",t=e.getCoverageSummary(!1),r=t.isEmpty();this.skipEmpty&&r||this.skipFull&&p(t)||(this.results[s]={statements:r?0:t.statements.pct,branches:r?0:t.branches.pct,functions:r?0:t.functions.pct,lines:r?0:t.lines.pct,uncoveredLines:f(e)})}onDetail(e){return this.onSummary(e)}formatter(e,s){if(this.watermarks[s]===void 0)return`<td>${e}%</td>`;let[t,r]=this.watermarks[s];return e<t?`<td><p style="color:red">${e}%</p></td>`:e>r?`<td><p style="color:green">${e}%</p></td>`:`<td><p style="color:yellow">${e}%</p></td>`}onEnd(){if(!this.cw)return;let e=Object.keys(this.results).sort();for(let s of e){let t=this.results[s];if(this.cw.write(`<tr><td><code>${s}</code></td>`),this.cw.write(this.formatter(t.statements,"statements")),this.cw.write(this.formatter(t.branches,"branches")),this.cw.write(this.formatter(t.functions,"functions")),this.cw.write(this.formatter(t.lines,"lines")),t.uncoveredLines.length>0){this.cw.write("<td><details><summary>Expand</summary><ul>");for(let r of t.uncoveredLines)r.length===1?this.cw.write(`<li>${r[0]}</li>`):this.cw.write(`<li>${r[0]}-${r[1]}</li>`);this.cw.write("</ul></details></td>")}else this.cw.write("<td></td>");this.cw.write("</tr>")}this.cw.write("</tbody></table>"),this.cw.close()}}; |
0 commit comments