Merge pull request #33 from JoinColony/bugfixes

Misc Bugfixes
uport
area 8 years ago committed by GitHub
commit e118454511
  1. 26
      instrumentSolidity.js
  2. 19
      test/if.js
  3. 14
      test/loops.js
  4. 10
      test/sources/statements/post-close-brace.sol
  5. 30
      test/statements.js

@ -77,7 +77,7 @@ module.exports = function(contract, fileName, instrumentingActive){
function instrumentStatement(expression){ function instrumentStatement(expression){
canCover = false; canCover = false;
//Can only instrument here if this is a self-contained statement //Can only instrument here if this is a self-contained statement
//If it's preceeded by a '{', we're good //If it's preceeded by a '{', we're good
if ( contract.slice(contract.slice(0,expression.start).lastIndexOf('{')+1, expression.start).trim().length===0 ){ if ( contract.slice(contract.slice(0,expression.start).lastIndexOf('{')+1, expression.start).trim().length===0 ){
@ -89,6 +89,11 @@ module.exports = function(contract, fileName, instrumentingActive){
canCover=true; canCover=true;
} }
//If it's preceeded by a '}', we're good
if ( contract.slice(contract.slice(0,expression.start).lastIndexOf('}')+1, expression.start).trim().length===0 ){
canCover=true;
}
if (!canCover){return;} if (!canCover){return;}
//We need to work out the lines and columns the expression starts and ends //We need to work out the lines and columns the expression starts and ends
statementId +=1; statementId +=1;
@ -468,22 +473,3 @@ module.exports = function(contract, fileName, instrumentingActive){
return {contract: contract, runnableLines: runnableLines, fnMap: fnMap, branchMap: branchMap, statementMap: statementMap}; return {contract: contract, runnableLines: runnableLines, fnMap: fnMap, branchMap: branchMap, statementMap: statementMap};
} }

@ -26,7 +26,7 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}); }).catch(done);
}); });
// Runs: a(1) => if (x == 1) x = 2; // Runs: a(1) => if (x == 1) x = 2;
@ -44,7 +44,7 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}).catch(err => {console.log(err); done() }) }).catch(done)
}) })
it('should cover an if statement with multiline bracketed consequent', (done) => { it('should cover an if statement with multiline bracketed consequent', (done) => {
@ -61,7 +61,7 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}); }).catch(done);
}); });
// Runs: a(1) => if (x == 1)\n x = 3; // Runs: a(1) => if (x == 1)\n x = 3;
@ -78,7 +78,7 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done);
}) })
it('should cover a simple if statement with a failing condition', (done) => { it('should cover a simple if statement with a failing condition', (done) => {
@ -95,7 +95,7 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 0}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 0});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}).catch(err => {console.log(err); done() }) }).catch(done);
}); });
// Runs: a(2) => if (x == 1){\n throw;\n }else{\n x = 5; \n} // Runs: a(2) => if (x == 1){\n throw;\n }else{\n x = 5; \n}
@ -112,7 +112,7 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 0, 3: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 0, 3: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done);
}); });
it('should cover an if statement with an unbracketed alternate',function(done){ it('should cover an if statement with an unbracketed alternate',function(done){
@ -128,7 +128,7 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 0, 3: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 0, 3: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done);
}) })
it('should cover nested if statements with missing else statements',function(done){ it('should cover nested if statements with missing else statements',function(done){
@ -136,7 +136,6 @@ describe('if, else, and else if statements', function(){
const info = getInstrumentedVersion(contract, fileName, true); const info = getInstrumentedVersion(contract, fileName, true);
const coverage = new CoverageMap(); const coverage = new CoverageMap();
coverage.addContract(info, filePath); coverage.addContract(info, filePath);
vm.execute(info.contract, 'a', [2, 3, 3]).then(events => { vm.execute(info.contract, 'a', [2, 3, 3]).then(events => {
const mapping = coverage.generate(events, pathPrefix); const mapping = coverage.generate(events, pathPrefix);
assert.deepEqual(mapping[filePath].l, {5: 1, 7: 1}); assert.deepEqual(mapping[filePath].l, {5: 1, 7: 1});
@ -144,6 +143,6 @@ describe('if, else, and else if statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done)
}) })
}) })

@ -26,7 +26,7 @@ describe('for and while statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 10}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 10});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done);
}); });
it('should cover a for statement with an unbracketed body', (done) => { it('should cover a for statement with an unbracketed body', (done) => {
@ -35,7 +35,7 @@ describe('for and while statements', function(){
const coverage = new CoverageMap(); const coverage = new CoverageMap();
coverage.addContract(info, filePath); coverage.addContract(info, filePath);
// Runs: a() => for(var x = 1; x < 10; x++)\n sha3(x);\n // Runs: a() => for(var x = 1; x < 10; x++)\n sha3(x);\n
vm.execute(info.contract, 'a', []).then(events => { vm.execute(info.contract, 'a', []).then(events => {
const mapping = coverage.generate(events, pathPrefix); const mapping = coverage.generate(events, pathPrefix);
assert.deepEqual(mapping[filePath].l, {5: 1, 6: 10}); assert.deepEqual(mapping[filePath].l, {5: 1, 6: 10});
@ -43,7 +43,7 @@ describe('for and while statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 10}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 10});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done);
}); });
it('should cover a while statement with an bracketed body (multiline)', (done) => { it('should cover a while statement with an bracketed body (multiline)', (done) => {
@ -60,7 +60,7 @@ describe('for and while statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1, 3: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1, 3: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done);
}); });
it('should cover a while statement with an unbracketed body (multiline)', (done) => { it('should cover a while statement with an unbracketed body (multiline)', (done) => {
@ -69,7 +69,7 @@ describe('for and while statements', function(){
const coverage = new CoverageMap(); const coverage = new CoverageMap();
coverage.addContract(info, filePath); coverage.addContract(info, filePath);
// Runs: a() => var t = true;\n while(t)\n t = false;\n // Runs: a() => var t = true;\n while(t)\n t = false;\n
vm.execute(info.contract, 'a', []).then(events => { vm.execute(info.contract, 'a', []).then(events => {
const mapping = coverage.generate(events, pathPrefix); const mapping = coverage.generate(events, pathPrefix);
assert.deepEqual(mapping[filePath].l, {5: 1, 6: 1, 7: 1}); assert.deepEqual(mapping[filePath].l, {5: 1, 6: 1, 7: 1});
@ -77,6 +77,6 @@ describe('for and while statements', function(){
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1, 3: 1}); assert.deepEqual(mapping[filePath].s, {1: 1, 2: 1, 3: 1});
assert.deepEqual(mapping[filePath].f, {1: 1}); assert.deepEqual(mapping[filePath].f, {1: 1});
done(); done();
}) }).catch(done);
}); });
}) })

@ -0,0 +1,10 @@
pragma solidity ^0.4.3;
contract Test {
function a(uint x) {
if (x>1){
x=3;
}
x=2;
}
}

@ -1,6 +1,10 @@
var solc = require('solc'); var solc = require('solc');
var getInstrumentedVersion = require('./../instrumentSolidity.js'); var getInstrumentedVersion = require('./../instrumentSolidity.js');
var util = require('./util/util.js'); var util = require('./util/util.js');
const CoverageMap = require('./../coverageMap');
const path = require('path');
const vm = require('./util/vm');
const assert = require('assert');
/** /**
* NB: passing '1' to solc as an option activates the optimiser * NB: passing '1' to solc as an option activates the optimiser
@ -8,24 +12,29 @@ var util = require('./util/util.js');
* and passing the error to mocha. * and passing the error to mocha.
*/ */
describe('generic statements', function(){ describe('generic statements', function(){
const fileName = 'test.sol';
const filePath = path.resolve('./test.sol');
const pathPrefix = './';
it('should compile after instrumenting a single statement (first line of function)', function(){ it('should compile after instrumenting a single statement (first line of function)', function(){
var contract = util.getCode('statements/single.sol'); var contract = util.getCode('statements/single.sol');
var info = getInstrumentedVersion(contract, "test.sol", true); var info = getInstrumentedVersion(contract, "test.sol", true);
var output = solc.compile(info.contract, 1); var output = solc.compile(info.contract, 1);
util.report(output.errors); util.report(output.errors);
}) })
it('should compile after instrumenting multiple statements', function(){ it('should compile after instrumenting multiple statements', function(){
var contract = util.getCode('statements/multiple.sol'); var contract = util.getCode('statements/multiple.sol');
var info = getInstrumentedVersion(contract, "test.sol", true); var info = getInstrumentedVersion(contract, "test.sol", true);
var output = solc.compile(info.contract, 1); var output = solc.compile(info.contract, 1);
util.report(output.errors); util.report(output.errors);
}) })
it('should compile after instrumenting a statement that is a function argument (single line)', function(){ it('should compile after instrumenting a statement that is a function argument (single line)', function(){
var contract = util.getCode('statements/fn-argument.sol'); var contract = util.getCode('statements/fn-argument.sol');
var info = getInstrumentedVersion(contract, "test.sol", true); var info = getInstrumentedVersion(contract, "test.sol", true);
var output = solc.compile(info.contract, 1); var output = solc.compile(info.contract, 1);
util.report(output.errors); util.report(output.errors);
}) })
@ -35,4 +44,19 @@ describe('generic statements', function(){
var output = solc.compile(info.contract, 1); var output = solc.compile(info.contract, 1);
util.report(output.errors); util.report(output.errors);
}) })
it.only('should cover a statement following a close brace', (done) => {
const contract = util.getCode('statements/post-close-brace.sol');
const info = getInstrumentedVersion(contract, "test.sol", true);
const coverage = new CoverageMap();
coverage.addContract(info, filePath);
vm.execute(info.contract, 'a', [1]).then(events => {
const mapping = coverage.generate(events, pathPrefix);
assert.deepEqual(mapping[filePath].l, {5: 1, 6: 0, 8: 1});
assert.deepEqual(mapping[filePath].b, {1: [0, 1]});
assert.deepEqual(mapping[filePath].s, {1: 1, 2: 0, 3: 1});
assert.deepEqual(mapping[filePath].f, {1: 1});
done();
}).catch(done);
});
}) })

Loading…
Cancel
Save