Add try / catch unit tests (#857)

pull/858/head
cgewecke 10 months ago committed by GitHub
parent 01ab173845
commit 042a99e638
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 11
      test/sources/solidity/contracts/try/try-catch-empty-blocks.sol
  2. 16
      test/sources/solidity/contracts/try/try-error-block.sol
  3. 29
      test/sources/solidity/contracts/try/try-multi-block.sol
  4. 16
      test/sources/solidity/contracts/try/try-panic-block.sol
  5. 15
      test/sources/solidity/contracts/try/try-revert-block.sol
  6. 123
      test/units/try.js

@ -0,0 +1,11 @@
pragma solidity >=0.8.0 <0.9.0;
contract Test {
function op(bool y) external {
require(y);
}
function a(bool x) external {
try this.op(x) { } catch { }
}
}

@ -0,0 +1,16 @@
pragma solidity >=0.8.0 <0.9.0;
contract Test {
function op(bool y) external returns (uint){
require(y, "sorry");
return 1;
}
function a(bool x) external returns (uint) {
try this.op(x) returns (uint v) {
return v;
} catch Error(string memory /*reason*/) {
return 0;
}
}
}

@ -0,0 +1,29 @@
pragma solidity >=0.8.0 <0.9.0;
contract Test {
function op(uint y) external returns (uint){
uint a = 100;
uint b = 0;
if (y == 0)
return 0;
if (y == 1)
require(false, 'sorry');
if (y == 2)
uint x = (a / b);
if (y == 3)
revert();
}
function a(uint x) external returns (uint) {
try this.op(x) returns (uint v) {
return 0;
} catch Error(string memory /*reason*/) {
return 1;
} catch Panic(uint /*errorCode*/) {
return 2;
} catch (bytes memory /*lowLevelData*/) {
return 3;
}
}
}

@ -0,0 +1,16 @@
pragma solidity >=0.8.0 <0.9.0;
contract Test {
function op(bool y) external returns (uint){
uint x = 100 / 0;
return x;
}
function a(bool x) external pure returns (uint) {
try this.op(x) returns (uint v) {
return v;
} catch Panic(uint /*errorCode*/) {
return 0;
}
}
}

@ -0,0 +1,15 @@
pragma solidity >=0.8.0 <0.9.0;
contract Test {
function op(bool y) external returns (uint){
if (y == false) revert();
}
function a(bool x) external pure returns (uint) {
try this.op(x) returns (uint v) {
return v;
} catch (bytes memory /*lowLevelData*/) {
return 0;
}
}
}

@ -0,0 +1,123 @@
const assert = require('assert');
const util = require('./../util/util.js');
const Coverage = require('./../../lib/coverage');
const Api = require('./../../lib/api')
describe.only('try / catch branches', () => {
let coverage;
let api;
before(async () => api = new Api({silent: true}));
beforeEach(() => coverage = new Coverage());
after(async() => await api.finish());
it('should cover a try/catch statement with empty blocks (success branch only)', async function() {
const contract = await util.bootstrapCoverage('try/try-catch-empty-blocks', api, this.provider, );
coverage.addContract(contract.instrumented, util.filePath);
await contract.instance.a(true, contract.gas);
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
});
});
it('should cover a try/catch statement with empty blocks (both branches)', async function() {
const contract = await util.bootstrapCoverage('try/try-catch-empty-blocks', api, this.provider, );
coverage.addContract(contract.instrumented, util.filePath);
await contract.instance.a(true, contract.gas);
try { await contract.instance.a(false, contract.gas) } catch(err) { /* ignore */ }
const mapping = coverage.generate(contract.data, util.pathPrefix);
assert.deepEqual(mapping[util.filePath].l, {
5:2,9:2
});
assert.deepEqual(mapping[util.filePath].b, {
1:[1,1]
});
assert.deepEqual(mapping[util.filePath].s, {
1:2,2:2
});
assert.deepEqual(mapping[util.filePath].f, {
1:2,2:2
});
});
it('should cover a try/catch statement with an Error block (success branch only)', async function() {
const contract = await util.bootstrapCoverage('try/try-error-block', api, this.provider, );
coverage.addContract(contract.instrumented, util.filePath);
await contract.instance.a(true, contract.gas);
const mapping = coverage.generate(contract.data, util.pathPrefix);
assert.deepEqual(mapping[util.filePath].l, {
5:1,6:1,10:1,11:1,13:0
});
assert.deepEqual(mapping[util.filePath].b, {
1:[1,0]
});
assert.deepEqual(mapping[util.filePath].s, {
1:1,2:1,3:1,4:1,5:0
});
assert.deepEqual(mapping[util.filePath].f, {
1:1,2:1
});
});
it('should cover a try/catch statement with an Error block (both branches)', async function() {
const contract = await util.bootstrapCoverage('try/try-error-block', api, this.provider, );
coverage.addContract(contract.instrumented, util.filePath);
await contract.instance.a(true, contract.gas);
try { await contract.instance.a(false, contract.gas) } catch(err) { /* ignore */ }
const mapping = coverage.generate(contract.data, util.pathPrefix);
assert.deepEqual(mapping[util.filePath].l, {
5:2,6:1,10:2,11:1,13:1
});
assert.deepEqual(mapping[util.filePath].b, {
1:[1,1]
});
assert.deepEqual(mapping[util.filePath].s, {
1:2,2:1,3:2,4:1,5:1
});
assert.deepEqual(mapping[util.filePath].f, {
1:2,2:2
});
});
it('should cover a try/catch statement with multi-block catch clauses (middle-block)', async function() {
const contract = await util.bootstrapCoverage('try/try-multi-block', api, this.provider, );
coverage.addContract(contract.instrumented, util.filePath);
await contract.instance.a(0, contract.gas);
try { await contract.instance.a(2, contract.gas) } catch(err) { /* ignore */ }
const mapping = coverage.generate(contract.data, util.pathPrefix);
assert.deepEqual(mapping[util.filePath].l, {
5:2,6:2,8:2,9:1,10:1,11:0,12:1,13:1,14:0,15:0,19:2,20:1,22:0,24:1,26:0
});
assert.deepEqual(mapping[util.filePath].b, {
1:[1,1],2:[0,1],3:[0,0],4:[1,0],5:[0,0]
});
assert.deepEqual(mapping[util.filePath].s, {
1:2,2:2,3:2,4:1,5:1,6:0,7:1,8:1,9:0,10:0,11:2,12:1,13:0,14:1,15:0
});
assert.deepEqual(mapping[util.filePath].f, {
1:2,2:2
});
});
});
Loading…
Cancel
Save