Fixed #1 - Fixed the whatsnew-** script for loading release notes into builds
Added test to ensure that release notes are parsed properly Updated to latest dependencies to fix security vulnerability Updated GH Actions Workflow to run test before updating tag Updated README.md to reflect proper whatsnew documentation.
This commit is contained in:
220
node_modules/istanbul-reports/lib/html/index.js
generated
vendored
220
node_modules/istanbul-reports/lib/html/index.js
generated
vendored
@@ -4,28 +4,130 @@
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const handlebars = require('handlebars').create();
|
||||
const html = require('html-escaper');
|
||||
const annotator = require('./annotator');
|
||||
const helpers = require('./helpers');
|
||||
const templateFor = function(name) {
|
||||
return handlebars.compile(
|
||||
fs.readFileSync(
|
||||
path.resolve(__dirname, 'templates', name + '.txt'),
|
||||
'utf8'
|
||||
)
|
||||
);
|
||||
};
|
||||
const headerTemplate = templateFor('head');
|
||||
const footerTemplate = templateFor('foot');
|
||||
const detailTemplate = handlebars.compile(
|
||||
[
|
||||
|
||||
function htmlHead(details) {
|
||||
return `
|
||||
<head>
|
||||
<title>Code coverage report for ${html.escape(details.entity)}</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="${html.escape(details.prettify.css)}" />
|
||||
<link rel="stylesheet" href="${html.escape(details.base.css)}" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type='text/css'>
|
||||
.coverage-summary .sorter {
|
||||
background-image: url(${html.escape(details.sorter.image)});
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
`;
|
||||
}
|
||||
|
||||
function headerTemplate(details) {
|
||||
function metricsTemplate({ pct, covered, total }, kind) {
|
||||
return `
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">${pct}% </span>
|
||||
<span class="quiet">${kind}</span>
|
||||
<span class='fraction'>${covered}/${total}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function skipTemplate(metrics) {
|
||||
const statements = metrics.statements.skipped;
|
||||
const branches = metrics.branches.skipped;
|
||||
const functions = metrics.functions.skipped;
|
||||
|
||||
const countLabel = (c, label, plural) =>
|
||||
c === 0 ? [] : `${c} ${label}${c === 1 ? '' : plural}`;
|
||||
const skips = [].concat(
|
||||
countLabel(statements, 'statement', 's'),
|
||||
countLabel(functions, 'function', 's'),
|
||||
countLabel(branches, 'branch', 'es')
|
||||
);
|
||||
|
||||
if (skips.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return `
|
||||
<div class='fl pad1y'>
|
||||
<span class="strong">${skips.join(', ')}</span>
|
||||
<span class="quiet">Ignored</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return `
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
${htmlHead(details)}
|
||||
<body>
|
||||
<div class='wrapper'>
|
||||
<div class='pad1'>
|
||||
<h1>${details.pathHtml}</h1>
|
||||
<div class='clearfix'>
|
||||
${metricsTemplate(details.metrics.statements, 'Statements')}
|
||||
${metricsTemplate(details.metrics.branches, 'Branches')}
|
||||
${metricsTemplate(details.metrics.functions, 'Functions')}
|
||||
${metricsTemplate(details.metrics.lines, 'Lines')}
|
||||
${skipTemplate(details.metrics)}
|
||||
</div>
|
||||
<p class="quiet">
|
||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
||||
</p>
|
||||
</div>
|
||||
<div class='status-line ${details.reportClass}'></div>
|
||||
`;
|
||||
}
|
||||
|
||||
function footerTemplate(details) {
|
||||
return `
|
||||
<div class='push'></div><!-- for sticky footer -->
|
||||
</div><!-- /wrapper -->
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank">istanbul</a>
|
||||
at ${html.escape(details.datetime)}
|
||||
</div>
|
||||
</div>
|
||||
<script src="${html.escape(details.prettify.js)}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
prettyPrint();
|
||||
};
|
||||
</script>
|
||||
<script src="${html.escape(details.sorter.js)}"></script>
|
||||
<script src="${html.escape(details.blockNavigation.js)}"></script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
}
|
||||
|
||||
function detailTemplate(data) {
|
||||
const lineNumbers = new Array(data.maxLines).fill().map((_, i) => i + 1);
|
||||
const lineLink = num =>
|
||||
`<a name='L${num}'></a><a href='#L${num}'>${num}</a>`;
|
||||
const lineCount = line =>
|
||||
`<span class="cline-any cline-${line.covered}">${line.hits}</span>`;
|
||||
|
||||
/* This is rendered in a `<pre>`, need control of all whitespace. */
|
||||
return [
|
||||
'<tr>',
|
||||
'<td class="line-count quiet">{{#show_lines}}{{maxLines}}{{/show_lines}}</td>',
|
||||
'<td class="line-coverage quiet">{{#show_line_execution_counts lineCoverage}}{{maxLines}}{{/show_line_execution_counts}}</td>',
|
||||
'<td class="text"><pre class="prettyprint lang-js">{{#show_code annotatedCode}}{{/show_code}}</pre></td>',
|
||||
'</tr>\n'
|
||||
].join('')
|
||||
);
|
||||
`<td class="line-count quiet">${lineNumbers
|
||||
.map(lineLink)
|
||||
.join('\n')}</td>`,
|
||||
`<td class="line-coverage quiet">${data.lineCoverage
|
||||
.map(lineCount)
|
||||
.join('\n')}</td>`,
|
||||
`<td class="text"><pre class="prettyprint lang-js">${data.annotatedCode.join(
|
||||
'\n'
|
||||
)}</pre></td>`,
|
||||
'</tr>'
|
||||
].join('');
|
||||
}
|
||||
const summaryTableHeader = [
|
||||
'<div class="pad1">',
|
||||
'<table class="coverage-summary">',
|
||||
@@ -45,22 +147,60 @@ const summaryTableHeader = [
|
||||
'</thead>',
|
||||
'<tbody>'
|
||||
].join('\n');
|
||||
const summaryLineTemplate = handlebars.compile(
|
||||
[
|
||||
'<tr>',
|
||||
'<td class="file {{reportClasses.statements}}" data-value="{{file}}"><a href="{{output}}">{{file}}</a></td>',
|
||||
'<td data-value="{{metrics.statements.pct}}" class="pic {{reportClasses.statements}}"><div class="chart">{{#show_picture}}{{metrics.statements.pct}}{{/show_picture}}</div></td>',
|
||||
'<td data-value="{{metrics.statements.pct}}" class="pct {{reportClasses.statements}}">{{metrics.statements.pct}}%</td>',
|
||||
'<td data-value="{{metrics.statements.total}}" class="abs {{reportClasses.statements}}">{{metrics.statements.covered}}/{{metrics.statements.total}}</td>',
|
||||
'<td data-value="{{metrics.branches.pct}}" class="pct {{reportClasses.branches}}">{{metrics.branches.pct}}%</td>',
|
||||
'<td data-value="{{metrics.branches.total}}" class="abs {{reportClasses.branches}}">{{metrics.branches.covered}}/{{metrics.branches.total}}</td>',
|
||||
'<td data-value="{{metrics.functions.pct}}" class="pct {{reportClasses.functions}}">{{metrics.functions.pct}}%</td>',
|
||||
'<td data-value="{{metrics.functions.total}}" class="abs {{reportClasses.functions}}">{{metrics.functions.covered}}/{{metrics.functions.total}}</td>',
|
||||
'<td data-value="{{metrics.lines.pct}}" class="pct {{reportClasses.lines}}">{{metrics.lines.pct}}%</td>',
|
||||
'<td data-value="{{metrics.lines.total}}" class="abs {{reportClasses.lines}}">{{metrics.lines.covered}}/{{metrics.lines.total}}</td>',
|
||||
'</tr>\n'
|
||||
].join('\n\t')
|
||||
);
|
||||
|
||||
function summaryLineTemplate(details) {
|
||||
const { reportClasses, metrics, file, output } = details;
|
||||
const percentGraph = pct => {
|
||||
if (!isFinite(pct)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const cls = ['cover-fill'];
|
||||
if (pct === 100) {
|
||||
cls.push('cover-full');
|
||||
}
|
||||
|
||||
pct = Math.floor(pct);
|
||||
return [
|
||||
`<div class="${cls.join(' ')}" style="width: ${pct}%"></div>`,
|
||||
`<div class="cover-empty" style="width: ${100 - pct}%"></div>`
|
||||
].join('');
|
||||
};
|
||||
const summaryType = (type, showGraph = false) => {
|
||||
const info = metrics[type];
|
||||
const reportClass = reportClasses[type];
|
||||
const result = [
|
||||
`<td data-value="${info.pct}" class="pct ${reportClass}">${info.pct}%</td>`,
|
||||
`<td data-value="${info.total}" class="abs ${reportClass}">${info.covered}/${info.total}</td>`
|
||||
];
|
||||
if (showGraph) {
|
||||
result.unshift(
|
||||
`<td data-value="${info.pct}" class="pic ${reportClass}">`,
|
||||
`<div class="chart">${percentGraph(info.pct)}</div>`,
|
||||
`</td>`
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return []
|
||||
.concat(
|
||||
'<tr>',
|
||||
`<td class="file ${
|
||||
reportClasses.statements
|
||||
}" data-value="${html.escape(file)}"><a href="${html.escape(
|
||||
output
|
||||
)}">${html.escape(file)}</a></td>`,
|
||||
summaryType('statements', true),
|
||||
summaryType('branches'),
|
||||
summaryType('functions'),
|
||||
summaryType('lines'),
|
||||
'</tr>\n'
|
||||
)
|
||||
.join('\n\t');
|
||||
}
|
||||
|
||||
const summaryTableFooter = ['</tbody>', '</table>', '</div>'].join('\n');
|
||||
const emptyClasses = {
|
||||
statements: 'empty',
|
||||
@@ -69,8 +209,6 @@ const emptyClasses = {
|
||||
branches: 'empty'
|
||||
};
|
||||
|
||||
helpers.registerHelpers(handlebars);
|
||||
|
||||
const standardLinkMapper = {
|
||||
getPath(node) {
|
||||
if (typeof node === 'string') {
|
||||
@@ -260,11 +398,7 @@ class HtmlReport {
|
||||
const cw = this.getWriter(context).writeFile(linkMapper.getPath(node));
|
||||
cw.write(headerTemplate(templateData));
|
||||
cw.write('<pre><table class="coverage">\n');
|
||||
cw.write(
|
||||
detailTemplate(
|
||||
annotator.annotateSourceCode(node.getFileCoverage(), context)
|
||||
)
|
||||
);
|
||||
cw.write(detailTemplate(annotator(node.getFileCoverage(), context)));
|
||||
cw.write('</table></pre>\n');
|
||||
cw.write(footerTemplate(templateData));
|
||||
cw.close();
|
||||
|
||||
Reference in New Issue
Block a user