embark-area-51/lib/modules/coverage/contract_sources.js

102 lines
2.9 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const ContractSource = require('./contract_source');
class ContractSources {
constructor(files) {
this.files = {};
switch(Object.prototype.toString.call(files)) {
case '[object Object]':
Object.keys(files).forEach((file) => { this.addFile(file, files[file]); });
break;
case '[object String]':
// No 'break' statement here on purpose, as it shares
// the logic below.
files = [files];
// falls through
case '[object Array]':
files.forEach((file) => {
var content = fs.readFileSync(file).toString();
this.addFile(file, content);
});
break;
default:
throw new Error(`Don't know how to initialize with ${Object.prototype.toString.call(files)}`);
}
}
addFile(fullPath, contents) {
let basename = path.basename(fullPath);
if(this.files[basename]) return;
this.files[basename] = new ContractSource(basename, fullPath, contents);
}
toSolcInputs() {
var inputs = {};
for(var file in this.files) {
inputs[file] = {content: this.files[file].body};
}
return inputs;
}
parseSolcOutput(output) {
for(var file in output.contracts) {
var contractSource = this.files[path.basename(file)];
if(!contractSource) continue;
contractSource.parseSolcOutput(output.sources[file], output.contracts[file]);
}
}
generateCodeCoverage(trace) {
var coverageReport = {};
for(var file in this.files) {
if(this.files[file].isInterface()) continue;
coverageReport[file] = this.files[file].generateCodeCoverage(trace);
}
if(!this.coverageReport) {
this.coverageReport = coverageReport;
return this.coverageReport;
}
// We already have a previous coverage report, so we're merging results here.
Object.keys(coverageReport).forEach((file) => {
if(!this.coverageReport[file]) {
this.coverageReport[file] = coverageReport[file];
return;
}
// Increment counters for statements, functions and lines
['s', 'f', 'l'].forEach((countType) => {
Object.keys(coverageReport[file][countType]).forEach((id) => {
this.coverageReport[file][countType][id] += coverageReport[file][countType][id];
});
});
// Branch counts are tracked in a different manner so we'll do these now
Object.keys(coverageReport[file].b).forEach((id) => {
// FIXME in solc-tests, this is sometimes empty
if (!this.coverageReport[file].b[id] || !this.coverageReport[file].b[id].length) {
return;
}
this.coverageReport[file].b[id][0] += coverageReport[file].b[id][0];
this.coverageReport[file].b[id][1] += coverageReport[file].b[id][1];
});
});
return this.coverageReport;
}
}
module.exports = ContractSources;