diff options
-rw-r--r-- | TestHelper.cpp | 49 | ||||
-rw-r--r-- | TestHelper.h | 30 | ||||
-rw-r--r-- | libsolidity/SolidityEndToEndTest.cpp | 53 |
3 files changed, 105 insertions, 27 deletions
diff --git a/TestHelper.cpp b/TestHelper.cpp index 733ccb6d..743b1627 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -178,7 +178,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state, stateOptio { stateOptions.m_bHasBalance = true; if (bigint(o["balance"].get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); + TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); balance = toInt(o["balance"]); } @@ -186,7 +186,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state, stateOptio { stateOptions.m_bHasNonce = true; if (bigint(o["nonce"].get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'nonce' is equal or greater than 2**256") ); + TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'nonce' is equal or greater than 2**256") ); nonce = toInt(o["nonce"]); } @@ -230,7 +230,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) { //check that every parameter was declared in state object if (!stateOptionMap.second.isAllSet()) - BOOST_THROW_EXCEPTION(MissingFields() << errinfo_comment("Import State: Missing state fields!")); + TBOOST_THROW_EXCEPTION(MissingFields() << errinfo_comment("Import State: Missing state fields!")); } } @@ -246,13 +246,13 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) assert(_o.count("data") > 0); if (bigint(_o["nonce"].get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); + TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); if (bigint(_o["gasPrice"].get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); + TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); if (bigint(_o["gasLimit"].get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); + TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); if (bigint(_o["value"].get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); + TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); m_transaction = _o["to"].get_str().empty() ? Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), importData(_o), toInt(_o["nonce"]), Secret(_o["secretKey"].get_str())) : @@ -285,9 +285,9 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta #define CHECK(a,b) \ { \ if (_throw == WhenError::Throw) \ - BOOST_CHECK_MESSAGE(a,b); \ + {TBOOST_CHECK_MESSAGE(a,b);}\ else \ - BOOST_WARN_MESSAGE(a,b); \ + {TBOOST_WARN_MESSAGE(a,b);} \ } for (auto const& a: _stateExpect.addresses()) @@ -304,35 +304,35 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta } catch(std::out_of_range const&) { - BOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!"); + TBOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!"); break; } } if (addressOptions.m_bHasBalance) - CHECK(_stateExpect.balance(a.first) == _statePost.balance(a.first), + CHECK((_stateExpect.balance(a.first) == _statePost.balance(a.first)), "Check State: " << a.first << ": incorrect balance " << _statePost.balance(a.first) << ", expected " << _stateExpect.balance(a.first)); if (addressOptions.m_bHasNonce) - CHECK(_stateExpect.transactionsFrom(a.first) == _statePost.transactionsFrom(a.first), + CHECK((_stateExpect.transactionsFrom(a.first) == _statePost.transactionsFrom(a.first)), "Check State: " << a.first << ": incorrect nonce " << _statePost.transactionsFrom(a.first) << ", expected " << _stateExpect.transactionsFrom(a.first)); if (addressOptions.m_bHasStorage) { unordered_map<u256, u256> stateStorage = _statePost.storage(a.first); for (auto const& s: _stateExpect.storage(a.first)) - CHECK(stateStorage[s.first] == s.second, + CHECK((stateStorage[s.first] == s.second), "Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(stateStorage[s.first]) << ", expected [" << s.first << "] = " << toHex(s.second)); //Check for unexpected storage values stateStorage = _stateExpect.storage(a.first); for (auto const& s: _statePost.storage(a.first)) - CHECK(stateStorage[s.first] == s.second, + CHECK((stateStorage[s.first] == s.second), "Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(s.second) << ", expected [" << s.first << "] = " << toHex(stateStorage[s.first])); } if (addressOptions.m_bHasCode) - CHECK(_stateExpect.code(a.first) == _statePost.code(a.first), + CHECK((_stateExpect.code(a.first) == _statePost.code(a.first)), "Check State: " << a.first << ": incorrect code '" << toHex(_statePost.code(a.first)) << "', expected '" << toHex(_stateExpect.code(a.first)) << "'"); } } @@ -518,18 +518,17 @@ void checkOutput(bytes const& _output, json_spirit::mObject& _o) int j = 0; if (_o["out"].get_str().find("#") == 0) - BOOST_CHECK((u256)_output.size() == toInt(_o["out"].get_str().substr(1))); - + {TBOOST_CHECK(((u256)_output.size() == toInt(_o["out"].get_str().substr(1))));} else if (_o["out"].type() == json_spirit::array_type) for (auto const& d: _o["out"].get_array()) { - BOOST_CHECK_MESSAGE(_output[j] == toInt(d), "Output byte [" << j << "] different!"); + TBOOST_CHECK_MESSAGE((_output[j] == toInt(d)), "Output byte [" << j << "] different!"); ++j; } else if (_o["out"].get_str().find("0x") == 0) - BOOST_CHECK(_output == fromHex(_o["out"].get_str().substr(2))); + {TBOOST_CHECK((_output == fromHex(_o["out"].get_str().substr(2))));} else - BOOST_CHECK(_output == fromHex(_o["out"].get_str())); + TBOOST_CHECK((_output == fromHex(_o["out"].get_str()))); } void checkStorage(map<u256, u256> _expectedStore, map<u256, u256> _resultStore, Address _expectedAddr) @@ -557,13 +556,13 @@ void checkStorage(map<u256, u256> _expectedStore, map<u256, u256> _resultStore, void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) { - BOOST_REQUIRE_EQUAL(_resultLogs.size(), _expectedLogs.size()); + TBOOST_REQUIRE_EQUAL(_resultLogs.size(), _expectedLogs.size()); for (size_t i = 0; i < _resultLogs.size(); ++i) { - BOOST_CHECK_EQUAL(_resultLogs[i].address, _expectedLogs[i].address); - BOOST_CHECK_EQUAL(_resultLogs[i].topics, _expectedLogs[i].topics); - BOOST_CHECK(_resultLogs[i].data == _expectedLogs[i].data); + TBOOST_CHECK_EQUAL(_resultLogs[i].address, _expectedLogs[i].address); + TBOOST_CHECK_EQUAL(_resultLogs[i].topics, _expectedLogs[i].topics); + TBOOST_CHECK((_resultLogs[i].data == _expectedLogs[i].data)); } } @@ -598,7 +597,7 @@ void userDefinedTest(std::function<void(json_spirit::mValue&, bool)> doTests) { cnote << "Testing user defined test: " << filename; json_spirit::mValue v; - string s = asString(contents(filename)); + string s = contentsString(filename); BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. "); json_spirit::read_string(s, v); json_spirit::mObject oSingleTest; diff --git a/TestHelper.h b/TestHelper.h index 8f0c73bf..df33c00d 100644 --- a/TestHelper.h +++ b/TestHelper.h @@ -31,6 +31,26 @@ #include <libevm/ExtVMFace.h> #include <libtestutils/Common.h> +#ifdef NOBOOST + #define TBOOST_THROW_EXCEPTION(arg) throw dev::Exception(); + #define TBOOST_REQUIRE(arg) if(arg == false) throw dev::Exception(); + #define TBOOST_REQUIRE_EQUAL(arg1, arg2) if(arg1 != arg2) throw dev::Exception(); + #define TBOOST_CHECK_EQUAL(arg1, arg2) if(arg1 != arg2) throw dev::Exception(); + #define TBOOST_CHECK(arg) if(arg == false) throw dev::Exception(); + #define TBOOST_CHECK_MESSAGE(arg1, arg2) if(arg1 == false) throw dev::Exception(); + #define TBOOST_WARN_MESSAGE(arg1, arg2) throw dev::Exception(); + #define TBOOST_ERROR(arg) throw dev::Exception(); +#else + #define TBOOST_THROW_EXCEPTION(arg) BOOST_THROW_EXCEPTION(arg) + #define TBOOST_REQUIRE(arg) BOOST_REQUIRE(arg) + #define TBOOST_REQUIRE_EQUAL(arg1, arg2) BOOST_REQUIRE_EQUAL(arg1, arg2) + #define TBOOST_CHECK(arg) BOOST_CHECK(arg) + #define TBOOST_CHECK_EQUAL(arg1, arg2) BOOST_CHECK_EQUAL(arg1, arg2) + #define TBOOST_CHECK_MESSAGE(arg1, arg2) BOOST_CHECK_MESSAGE(arg1, arg2) + #define TBOOST_WARN_MESSAGE(arg1, arg2) BOOST_WARN_MESSAGE(arg1, arg2) + #define TBOOST_ERROR(arg) BOOST_ERROR(arg) +#endif + namespace dev { namespace eth @@ -163,6 +183,12 @@ eth::LastHashes lastHashes(u256 _currentBlockNumber); json_spirit::mObject fillJsonWithState(eth::State _state); json_spirit::mObject fillJsonWithTransaction(eth::Transaction _txn); +//Fill Test Functions +void doTransactionTests(json_spirit::mValue& _v, bool _fillin); +void doStateTests(json_spirit::mValue& v, bool _fillin); +void doVMTests(json_spirit::mValue& v, bool _fillin); +void doBlockchainTests(json_spirit::mValue& _v, bool _fillin); + template<typename mapType> void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs) { @@ -171,9 +197,9 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs) auto& resultAddr = resultPair.first; auto expectedAddrIt = _expectedAddrs.find(resultAddr); if (expectedAddrIt == _expectedAddrs.end()) - BOOST_ERROR("Missing result address " << resultAddr); + TBOOST_ERROR("Missing result address " << resultAddr); } - BOOST_CHECK(_expectedAddrs == _resultAddrs); + TBOOST_CHECK((_expectedAddrs == _resultAddrs)); } class Options diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp index 10624281..95f253d5 100644 --- a/libsolidity/SolidityEndToEndTest.cpp +++ b/libsolidity/SolidityEndToEndTest.cpp @@ -4335,6 +4335,59 @@ BOOST_AUTO_TEST_CASE(accessor_involving_strings) BOOST_REQUIRE(callContractFunction("data(uint256,uint256)", x, y) == result); } +BOOST_AUTO_TEST_CASE(storage_array_ref) +{ + char const* sourceCode = R"( + contract BinarySearch { + /// Finds the position of _value in the sorted list _data. + /// Note that "internal" is important here, because storage references only work for internal or private functions + function find(uint[] storage _data, uint _value) internal returns (uint o_position) { + return find(_data, 0, _data.length, _value); + } + function find(uint[] storage _data, uint _begin, uint _len, uint _value) private returns (uint o_position) { + if (_len == 0 || (_len == 1 && _data[_begin] != _value)) + return uint(-1); // failure + uint halfLen = _len / 2; + uint v = _data[_begin + halfLen]; + if (_value < v) + return find(_data, _begin, halfLen, _value); + else if (_value > v) + return find(_data, _begin + halfLen + 1, halfLen - 1, _value); + else + return _begin + halfLen; + } + } + + contract Store is BinarySearch { + uint[] data; + function add(uint v) { + data.length++; + data[data.length - 1] = v; + } + function find(uint v) returns (uint) { + return find(data, v); + } + } + )"; + compileAndRun(sourceCode, 0, "Store"); + BOOST_REQUIRE(callContractFunction("find(uint256)", u256(7)) == encodeArgs(u256(-1))); + BOOST_REQUIRE(callContractFunction("add(uint256)", u256(7)) == encodeArgs()); + BOOST_REQUIRE(callContractFunction("find(uint256)", u256(7)) == encodeArgs(u256(0))); + BOOST_CHECK(callContractFunction("add(uint256)", u256(11)) == encodeArgs()); + BOOST_CHECK(callContractFunction("add(uint256)", u256(17)) == encodeArgs()); + BOOST_CHECK(callContractFunction("add(uint256)", u256(27)) == encodeArgs()); + BOOST_CHECK(callContractFunction("add(uint256)", u256(31)) == encodeArgs()); + BOOST_CHECK(callContractFunction("add(uint256)", u256(32)) == encodeArgs()); + BOOST_CHECK(callContractFunction("add(uint256)", u256(66)) == encodeArgs()); + BOOST_CHECK(callContractFunction("add(uint256)", u256(177)) == encodeArgs()); + BOOST_CHECK(callContractFunction("find(uint256)", u256(7)) == encodeArgs(u256(0))); + BOOST_CHECK(callContractFunction("find(uint256)", u256(27)) == encodeArgs(u256(3))); + BOOST_CHECK(callContractFunction("find(uint256)", u256(32)) == encodeArgs(u256(5))); + BOOST_CHECK(callContractFunction("find(uint256)", u256(176)) == encodeArgs(u256(-1))); + BOOST_CHECK(callContractFunction("find(uint256)", u256(0)) == encodeArgs(u256(-1))); + BOOST_CHECK(callContractFunction("find(uint256)", u256(400)) == encodeArgs(u256(-1))); +} + BOOST_AUTO_TEST_SUITE_END() } |