embark/lib/modules/coverage/contract_sources.js

100 lines
2.8 KiB
JavaScript
Raw Normal View History

2018-08-01 15:48:17 +00:00
const fs = require('fs');
2018-08-07 19:26:39 +00:00
const path = require('path');
2018-08-01 15:48:17 +00:00
const ContractSource = require('./contract_source');
class ContractSources {
constructor(files) {
this.files = {};
2018-08-07 19:26:39 +00:00
switch(Object.prototype.toString.call(files)) {
case '[object Object]':
Object.keys(files).forEach((file) => {
var basename = path.basename(file);
this.files[basename] = new ContractSource(basename, files[file]);
});
break;
case '[object String]':
// No 'break' statement here on purpose, as it shares
// the logic below.
files = [files];
2018-08-09 20:46:20 +00:00
// falls through
2018-08-07 19:26:39 +00:00
case '[object Array]':
files.forEach((file) => {
var basename = path.basename(file);
try {
var content = fs.readFileSync(file).toString();
this.files[basename] = new ContractSource(basename, content);
} catch(e) {
throw new Error(`Error loading ${file}: ${e.code}`);
}
});
break;
2018-08-09 20:46:20 +00:00
default:
throw new Error(`Don't know how to initialize with ${Object.prototype.toString.call(files)}`);
2018-08-07 19:26:39 +00:00
}
2018-08-01 15:48:17 +00:00
}
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) {
2018-08-07 19:26:39 +00:00
var basename = path.basename(file);
var contractSource = this.files[basename];
2018-08-09 20:46:20 +00:00
if(!contractSource) continue;
2018-08-07 19:26:39 +00:00
contractSource.parseSolcOutput(output.sources[file], output.contracts[file]);
2018-08-01 15:48:17 +00:00
}
}
generateCodeCoverage(trace) {
var coverageReport = {};
for(var file in this.files) {
var contractSource = this.files[file];
coverageReport[file] = contractSource.generateCodeCoverage(trace);
}
2018-08-07 19:26:39 +00:00
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) => {
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;
2018-08-01 15:48:17 +00:00
}
}
module.exports = ContractSources;