You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.0 KiB
106 lines
3.0 KiB
2 years ago
|
import libCoverage from 'istanbul-lib-coverage';
|
||
|
import libReport from 'istanbul-lib-report';
|
||
|
import reports from 'istanbul-reports';
|
||
|
import { glob } from "../lib/builderator.js";
|
||
|
import fs from "fs";
|
||
|
import v8toIstanbul from 'v8-to-istanbul';
|
||
|
import assert from "assert";
|
||
|
import url from "url";
|
||
|
import normalize from "normalize-path";
|
||
|
|
||
|
export const description = "Takes the output of a nv8 coverage directory and generates a report.";
|
||
|
|
||
|
export const argument = ["<coverage_dir>", "coverage directory"];
|
||
|
|
||
|
export const main = async (coverage_dir) => {
|
||
|
const covdir = normalize(coverage_dir);
|
||
|
const covpattern = `${covdir}/**/*.json`;
|
||
|
console.log(`Searching ${covpattern} for coverage files...`);
|
||
|
|
||
|
const covfiles = glob(covpattern);
|
||
|
console.log(`Found ${covfiles.length} .json files in ${covdir}`);
|
||
|
|
||
|
const coverage = {};
|
||
|
|
||
|
const excludes = [
|
||
|
"node_modules",
|
||
|
"secrets",
|
||
|
"/net"
|
||
|
];
|
||
|
|
||
|
for(const fname of covfiles) {
|
||
|
const data = JSON.parse(fs.readFileSync(fname));
|
||
|
|
||
|
// test removing just node modules
|
||
|
data.result = data.result.filter(x => {
|
||
|
if(x.url) {
|
||
|
// we need to do surgery on the URL because node is bad at them
|
||
|
let pathname = url.parse(x.url).pathname;
|
||
|
|
||
|
// fix the URL and turn it into a file name
|
||
|
if(!pathname) {
|
||
|
return false;
|
||
|
} else if(pathname.startsWith("/C:")) {
|
||
|
// why does url not parse windows paths right?
|
||
|
// remove the leading / so it's parsed correctly
|
||
|
x.url = pathname.slice(1);
|
||
|
} else {
|
||
|
x.url = pathname;
|
||
|
}
|
||
|
|
||
|
const excluded = excludes.filter(e => x.url.includes(e));
|
||
|
return excluded.length === 0 && fs.existsSync(x.url);
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// looks good, save it
|
||
|
if(data.result.length > 0) {
|
||
|
coverage[fname] = data;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const coverageMap = libCoverage.createCoverageMap();
|
||
|
console.log("After filtering, found count is:", Object.entries(coverage).length);
|
||
|
|
||
|
for(const [fname, data] of Object.entries(coverage)) {
|
||
|
for(const entry of data.result) {
|
||
|
let converter;
|
||
|
const pathname = url.parse(entry.url).pathname
|
||
|
assert(fs.existsSync(pathname), `coverage entry in ${fname} contains ${entry.url} that doesn't exist but should`);
|
||
|
|
||
|
converter = v8toIstanbul(pathname, 0, {source: entry.source}, path => {
|
||
|
const excluded = excludes.filter(e => path.includes(e));
|
||
|
return excluded.length > 0;
|
||
|
});
|
||
|
|
||
|
try {
|
||
|
await converter.load();
|
||
|
converter.applyCoverage(entry.functions);
|
||
|
coverageMap.merge(converter.toIstanbul());
|
||
|
} catch(error) {
|
||
|
console.error(error, "load", entry.url);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const watermarks = undefined; // used in check coverage ignored here
|
||
|
|
||
|
const context = libReport.createContext({
|
||
|
dir: "coverage",
|
||
|
watermarks,
|
||
|
coverageMap
|
||
|
});
|
||
|
|
||
|
["text","html"].forEach(format => {
|
||
|
reports.create(format, {
|
||
|
skipEmpty: false,
|
||
|
skipFull: true,
|
||
|
maxCols: 100
|
||
|
}).execute(context);
|
||
|
});
|
||
|
|
||
|
process.exit(0);
|
||
|
}
|