Merge branch 'adriamb-master' into truffle3-adriamb

pull/1/head
cgewecke 8 years ago
commit cb833aa386
  1. 31
      coverageMap.js
  2. 18
      injector.js
  3. 6
      instrumentSolidity.js
  4. 3
      package.json
  5. 0
      runCoveredTests.js

@ -5,11 +5,7 @@
*/
const SolidityCoder = require('web3/lib/solidity/coder.js');
const path = require('path');
const lineTopic = 'b8995a65f405d9756b41a334f38d8ff0c93c4934e170d3c1429c3e7ca101014d';
const functionTopic = 'd4ce765fd23c5cc3660249353d61ecd18ca60549dd62cb9ca350a4244de7b87f';
const branchTopic = 'd4cf56ed5ba572684f02f889f12ac42d9583c8e3097802060e949bfbb3c1bff5';
const statementTopic = 'b51abbff580b3a34bbc725f2dc6f736e9d4b45a41293fd0084ad865a31fde0c8';
const keccak = require('keccakjs');
/**
* Converts solcover event data into an object that can be
@ -20,6 +16,10 @@ module.exports = class CoverageMap {
constructor() {
this.coverage = {};
this.lineTopics = [];
this.functionTopics = [];
this.branchTopics = [];
this.statementTopics = [];
}
/**
@ -29,6 +29,7 @@ module.exports = class CoverageMap {
* @param {String} canonicalContractPath target file location
* @return {Object} coverage map with all values set to zero
*/
addContract(info, canonicalContractPath) {
this.coverage[canonicalContractPath] = {
l: {},
@ -56,6 +57,17 @@ module.exports = class CoverageMap {
for (let x = 1; x <= Object.keys(info.statementMap).length; x++) {
this.coverage[canonicalContractPath].s[x] = 0;
}
const keccakhex = (x => {
const hash = new keccak(256); // eslint-disable-line new-cap
hash.update(x);
return hash.digest('hex');
});
this.lineTopics.push(keccakhex('__Coverage' + info.contractName + '(string,uint256)'));
this.functionTopics.push(keccakhex('__FunctionCoverage' + info.contractName + '(string,uint256)'));
this.branchTopics.push(keccakhex('__BranchCoverage' + info.contractName + '(string,uint256,uint256)'));
this.statementTopics.push(keccakhex('__StatementCoverage' + info.contractName + '(string,uint256)'));
}
/**
@ -68,19 +80,20 @@ module.exports = class CoverageMap {
generate(events, pathPrefix) {
for (let idx = 0; idx < events.length; idx++) {
const event = JSON.parse(events[idx]);
if (event.topics.indexOf(lineTopic) >= 0) {
if (event.topics.filter(t => this.lineTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].l[data[1].toNumber()] += 1;
} else if (event.topics.indexOf(functionTopic) >= 0) {
} else if (event.topics.filter(t => this.functionTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].f[data[1].toNumber()] += 1;
} else if (event.topics.indexOf(branchTopic) >= 0) {
} else if (event.topics.filter(t => this.branchTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].b[data[1].toNumber()][data[2].toNumber()] += 1;
} else if (event.topics.indexOf(statementTopic) >= 0) {
} else if (event.topics.filter(t => this.statementTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].s[data[1].toNumber()] += 1;

@ -6,27 +6,27 @@ injector.callEvent = function injectCallEvent(contract, fileName, injectionPoint
const linecount = (contract.instrumented.slice(0, injectionPoint).match(/\n/g) || []).length + 1;
contract.runnableLines.push(linecount);
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'Coverage(\'' + fileName + '\',' + linecount + ');\n' +
'__Coverage' + contract.contractName + '(\'' + fileName + '\',' + linecount + ');\n' +
contract.instrumented.slice(injectionPoint);
};
injector.callFunctionEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'FunctionCoverage(\'' + fileName + '\',' + injection.fnId + ');\n' +
'__FunctionCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.fnId + ');\n' +
contract.instrumented.slice(injectionPoint);
};
injector.callBranchEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
(injection.openBracket ? '{' : '') +
'BranchCoverage(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' +
'__BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' +
(injection.comma ? ',' : ';') +
contract.instrumented.slice(injectionPoint);
};
injector.callEmptyBranchEvent = function injectCallEmptyBranchEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'else { BranchCoverage(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ');}\n' +
'else { __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ');}\n' +
contract.instrumented.slice(injectionPoint);
};
@ -44,16 +44,16 @@ injector.literal = function injectLiteral(contract, fileName, injectionPoint, in
injector.statement = function injectStatement(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
' StatementCoverage(\'' + fileName + '\',' + injection.statementId + ');\n' +
' __StatementCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.statementId + ');\n' +
contract.instrumented.slice(injectionPoint);
};
injector.eventDefinition = function injectEventDefinition(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'event Coverage(string fileName, uint256 lineNumber);\n' +
'event FunctionCoverage(string fileName, uint256 fnId);\n' +
'event StatementCoverage(string fileName, uint256 statementId);\n' +
'event BranchCoverage(string fileName, uint256 branchId, uint256 locationIdx);\n' +
'event __Coverage' + contract.contractName + '(string fileName, uint256 lineNumber);\n' +
'event __FunctionCoverage' + contract.contractName + '(string fileName, uint256 fnId);\n' +
'event __StatementCoverage' + contract.contractName + '(string fileName, uint256 statementId);\n' +
'event __BranchCoverage' + contract.contractName + '(string fileName, uint256 branchId, uint256 locationIdx);\n' +
contract.instrumented.slice(injectionPoint);
};

@ -38,8 +38,12 @@ module.exports = function instrumentSolidity(contractSource, fileName) {
contract.preprocessed = preprocessor.run(contract.source);
contract.instrumented = contract.preprocessed;
ast = SolidityParser.parse(contract.preprocessed);
const contractStatement = ast.body.filter(node => node.type === 'ContractStatement');
contract.contractName = contractStatement[0].name;
parse[ast.type](contract, ast);
// var result = solparse.parse(contract);
@ -59,5 +63,7 @@ module.exports = function instrumentSolidity(contractSource, fileName) {
});
retValue.runnableLines = contract.runnableLines;
retValue.contract = contract.instrumented;
retValue.contractName = contractStatement[0].name;
return retValue;
};

@ -18,6 +18,7 @@
"commander": "^2.9.0",
"ethereumjs-testrpc": "https://github.com/sc-forks/testrpc-sc.git",
"istanbul": "^0.4.5",
"keccakjs": "^0.2.1",
"mkdirp": "^0.5.1",
"req-cwd": "^1.0.1",
"shelljs": "^0.7.4",
@ -37,6 +38,6 @@
"istanbul": "^0.4.5",
"merkle-patricia-tree": "~2.1.2",
"mocha": "^3.1.0",
"solc": "0.4.6"
"solc": "0.4.8"
}
}

Loading…
Cancel
Save