Second commit

uport
Alex Rea 8 years ago
parent 3a7a70fe21
commit 165694d3cf
  1. 27
      instrumentSolidity.js
  2. 75
      runCoveredTests.js

@ -1,12 +1,14 @@
var SolidityParser = require("solidity-parser");
var path = require("path");
module.exports = function(pathToFile, instrument){
var result = SolidityParser.parseFile("./" + pathToFile);
var instrumented = "";
const __INDENTATION__ = " ";
var parse = {};
var runnableLines=[];
var linecount = 1;
var fileName = path.basename(pathToFile);
var dottable = ['msg', 'tx', 'this'];
parse["AssignmentExpression"] = function (expression){
@ -81,7 +83,6 @@ module.exports = function(pathToFile, instrument){
}
parse["IfStatement"] = function(expression){
console.log(expression);
var retval = "if (";
retval += parse[expression.test.type](expression.test) + "){" + parse[expression.consequent.type](expression.consequent) + "}";
return retval;
@ -119,8 +120,10 @@ module.exports = function(pathToFile, instrument){
}
parse["BlockStatement"] = function(expression){
console.log(expression);
return 'BLOCKSTATEMENT'
if (expression.body.length>1){
console.log('bigger blockstatement...')
}
return parse[expression.body[0].type](expression.body[0]);
}
function newLine(lastchar){
@ -140,7 +143,7 @@ module.exports = function(pathToFile, instrument){
if (content.type === "ContractStatement"){
instrumented += 'contract ' + content.name + ' {' + newLine('{');
//Inject our coverage event;
instrumented += "event Coverage(string contract, uint256 lineNumber);\n"; //We're injecting this, so don't count the newline
instrumented += "event Coverage(string fileName, uint256 lineNumber);\n"; //We're injecting this, so don't count the newline
for (x in content.body){
printBody(content.body[x], indented+1, cover);
@ -160,6 +163,15 @@ module.exports = function(pathToFile, instrument){
instrumented+='{' + newLine('{');
printBody(content.body, indented+1, instrument);
instrumented+=__INDENTATION__.repeat(indented) +'}' + newLine('}');
}else if (content.type === "LibraryStatement"){
instrumented += 'library ' + content.name + ' {' + newLine('{');
//Inject our coverage event;
instrumented += "event Coverage(string fileName, uint256 lineNumber);\n"; //We're injecting this, so don't count the newline
for (x in content.body){
printBody(content.body[x], indented+1, cover);
}
instrumented += '}' + newLine('}');
}else{
for (x in content.body){
printBody(content.body[x], indented, cover);
@ -168,7 +180,8 @@ module.exports = function(pathToFile, instrument){
}else{
if (parse[content.type]!==undefined){
if (cover){
instrumented += __INDENTATION__.repeat(indented) +"Coverage(" + linecount + ");\n";
instrumented += __INDENTATION__.repeat(indented) +"Coverage('" + fileName + "'," + linecount + ");\n";
runnableLines.push(linecount);
}
instrumented += __INDENTATION__.repeat(indented) + parse[content.type](content);
instrumented += newLine(instrumented.slice(-1));
@ -181,6 +194,6 @@ module.exports = function(pathToFile, instrument){
return instrumented;
return {contract: instrumented, runnableLines: runnableLines};
}

@ -0,0 +1,75 @@
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var shell = require('shelljs');
var SolidityCoder = require("web3/lib/solidity/coder.js");
var coverage = {};
var fs = require('fs');
var path = require('path');
var getInstrumentedVersion = require('./instrumentSolidity.js');
shell.mkdir('./canonicalContracts/');
shell.mv('./contracts/', './originalContracts');
shell.mkdir('./contracts/');
//For each contract in originalContracts, get the canonical version and the instrumented version
shell.ls('./originalContracts/*.sol').forEach(function(file) {
if (file !== './originalContracts/Migrations.sol') {
var instrumentedContractInfo = getInstrumentedVersion(file, true);
var canonicalContractInfo = getInstrumentedVersion(file, false);
fs.writeFileSync('./canonicalContracts/' + path.basename(file), canonicalContractInfo.contract);
fs.writeFileSync('./contracts/' + path.basename(file), instrumentedContractInfo.contract);
}
shell.cp("./originalContracts/Migrations.sol", "./contracts/Migrations.sol");
});
var filter = web3.eth.filter('latest');
var res = web3.currentProvider.send({
jsonrpc: '2.0',
method: 'eth_newFilter',
params: [{ "fromBlock": "0x0", "toBlock": "latest" }],
id: new Date().getTime()
});
var filterid = res.result;
shell.exec("truffle test");
//Again, once that truffle issue gets solved, we don't have to call these again here
shell.ls('./originalContracts/*.sol').forEach(function(file) {
if (file !== './originalContracts/Migrations.sol') {
var canonicalContractPath = path.resolve('./canonicalContracts/' + path.basename(file));
coverage[canonicalContractPath] = { "l": {}, "path": canonicalContractPath, "s": {}, "b": {}, "f": {}, "fnMap": {}, "statementMap": {}, "branchMap": {} };
var instrumentedContractInfo = getInstrumentedVersion(file, true);
var canonicalContractInfo = getInstrumentedVersion(file, false);
for (idx in instrumentedContractInfo.runnableLines) {
coverage[canonicalContractPath]["l"][instrumentedContractInfo.runnableLines[idx]] = 0;
}
}
})
var res = web3.currentProvider.send({
jsonrpc: '2.0',
method: 'eth_getFilterChanges',
params: [filterid],
id: new Date().getTime()
});
events = res.result;
for (idx in res.result) {
var event = res.result[idx];
if (event.topics.indexOf("0xb8995a65f405d9756b41a334f38d8ff0c93c4934e170d3c1429c3e7ca101014d") >= 0) {
var data = SolidityCoder.decodeParams(["string", "uint256"], event.data.replace("0x", ""));
var canonicalContractPath = path.resolve('./canonicalContracts/' + path.basename(data[0]));
coverage[canonicalContractPath]["l"][data[1].toNumber()] += 1;
}
}
fs.writeFileSync('./coverage.json', JSON.stringify(coverage));
shell.exec("istanbul report text")
shell.rm('-rf', './contracts');
shell.rm('-rf', './canonicalContracts');
shell.mv('./originalContracts', './contracts');
Loading…
Cancel
Save