Moving some tests to semantic tests.

This commit is contained in:
Djordje Mijovic 2020-11-02 13:11:18 +01:00
parent be02db4950
commit 18a464f4f4
47 changed files with 123 additions and 255 deletions

View File

@ -536,39 +536,6 @@ BOOST_AUTO_TEST_CASE(for_loop)
)
}
BOOST_AUTO_TEST_CASE(for_loop_empty)
{
char const* sourceCode = R"(
contract test {
function f() public returns(uint ret) {
ret = 1;
for (;;) {
ret += 1;
if (ret >= 10) break;
}
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
auto for_loop_empty_cpp = []() -> u256
{
u256 ret = 1;
for (;;)
{
ret += 1;
if (ret >= 10) break;
}
return ret;
};
testContractAgainstCpp("f()", for_loop_empty_cpp);
)
}
BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)
{
char const* sourceCode = R"(
@ -648,85 +615,6 @@ BOOST_AUTO_TEST_CASE(for_loop_break_continue)
);
}
BOOST_AUTO_TEST_CASE(calling_other_functions)
{
char const* sourceCode = R"(
contract collatz {
function run(uint x) public returns(uint y) {
while ((y = x) > 1) {
if (x % 2 == 0) x = evenStep(x);
else x = oddStep(x);
}
}
function evenStep(uint x) public returns(uint y) {
return x / 2;
}
function oddStep(uint x) public returns(uint y) {
return 3 * x + 1;
}
}
)";
auto evenStep_cpp = [](u256 const& n) -> u256
{
return n / 2;
};
auto oddStep_cpp = [](u256 const& n) -> u256
{
return 3 * n + 1;
};
auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp](u256 n) -> u256
{
u256 y;
while ((y = n) > 1)
{
if (n % 2 == 0)
n = evenStep_cpp(n);
else
n = oddStep_cpp(n);
}
return y;
};
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(0));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(1));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(2));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(8));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(127));
)
}
BOOST_AUTO_TEST_CASE(many_local_variables)
{
char const* sourceCode = R"(
contract test {
function run(uint x1, uint x2, uint x3) public returns(uint y) {
uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100;
y = a + b + c + x1 + x2 + x3;
y += b + x2;
}
}
)";
auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256
{
u256 a = 0x1;
u256 b = 0x10;
u256 c = 0x100;
u256 y = a + b + c + x1 + x2 + x3;
return y + b + x2;
};
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
testContractAgainstCpp("run(uint256,uint256,uint256)", f, u256(0x1000), u256(0x10000), u256(0x100000));
)
}
BOOST_AUTO_TEST_CASE(short_circuiting)
{
char const* sourceCode = R"(
@ -819,149 +707,6 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types)
testContractAgainstCpp("run()", small_unsigned_types_cpp);
}
BOOST_AUTO_TEST_CASE(small_signed_types)
{
char const* sourceCode = R"(
contract test {
function run() public returns(int256 y) {
return -int32(10) * -int64(20);
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
auto small_signed_types_cpp = []() -> u256
{
return -int32_t(10) * -int64_t(20);
};
testContractAgainstCpp("run()", small_signed_types_cpp);
);
}
BOOST_AUTO_TEST_CASE(compound_assign)
{
char const* sourceCode = R"(
contract test {
uint value1;
uint value2;
function f(uint x, uint y) public returns (uint w) {
uint value3 = y;
value1 += x;
value3 *= x;
value2 *= value3 + value1;
return value2 += 7;
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
u256 value1;
u256 value2;
auto f = [&](u256 const& _x, u256 const& _y) -> u256
{
u256 value3 = _y;
value1 += _x;
value3 *= _x;
value2 *= value3 + value1;
return value2 += 7;
};
testContractAgainstCpp("f(uint256,uint256)", f, u256(0), u256(6));
testContractAgainstCpp("f(uint256,uint256)", f, u256(1), u256(3));
testContractAgainstCpp("f(uint256,uint256)", f, u256(2), u256(25));
testContractAgainstCpp("f(uint256,uint256)", f, u256(3), u256(69));
testContractAgainstCpp("f(uint256,uint256)", f, u256(4), u256(84));
testContractAgainstCpp("f(uint256,uint256)", f, u256(5), u256(2));
testContractAgainstCpp("f(uint256,uint256)", f, u256(6), u256(51));
testContractAgainstCpp("f(uint256,uint256)", f, u256(7), u256(48));
)
}
BOOST_AUTO_TEST_CASE(mapping_state)
{
char const* sourceCode = R"(
contract Ballot {
mapping(address => bool) canVote;
mapping(address => uint) voteCount;
mapping(address => bool) voted;
function getVoteCount(address addr) public returns (uint retVoteCount) {
return voteCount[addr];
}
function grantVoteRight(address addr) public {
canVote[addr] = true;
}
function vote(address voter, address vote) public returns (bool success) {
if (!canVote[voter] || voted[voter]) return false;
voted[voter] = true;
voteCount[vote] = voteCount[vote] + 1;
return true;
}
}
)";
class Ballot
{
public:
u256 getVoteCount(u160 _address) { return m_voteCount[_address]; }
void grantVoteRight(u160 _address) { m_canVote[_address] = true; }
bool vote(u160 _voter, u160 _vote)
{
if (!m_canVote[_voter] || m_voted[_voter]) return false;
m_voted[_voter] = true;
m_voteCount[_vote]++;
return true;
}
private:
map<u160, bool> m_canVote;
map<u160, u256> m_voteCount;
map<u160, bool> m_voted;
};
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
Ballot ballot;
auto getVoteCount = bind(&Ballot::getVoteCount, &ballot, _1);
auto grantVoteRight = bind(&Ballot::grantVoteRight, &ballot, _1);
auto vote = bind(&Ballot::vote, &ballot, _1, _2);
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// voting without vote right should be rejected
testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// grant vote rights
testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(0));
testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(1));
// vote, should increase 2's vote count
testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// vote again, should be rejected
testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// vote without right to vote
testContractAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// grant vote right and now vote again
testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(2));
testContractAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
)
}
BOOST_AUTO_TEST_CASE(mapping_state_inc_dec)
{
char const* sourceCode = R"(

View File

@ -0,0 +1,13 @@
contract test {
function f() public returns(uint ret) {
ret = 1;
for (;;) {
ret += 1;
if (ret >= 10) break;
}
}
}
// ====
// compileViaYul: also
// ----
// f() -> 10

View File

@ -0,0 +1,22 @@
contract collatz {
function run(uint x) public returns(uint y) {
while ((y = x) > 1) {
if (x % 2 == 0) x = evenStep(x);
else x = oddStep(x);
}
}
function evenStep(uint x) public returns(uint y) {
return x / 2;
}
function oddStep(uint x) public returns(uint y) {
return 3 * x + 1;
}
}
// ====
// compileViaYul: also
// ----
// run(uint256): 0 -> 0
// run(uint256): 1 -> 1
// run(uint256): 2 -> 1
// run(uint256): 8 -> 1
// run(uint256): 127 -> 1

View File

@ -0,0 +1,11 @@
contract test {
function run(uint x1, uint x2, uint x3) public returns(uint y) {
uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100;
y = a + b + c + x1 + x2 + x3;
y += b + x2;
}
}
// ====
// compileViaYul: also
// ----
// run(uint256,uint256,uint256): 0x1000, 0x10000, 0x100000 -> 0x121121

View File

@ -0,0 +1,9 @@
contract test {
function run() public returns(int256 y) {
return -int32(10) * -int64(20);
}
}
// ====
// compileViaYul: also
// ----
// run() -> 200

View File

@ -0,0 +1,22 @@
contract test {
uint value1;
uint value2;
function f(uint x, uint y) public returns (uint w) {
uint value3 = y;
value1 += x;
value3 *= x;
value2 *= value3 + value1;
return value2 += 7;
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,uint256): 0, 6 -> 7
// f(uint256,uint256): 1, 3 -> 0x23
// f(uint256,uint256): 2, 25 -> 0x0746
// f(uint256,uint256): 3, 69 -> 396613
// f(uint256,uint256): 4, 84 -> 137228105
// f(uint256,uint256): 5, 2 -> 0xcc7c5e28
// f(uint256,uint256): 6, 51 -> 1121839760671
// f(uint256,uint256): 7, 48 -> 408349672884251

View File

@ -0,0 +1,46 @@
contract Ballot {
mapping(address => bool) canVote;
mapping(address => uint) voteCount;
mapping(address => bool) voted;
function getVoteCount(address addr) public returns (uint retVoteCount) {
return voteCount[addr];
}
function grantVoteRight(address addr) public {
canVote[addr] = true;
}
function vote(address voter, address vote) public returns (bool success) {
if (!canVote[voter] || voted[voter]) return false;
voted[voter] = true;
voteCount[vote] = voteCount[vote] + 1;
return true;
}
}
// ====
// compileViaYul: also
// ----
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 0
// vote(address,address): 0, 2 -> false
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 0
// grantVoteRight(address): 0 ->
// grantVoteRight(address): 1 ->
// vote(address,address): 0, 2 -> true
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 1
// vote(address,address): 0, 1 -> false
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 1
// vote(address,address): 2, 1 -> false
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 1
// grantVoteRight(address): 2 ->
// vote(address,address): 2, 1 -> true
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 1
// getVoteCount(address): 2 -> 1