This is the template project that's checked out and configured when you run the bando-up command from ljsthw-bandolier. This is where the code really lives.
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.
bandolier-template/commands/coverage.js

106 lines
3.0 KiB

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);
}