From a819042f6ea5fffe0c7d7a80e09669193e7208a8 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 19 Apr 2020 15:33:40 -0700 Subject: [PATCH] Add initial OR coverage test cases --- .../solidity/contracts/or/and-or-brackets.sol | 11 + test/sources/solidity/contracts/or/and-or.sol | 11 + test/sources/solidity/contracts/or/bzx-or.sol | 19 + test/sources/solidity/contracts/or/if-or.sol | 11 + .../solidity/contracts/or/multi-or.sol | 11 + .../solidity/contracts/or/require-or.sol | 7 + .../solidity/contracts/or/return-or.sol | 8 + .../solidity/contracts/or/while-or.sol | 10 + test/units/or.js | 348 ++++++++++++++++++ 9 files changed, 436 insertions(+) create mode 100644 test/sources/solidity/contracts/or/and-or-brackets.sol create mode 100644 test/sources/solidity/contracts/or/and-or.sol create mode 100644 test/sources/solidity/contracts/or/bzx-or.sol create mode 100644 test/sources/solidity/contracts/or/if-or.sol create mode 100644 test/sources/solidity/contracts/or/multi-or.sol create mode 100644 test/sources/solidity/contracts/or/require-or.sol create mode 100644 test/sources/solidity/contracts/or/return-or.sol create mode 100644 test/sources/solidity/contracts/or/while-or.sol create mode 100644 test/units/or.js diff --git a/test/sources/solidity/contracts/or/and-or-brackets.sol b/test/sources/solidity/contracts/or/and-or-brackets.sol new file mode 100644 index 0000000..9585918 --- /dev/null +++ b/test/sources/solidity/contracts/or/and-or-brackets.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(uint x) public { + if ((x == 1) && (x == 2 || true)) { + /* ignore */ + } else { + revert(); + } + } +} diff --git a/test/sources/solidity/contracts/or/and-or.sol b/test/sources/solidity/contracts/or/and-or.sol new file mode 100644 index 0000000..e15fa66 --- /dev/null +++ b/test/sources/solidity/contracts/or/and-or.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(uint x) public { + if (x == 1 && true || x == 2) { + /* ignore */ + } else { + revert(); + } + } +} diff --git a/test/sources/solidity/contracts/or/bzx-or.sol b/test/sources/solidity/contracts/or/bzx-or.sol new file mode 100644 index 0000000..786e6e6 --- /dev/null +++ b/test/sources/solidity/contracts/or/bzx-or.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.5.0; + +contract Test { + function isFalse(uint _a, uint _b) public pure returns (bool){ + return false; + } + + function a(uint x) public { + require(( + x == 1 && + x == 2 ) || + !isFalse( + x, + 3 + ), + "unhealthy position" + ); + } +} diff --git a/test/sources/solidity/contracts/or/if-or.sol b/test/sources/solidity/contracts/or/if-or.sol new file mode 100644 index 0000000..8cf7c0d --- /dev/null +++ b/test/sources/solidity/contracts/or/if-or.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(uint x) public { + if (x == 1 || x == 2) { + /* ignore */ + } else { + revert(); + } + } +} diff --git a/test/sources/solidity/contracts/or/multi-or.sol b/test/sources/solidity/contracts/or/multi-or.sol new file mode 100644 index 0000000..85d0b59 --- /dev/null +++ b/test/sources/solidity/contracts/or/multi-or.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(uint x) public { + if ((x == 1) || (x == 2 || true)) { + /* ignore */ + } else { + revert(); + } + } +} diff --git a/test/sources/solidity/contracts/or/require-or.sol b/test/sources/solidity/contracts/or/require-or.sol new file mode 100644 index 0000000..5a9944b --- /dev/null +++ b/test/sources/solidity/contracts/or/require-or.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(uint x) public { + require(x == 1 || x == 2); + } +} diff --git a/test/sources/solidity/contracts/or/return-or.sol b/test/sources/solidity/contracts/or/return-or.sol new file mode 100644 index 0000000..d0ba26d --- /dev/null +++ b/test/sources/solidity/contracts/or/return-or.sol @@ -0,0 +1,8 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(uint x) public pure returns (bool) { + return (x == 1 && true) || + (x == 2 && true); + } +} diff --git a/test/sources/solidity/contracts/or/while-or.sol b/test/sources/solidity/contracts/or/while-or.sol new file mode 100644 index 0000000..5bb4cc7 --- /dev/null +++ b/test/sources/solidity/contracts/or/while-or.sol @@ -0,0 +1,10 @@ +pragma solidity ^0.5.0; + +contract Test { + function a(uint x) public { + uint counter; + while( (x == 1 || x == 2) && counter < 2 ){ + counter++; + } + } +} diff --git a/test/units/or.js b/test/units/or.js new file mode 100644 index 0000000..a52e6a1 --- /dev/null +++ b/test/units/or.js @@ -0,0 +1,348 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); + +const ganache = require('ganache-core-sc'); +const Coverage = require('./../../lib/coverage'); + +describe('logical OR branches', () => { + let coverage; + let provider; + let collector; + + before(async () => ({ provider, collector } = await util.initializeProvider(ganache))); + beforeEach(() => coverage = new Coverage()); + after((done) => provider.close(done)); + + // if (x == 1 || x == 2) { } else ... + it('should cover an if statement with a simple OR condition (single branch)', async function() { + const contract = await util.bootstrapCoverage('or/if-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // if (x == 1 || x == 2) { } else ... + it('should cover an if statement with a simple OR condition (both branches)', async function() { + const contract = await util.bootstrapCoverage('or/if-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + await contract.instance.a(2); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 2, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [2, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 2, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 2, + }); + }); + + // require(x == 1 || x == 2) + it('should cover a require statement with a simple OR condition (single branch)', async function() { + const contract = await util.bootstrapCoverage('or/require-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // require(x == 1 || x == 2) + it('should cover a require statement with a simple OR condition (both branches)', async function() { + const contract = await util.bootstrapCoverage('or/require-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + await contract.instance.a(2); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 2, + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [2, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 2, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 2, + }); + }); + + // while( (x == 1 || x == 2) && counter < 2 ){ + it('should cover a while statement with a simple OR condition (single branch)', async function() { + const contract = await util.bootstrapCoverage('or/while-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 6: 1, 7: 2 + }); + assert.deepEqual(mapping[util.filePath].b, { + + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1 + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // while( (x == 1 || x == 2) && counter < 2 ){ + it('should cover a while statement with a simple OR condition (both branches)', async function() { + const contract = await util.bootstrapCoverage('or/while-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + await contract.instance.a(2); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 2, 6: 2, 7: 4 + }); + assert.deepEqual(mapping[util.filePath].b, { + + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 2, 2: 2 + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 2, + }); + }); + + // return (x == 1 && true) || (x == 2 && true); + it('should cover a return statement with ANDED OR conditions (single branch)', async function() { + const contract = await util.bootstrapCoverage('or/return-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, + }); + assert.deepEqual(mapping[util.filePath].b, { + + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // return (x == 1 && true) || (x == 2 && true); + it('should cover a return statement with ANDED OR conditions (both branches)', async function() { + const contract = await util.bootstrapCoverage('or/return-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + await contract.instance.a(2); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 2, + }); + assert.deepEqual(mapping[util.filePath].b, { + + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 2, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 2, + }); + }); + + //if (x == 1 && true || x == 2) { + it('should cover an if statement with OR and AND conditions (single branch)', async function() { + const contract = await util.bootstrapCoverage('or/and-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + //if (x == 1 && true || x == 2) { + it('should cover an if statement with OR and AND conditions (both branches)', async function() { + const contract = await util.bootstrapCoverage('or/and-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + await contract.instance.a(2); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 2, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [2, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 2, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 2, + }); + }); + + // if ((x == 1) && (x == 2 || true)) { + it('should cover an if statement with bracked ANDED OR and AND conditions (both branches)', async function() { + const contract = await util.bootstrapCoverage('or/and-or-brackets', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // if ((x == 1) || (x == 2 || true)) { + it('should cover an if statement with multiple (bracketed) OR conditions (branch 1)', async function() { + const contract = await util.bootstrapCoverage('or/multi-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(1); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // if ((x == 1) || (x == 2 || true)) { + it('should cover an if statement with multiple (bracketed) OR conditions (branch 2)', async function() { + const contract = await util.bootstrapCoverage('or/multi-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(2); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + // if ((x == 1) || (x == 2 || true)) { + it('should cover an if statement with multiple (bracketed) OR conditions (branch 3)', async function() { + const contract = await util.bootstrapCoverage('or/multi-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(3); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 8: 0 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 0, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, + }); + }); + + it('should cover the bzx example', async function(){ + const contract = await util.bootstrapCoverage('or/bzx-or', provider, collector); + coverage.addContract(contract.instrumented, util.filePath); + await contract.instance.a(3); + + const mapping = coverage.generate(contract.data, util.pathPrefix); + + assert.deepEqual(mapping[util.filePath].l, { + 5: 1, 9: 1 + }); + assert.deepEqual(mapping[util.filePath].b, { + 1: [1, 0], + }); + assert.deepEqual(mapping[util.filePath].s, { + 1: 1, 2: 1, + }); + assert.deepEqual(mapping[util.filePath].f, { + 1: 1, 2: 1 + }); + }) +});