From 7639bfe7e5fa7714ee360fe55897170afccdacbd Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 5 Mar 2015 18:22:17 +0100 Subject: [PATCH 1/9] Copying between calldata and storage. --- SolidityEndToEndTest.cpp | 62 ++++++++++++++++++++++++++++++++++++ solidityExecutionFramework.h | 2 +- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index dae0ca03a..c8664b4d0 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -3008,6 +3008,68 @@ BOOST_AUTO_TEST_CASE(bytes_index_access) BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193)); } +BOOST_AUTO_TEST_CASE(array_copy_calldata_storage) +{ + char const* sourceCode = R"( + contract c { + uint[9] m_data; + uint[] m_data_dyn; + uint8[][] m_byte_data; + function store(uint[9] a, uint8[3][] b) external returns (uint8) { + m_data = a; + m_data_dyn = a; + m_byte_data = b; + return b[3][1]; // note that access and declaration[ are reversed to each other + } + function retrieve() returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) { + a = m_data.length; + b = m_data[7]; + c = m_data_dyn.length; + d = m_data_dyn[7]; + e = m_byte_data.length; + f = m_byte_data[3].length; + g = m_byte_data[3][1]; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("store(uint256[9],uint8[3][])", encodeArgs( + 21, 22, 23, 24, 25, 26, 27, 28, 29, // a + 4, // size of b + 1, 2, 3, // b[0] + 11, 12, 13, // b[1] + 21, 22, 23, // b[2] + 31, 32, 33 // b[3] + )) == encodeArgs(32)); + BOOST_CHECK(callContractFunction("retrieve()") == encodeArgs( + 9, 28, 9, 28, + 4, 3, 32)); +} + +BOOST_AUTO_TEST_CASE(array_copy_nested_array) +{ + char const* sourceCode = R"( + contract c { + uint[4][] a; + uint[5][] b; + uint[][] c; + function test(uint[2][] d) external returns (uint) { + a = d; + b = a; + c = b; + return c[1][1] | c[1][2] | c[1][3] | c[1][4]; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test(uint256[2][])", encodeArgs( + 3, + 7, 8, + 9, 10, + 11, 12 + )) == encodeArgs(10)); +} + BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base) { char const* sourceCode = R"( diff --git a/solidityExecutionFramework.h b/solidityExecutionFramework.h index 4ef9bfdc8..4ed3854b1 100644 --- a/solidityExecutionFramework.h +++ b/solidityExecutionFramework.h @@ -178,7 +178,7 @@ protected: Address m_contractAddress; eth::State m_state; u256 const m_gasPrice = 100 * eth::szabo; - u256 const m_gas = 1000000; + u256 const m_gas = 100000000; bytes m_output; eth::LogEntries m_logs; }; From e6c778e740bfdbca0b5d6f48f0f053a16335887e Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 6 Mar 2015 13:00:54 +0100 Subject: [PATCH 2/9] Fix for arrays containing mappings. --- SolidityEndToEndTest.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index c8664b4d0..ab6e572f1 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -3070,6 +3070,43 @@ BOOST_AUTO_TEST_CASE(array_copy_nested_array) )) == encodeArgs(10)); } +BOOST_AUTO_TEST_CASE(array_copy_including_mapping) +{ + char const* sourceCode = R"( + contract c { + mapping(uint=>uint)[90][] large; + mapping(uint=>uint)[3][] small; + function test() returns (uint r) { + large.length = small.length = 7; + large[3][2][0] = 2; + large[1] = large[3]; + small[3][2][0] = 2; + small[1] = small[2]; + r = (( + small[3][2][0] * 0x100 | + small[1][2][0]) * 0x100 | + large[3][2][0]) * 0x100 | + large[1][2][0]; + delete small; + delete large; + } + function clear() returns (uint r) { + large.length = small.length = 7; + small[3][2][0] = 0; + large[3][2][0] = 0; + small.length = large.length = 0; + return 7; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(0x02000200)); + // storage is not empty because we cannot delete the mappings + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("clear()") == encodeArgs(7)); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base) { char const* sourceCode = R"( From 1234526c938504134b6b86252353ab5e2ae6319f Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 6 Mar 2015 13:44:37 +0100 Subject: [PATCH 3/9] Fix type checks for storage variable initializer. --- SolidityNameAndTypeResolution.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index a48b62d0d..6e6254eba 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -1292,6 +1292,24 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int) +{ + char const* text = R"( + contract c { + uint8 a = 1000; + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) +{ + char const* text = R"( + contract c { + uint a = "abc"; + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From 10c666fb52271f1100888676e70ad43aa65c8cdf Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 6 Mar 2015 00:20:20 +0100 Subject: [PATCH 4/9] Extracting ETH_TEST_REQUIRE_NO_THROW() from my other PR --- SolidityExpressionCompiler.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/SolidityExpressionCompiler.cpp b/SolidityExpressionCompiler.cpp index 3340334f8..e9d9a49ee 100644 --- a/SolidityExpressionCompiler.cpp +++ b/SolidityExpressionCompiler.cpp @@ -44,6 +44,23 @@ namespace test namespace { +// LTODO: Move to some more generic location. We really need it +/// Make sure that no Exception is thrown during testing. If one is thrown show its info. +/// @param _expression The expression for which to make sure no exceptions are thrown +/// @param _message A message to act as a prefix to the expression's error information +#define ETH_TEST_REQUIRE_NO_THROW(_expression, _message) \ + do { \ + try \ + { \ + _expression; \ + } \ + catch (boost::exception const& _e) \ + { \ + auto msg = std::string(_message) + boost::diagnostic_information(_e); \ + BOOST_FAIL(msg); \ + } \ + }while (0) + /// Helper class that extracts the first expression in an AST. class FirstExpressionExtractor: private ASTVisitor { @@ -72,8 +89,8 @@ private: Expression* m_expression; }; -Declaration const& resolveDeclaration(vector const& _namespacedName, - NameAndTypeResolver const& _resolver) +Declaration const& resolveDeclaration( + vector const& _namespacedName, NameAndTypeResolver const& _resolver) { Declaration const* declaration = nullptr; // bracers are required, cause msvc couldnt handle this macro in for statement @@ -112,13 +129,13 @@ bytes compileFirstExpression(const string& _sourceCode, vector> _ for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { - BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + ETH_TEST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract), "Resolving names failed"); inheritanceHierarchy = vector(1, contract); } for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { - BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract)); + ETH_TEST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract), "Checking type Requirements failed"); } for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) From 79bbe1e5d81947436b00febd7aa75246c47eabd6 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 6 Mar 2015 12:06:12 +0100 Subject: [PATCH 5/9] Move ETH_TEST() Macros to TestHelper.h - Also use them in Solidity Parser --- SolidityExpressionCompiler.cpp | 19 +---- SolidityInterface.cpp | 6 +- SolidityParser.cpp | 146 +++++++++++++++------------------ TestHelper.h | 35 ++++++++ 4 files changed, 104 insertions(+), 102 deletions(-) diff --git a/SolidityExpressionCompiler.cpp b/SolidityExpressionCompiler.cpp index e9d9a49ee..7034085ef 100644 --- a/SolidityExpressionCompiler.cpp +++ b/SolidityExpressionCompiler.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include "TestHelper.h" using namespace std; @@ -44,23 +44,6 @@ namespace test namespace { -// LTODO: Move to some more generic location. We really need it -/// Make sure that no Exception is thrown during testing. If one is thrown show its info. -/// @param _expression The expression for which to make sure no exceptions are thrown -/// @param _message A message to act as a prefix to the expression's error information -#define ETH_TEST_REQUIRE_NO_THROW(_expression, _message) \ - do { \ - try \ - { \ - _expression; \ - } \ - catch (boost::exception const& _e) \ - { \ - auto msg = std::string(_message) + boost::diagnostic_information(_e); \ - BOOST_FAIL(msg); \ - } \ - }while (0) - /// Helper class that extracts the first expression in an AST. class FirstExpressionExtractor: private ASTVisitor { diff --git a/SolidityInterface.cpp b/SolidityInterface.cpp index 354715182..ecab64c8c 100644 --- a/SolidityInterface.cpp +++ b/SolidityInterface.cpp @@ -20,7 +20,7 @@ * Unit tests for generating source interfaces for Solidity contracts. */ -#include +#include "TestHelper.h" #include #include @@ -42,9 +42,9 @@ public: ContractDefinition const& checkInterface(string const& _code, string const& _contractName = "") { m_code = _code; - BOOST_REQUIRE_NO_THROW(m_compilerStack.parse(_code)); + ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parse(_code), "Parsing failed"); m_interface = m_compilerStack.getMetadata("", DocumentationType::ABISolidityInterface); - BOOST_REQUIRE_NO_THROW(m_reCompiler.parse(m_interface)); + ETH_TEST_REQUIRE_NO_THROW(m_reCompiler.parse(m_interface), "Interface parsing failed"); return m_reCompiler.getContractDefinition(_contractName); } diff --git a/SolidityParser.cpp b/SolidityParser.cpp index 28221cc62..88b86e638 100644 --- a/SolidityParser.cpp +++ b/SolidityParser.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include "TestHelper.h" using namespace std; @@ -50,22 +50,6 @@ ASTPointer parseText(std::string const& _source) return ASTPointer(); } -ASTPointer parseTextExplainError(std::string const& _source) -{ - try - { - return parseText(_source); - } - catch (Exception const& exception) - { - // LTODO: Print the error in a kind of a better way? - // In absence of CompilerStack we can't use SourceReferenceFormatter - cout << "Exception while parsing: " << diagnostic_information(exception); - // rethrow to signal test failure - throw exception; - } -} - static void checkFunctionNatspec(ASTPointer _function, std::string const& _expectedDoc) { @@ -84,7 +68,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) char const* text = "contract test {\n" " uint256 stateVariable1;\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); } BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration) @@ -103,7 +87,7 @@ BOOST_AUTO_TEST_CASE(empty_function) " returns (int id)\n" " { }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); } BOOST_AUTO_TEST_CASE(no_function_params) @@ -112,7 +96,7 @@ BOOST_AUTO_TEST_CASE(no_function_params) " uint256 stateVar;\n" " function functionName() {}\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); } BOOST_AUTO_TEST_CASE(single_function_param) @@ -121,7 +105,7 @@ BOOST_AUTO_TEST_CASE(single_function_param) " uint256 stateVar;\n" " function functionName(hash hashin) returns (hash hashout) {}\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); } BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args) @@ -151,9 +135,9 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) " /// This is a test function\n" " function functionName(hash hashin) returns (hash hashout) {}\n" "}\n"; - BOOST_REQUIRE_NO_THROW(contract = parseText(text)); + ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); - BOOST_REQUIRE_NO_THROW(function = functions.at(0)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); checkFunctionNatspec(function, "This is a test function"); } @@ -166,9 +150,9 @@ BOOST_AUTO_TEST_CASE(function_normal_comments) " // We won't see this comment\n" " function functionName(hash hashin) returns (hash hashout) {}\n" "}\n"; - BOOST_REQUIRE_NO_THROW(contract = parseText(text)); + ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); - BOOST_REQUIRE_NO_THROW(function = functions.at(0)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); BOOST_CHECK_MESSAGE(function->getDocumentation() == nullptr, "Should not have gotten a Natspecc comment for this function"); } @@ -188,20 +172,20 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) " /// This is test function 4\n" " function functionName4(hash hashin) returns (hash hashout) {}\n" "}\n"; - BOOST_REQUIRE_NO_THROW(contract = parseText(text)); + ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); - BOOST_REQUIRE_NO_THROW(function = functions.at(0)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); checkFunctionNatspec(function, "This is test function 1"); - BOOST_REQUIRE_NO_THROW(function = functions.at(1)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(1), "Failed to retrieve function"); checkFunctionNatspec(function, "This is test function 2"); - BOOST_REQUIRE_NO_THROW(function = functions.at(2)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(2), "Failed to retrieve function"); BOOST_CHECK_MESSAGE(function->getDocumentation() == nullptr, "Should not have gotten natspec comment for functionName3()"); - BOOST_REQUIRE_NO_THROW(function = functions.at(3)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(3), "Failed to retrieve function"); checkFunctionNatspec(function, "This is test function 4"); } @@ -215,10 +199,10 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) " /// and it has 2 lines\n" " function functionName1(hash hashin) returns (hash hashout) {}\n" "}\n"; - BOOST_REQUIRE_NO_THROW(contract = parseText(text)); + ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); - BOOST_REQUIRE_NO_THROW(function = functions.at(0)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); checkFunctionNatspec(function, "This is a test function\n" " and it has 2 lines"); } @@ -240,13 +224,13 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) " /// and it has 2 lines\n" " function fun(hash hashin) returns (hash hashout) {}\n" "}\n"; - BOOST_REQUIRE_NO_THROW(contract = parseText(text)); + ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); - BOOST_REQUIRE_NO_THROW(function = functions.at(0)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); checkFunctionNatspec(function, "fun1 description"); - BOOST_REQUIRE_NO_THROW(function = functions.at(1)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(1), "Failed to retrieve function"); checkFunctionNatspec(function, "This is a test function\n" " and it has 2 lines"); } @@ -266,10 +250,10 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) " string name = \"Solidity\";" " }\n" "}\n"; - BOOST_REQUIRE_NO_THROW(contract = parseText(text)); + ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); - BOOST_REQUIRE_NO_THROW(function = functions.at(0)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); BOOST_CHECK_MESSAGE(!function->getDocumentation(), "Shouldn't get natspec docstring for this function"); } @@ -289,10 +273,10 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature) " string name = \"Solidity\";" " }\n" "}\n"; - BOOST_REQUIRE_NO_THROW(contract = parseText(text)); + ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); - BOOST_REQUIRE_NO_THROW(function = functions.at(0)); + ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); BOOST_CHECK_MESSAGE(!function->getDocumentation(), "Shouldn't get natspec docstring for this function"); } @@ -306,7 +290,7 @@ BOOST_AUTO_TEST_CASE(struct_definition) " uint256 count;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(mapping) @@ -314,7 +298,7 @@ BOOST_AUTO_TEST_CASE(mapping) char const* text = "contract test {\n" " mapping(address => string) names;\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(mapping_in_struct) @@ -326,7 +310,7 @@ BOOST_AUTO_TEST_CASE(mapping_in_struct) " mapping(hash => test_struct) self_reference;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct) @@ -337,7 +321,7 @@ BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct) " mapping (uint64 => mapping (hash => uint)) complex_mapping;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(variable_definition) @@ -350,7 +334,7 @@ BOOST_AUTO_TEST_CASE(variable_definition) " customtype varname;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) @@ -364,7 +348,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) " customtype varname;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter) @@ -408,7 +392,7 @@ BOOST_AUTO_TEST_CASE(operator_expression) " uint256 x = (1 + 4) || false && (1 - 12) + -9;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(complex_expression) @@ -418,7 +402,7 @@ BOOST_AUTO_TEST_CASE(complex_expression) " uint256 x = (1 + 4).member(++67)[a/=9] || true;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(exp_expression) @@ -429,7 +413,7 @@ BOOST_AUTO_TEST_CASE(exp_expression) uint256 x = 3 ** a; } })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(while_loop) @@ -439,7 +423,7 @@ BOOST_AUTO_TEST_CASE(while_loop) " while (true) { uint256 x = 1; break; continue; } x = 9;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr) @@ -450,7 +434,7 @@ BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr) " { uint256 x = i; break; continue; }\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr) @@ -462,7 +446,7 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr) " { uint256 x = i; break; continue; }\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr) @@ -474,7 +458,7 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr) " { uint256 x = i; break; continue; }\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body) @@ -486,7 +470,7 @@ BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body) " continue;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(if_statement) @@ -496,7 +480,7 @@ BOOST_AUTO_TEST_CASE(if_statement) " if (a >= 8) return 2; else { var b = 7; }\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(else_if_statement) @@ -506,7 +490,7 @@ BOOST_AUTO_TEST_CASE(else_if_statement) " if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion) @@ -518,7 +502,7 @@ BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion) " uint64[](3);\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array) @@ -528,7 +512,7 @@ BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array) " var x = uint64[](3);\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(import_directive) @@ -539,7 +523,7 @@ BOOST_AUTO_TEST_CASE(import_directive) " uint64(2);\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(multiple_contracts) @@ -554,7 +538,7 @@ BOOST_AUTO_TEST_CASE(multiple_contracts) " uint64(2);\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports) @@ -572,7 +556,7 @@ BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports) " }\n" "}\n" "import \"ghi\";\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(contract_inheritance) @@ -587,7 +571,7 @@ BOOST_AUTO_TEST_CASE(contract_inheritance) " uint64(2);\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(contract_multiple_inheritance) @@ -602,7 +586,7 @@ BOOST_AUTO_TEST_CASE(contract_multiple_inheritance) " uint64(2);\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments) @@ -617,7 +601,7 @@ BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments) " uint64(2);\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(placeholder_in_function_context) @@ -628,7 +612,7 @@ BOOST_AUTO_TEST_CASE(placeholder_in_function_context) " return _ + 1;" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(modifier) @@ -636,7 +620,7 @@ BOOST_AUTO_TEST_CASE(modifier) char const* text = "contract c {\n" " modifier mod { if (msg.sender == 0) _ }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(modifier_arguments) @@ -644,7 +628,7 @@ BOOST_AUTO_TEST_CASE(modifier_arguments) char const* text = "contract c {\n" " modifier mod(uint a) { if (msg.sender == a) _ }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(modifier_invocation) @@ -654,7 +638,7 @@ BOOST_AUTO_TEST_CASE(modifier_invocation) " modifier mod2 { if (msg.sender == 2) _ }\n" " function f() mod1(7) mod2 { }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(fallback_function) @@ -662,7 +646,7 @@ BOOST_AUTO_TEST_CASE(fallback_function) char const* text = "contract c {\n" " function() { }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(event) @@ -671,7 +655,7 @@ BOOST_AUTO_TEST_CASE(event) contract c { event e(); })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(event_arguments) @@ -680,7 +664,7 @@ BOOST_AUTO_TEST_CASE(event_arguments) contract c { event e(uint a, string32 s); })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(event_arguments_indexed) @@ -689,7 +673,7 @@ BOOST_AUTO_TEST_CASE(event_arguments_indexed) contract c { event e(uint a, string32 indexed s, bool indexed b); })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(visibility_specifiers) @@ -705,7 +689,7 @@ BOOST_AUTO_TEST_CASE(visibility_specifiers) function f_public() public {} function f_internal() internal {} })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers) @@ -733,7 +717,7 @@ BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations) uint256 c; uint256 d; })"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expressions) @@ -746,7 +730,7 @@ BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expression } uint256 a; })"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(enum_valid_declaration) @@ -760,7 +744,7 @@ BOOST_AUTO_TEST_CASE(enum_valid_declaration) } uint256 a; })"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(empty_enum_declaration) @@ -769,7 +753,7 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration) contract c { enum foo { } })"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(malformed_enum_declaration) @@ -787,7 +771,7 @@ BOOST_AUTO_TEST_CASE(external_function) contract c { function x() external {} })"; - BOOST_CHECK_NO_THROW(parseTextExplainError(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(external_variable) @@ -808,7 +792,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_storage) struct x { uint[2**20] b; y[0] c; } struct y { uint d; mapping(uint=>x)[] e; } })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(arrays_in_events) @@ -817,7 +801,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_events) contract c { event e(uint[10] a, string7[8] indexed b, c[3] x); })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(arrays_in_expressions) @@ -826,7 +810,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_expressions) contract c { function f() { c[10] a = 7; uint8[10 * 2] x; } })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_CASE(multi_arrays) @@ -835,7 +819,7 @@ BOOST_AUTO_TEST_CASE(multi_arrays) contract c { mapping(uint => mapping(uint => int8)[8][][9])[] x; })"; - BOOST_CHECK_NO_THROW(parseText(text)); + ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/TestHelper.h b/TestHelper.h index 849f822bd..37c90add5 100644 --- a/TestHelper.h +++ b/TestHelper.h @@ -44,6 +44,41 @@ void connectClients(Client& c1, Client& c2); namespace test { +/// Make sure that no Exception is thrown during testing. If one is thrown show its info and fail the test. +/// Our version of BOOST_REQUIRE_NO_THROW() +/// @param _expression The expression for which to make sure no exceptions are thrown +/// @param _message A message to act as a prefix to the expression's error information +#define ETH_TEST_REQUIRE_NO_THROW(_expression, _message) \ + do { \ + try \ + { \ + _expression; \ + } \ + catch (boost::exception const& _e) \ + { \ + auto msg = std::string(_message) + boost::diagnostic_information(_e); \ + BOOST_FAIL(msg); \ + } \ + }while (0) + +/// Check if an Exception is thrown during testing. If one is thrown show its info and continue the test +/// Our version of BOOST_CHECK_NO_THROW() +/// @param _expression The expression for which to make sure no exceptions are thrown +/// @param _message A message to act as a prefix to the expression's error information +#define ETH_TEST_CHECK_NO_THROW(_expression, _message) \ + do { \ + try \ + { \ + _expression; \ + } \ + catch (boost::exception const& _e) \ + { \ + auto msg = std::string(_message) + boost::diagnostic_information(_e); \ + BOOST_MESSAGE(msg); \ + } \ + }while (0) + + class ImportTest { public: From 4cd659c51d36eb03b4734ea8d2a2f246af9fac41 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 6 Mar 2015 12:50:31 +0100 Subject: [PATCH 6/9] NameAndtypeResolution tests use ETH_TEST macros --- SolidityNameAndTypeResolution.cpp | 119 ++++++++++++------------------ SolidityNatspecJSON.cpp | 12 +-- 2 files changed, 50 insertions(+), 81 deletions(-) diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 6e6254eba..c3a4a3377 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include "TestHelper.h" using namespace std; @@ -58,30 +58,6 @@ ASTPointer parseTextAndResolveNames(std::string const& _source) return sourceUnit; } -ASTPointer parseTextAndResolveNamesWithChecks(std::string const& _source) -{ - Parser parser; - ASTPointer sourceUnit; - try - { - sourceUnit = parser.parse(std::make_shared(CharStream(_source))); - NameAndTypeResolver resolver({}); - resolver.registerDeclarations(*sourceUnit); - for (ASTPointer const& node: sourceUnit->getNodes()) - if (ContractDefinition* contract = dynamic_cast(node.get())) - resolver.resolveNamesAndTypes(*contract); - for (ASTPointer const& node: sourceUnit->getNodes()) - if (ContractDefinition* contract = dynamic_cast(node.get())) - resolver.checkTypeRequirements(*contract); - } - catch(boost::exception const& _e) - { - auto msg = std::string("Parsing text and resolving names failed with: \n") + boost::diagnostic_information(_e); - BOOST_FAIL(msg); - } - return sourceUnit; -} - static ContractDefinition const* retrieveContract(ASTPointer _source, unsigned index) { ContractDefinition* contract; @@ -109,7 +85,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) " uint256 stateVariable1;\n" " function fun(uint256 arg1) { var x; uint256 y; }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(double_stateVariable_declaration) @@ -144,7 +120,7 @@ BOOST_AUTO_TEST_CASE(name_shadowing) " uint256 variable;\n" " function f() { uint32 variable ; }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(name_references) @@ -153,7 +129,7 @@ BOOST_AUTO_TEST_CASE(name_references) " uint256 variable;\n" " function f(uint256 arg) returns (uint out) { f(variable); test; out; }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(undeclared_name) @@ -171,7 +147,7 @@ BOOST_AUTO_TEST_CASE(reference_to_later_declaration) " function g() { f(); }" " function f() { }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive) @@ -209,7 +185,7 @@ BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping) " mapping(uint => MyStructName1) x;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(type_inference_smoke_test) @@ -217,7 +193,7 @@ BOOST_AUTO_TEST_CASE(type_inference_smoke_test) char const* text = "contract test {\n" " function f(uint256 arg1, uint32 arg2) returns (bool ret) { var x = arg1 + arg2 == 8; ret = x; }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(type_checking_return) @@ -225,7 +201,7 @@ BOOST_AUTO_TEST_CASE(type_checking_return) char const* text = "contract test {\n" " function f() returns (bool r) { return 1 >= 2; }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number) @@ -250,7 +226,7 @@ BOOST_AUTO_TEST_CASE(type_checking_function_call) " function f() returns (bool r) { return g(12, true) == 3; }\n" " function g(uint256 a, bool b) returns (uint256 r) { }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(type_conversion_for_comparison) @@ -258,7 +234,7 @@ BOOST_AUTO_TEST_CASE(type_conversion_for_comparison) char const* text = "contract test {\n" " function f() { uint32(2) == int64(2); }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid) @@ -274,7 +250,7 @@ BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion) char const* text = "contract test {\n" " function f() returns (int256 r) { var x = int256(uint32(2)); return x; }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(large_string_literal) @@ -292,7 +268,7 @@ BOOST_AUTO_TEST_CASE(balance) " uint256 x = address(0).balance;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(balance_invalid) @@ -332,7 +308,7 @@ BOOST_AUTO_TEST_CASE(assignment_to_struct) " data = a;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(returns_in_constructor) @@ -356,7 +332,7 @@ BOOST_AUTO_TEST_CASE(forward_function_reference) " if (First(2).fun() == true) return 1;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(comparison_bitop_precedence) @@ -366,7 +342,7 @@ BOOST_AUTO_TEST_CASE(comparison_bitop_precedence) " return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(function_canonical_signature) @@ -423,7 +399,7 @@ BOOST_AUTO_TEST_CASE(inheritance_basic) function f() { baseMember = 7; } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(inheritance_diamond_basic) @@ -436,7 +412,7 @@ BOOST_AUTO_TEST_CASE(inheritance_diamond_basic) function g() { f(); rootFunction(); } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(cyclic_inheritance) @@ -492,7 +468,7 @@ BOOST_AUTO_TEST_CASE(complex_inheritance) contract B { function f() {} function g() returns (uint8 r) {} } contract C is A, B { } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(constructor_visibility) @@ -502,7 +478,7 @@ BOOST_AUTO_TEST_CASE(constructor_visibility) contract A { function A() { } } contract B is A { function f() { A x = A(0); } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(overriding_constructor) @@ -512,7 +488,7 @@ BOOST_AUTO_TEST_CASE(overriding_constructor) contract A { function A() { } } contract B is A { function A() returns (uint8 r) {} } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(missing_base_constructor_arguments) @@ -541,7 +517,7 @@ BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion) function f() { A a = B(1); } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) @@ -564,7 +540,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation) modifier mod2(string7 a) { while (a == "1234567") _ } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(invalid_function_modifier_type) @@ -587,7 +563,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters) modifier mod2(string7 a) { while (a == "1234567") _ } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables) @@ -598,7 +574,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables) modifier mod(uint a) { if (a > 0) _ } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(legal_modifier_override) @@ -607,7 +583,7 @@ BOOST_AUTO_TEST_CASE(legal_modifier_override) contract A { modifier mod(uint a) {} } contract B is A { modifier mod(uint a) {} } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(illegal_modifier_override) @@ -661,7 +637,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) ASTPointer source; ContractDefinition const* contract; - BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(source = parseTextAndResolveNames(text), "Parsing and Resolving names failed"); BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()"); BOOST_REQUIRE(function && function->hasDeclaration()); @@ -711,7 +687,7 @@ BOOST_AUTO_TEST_CASE(private_state_variable) ASTPointer source; ContractDefinition const* contract; - BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(source = parseTextAndResolveNames(text), "Parsing and Resolving names failed"); BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); FunctionTypePointer function; function = retrieveFunctionBySignature(contract, "foo()"); @@ -729,7 +705,7 @@ BOOST_AUTO_TEST_CASE(base_class_state_variable_accessor) "contract Child is Parent{\n" " function foo() returns (uint256) { return Parent.m_aMember; }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(base_class_state_variable_internal_member) @@ -740,7 +716,7 @@ BOOST_AUTO_TEST_CASE(base_class_state_variable_internal_member) "contract Child is Parent{\n" " function foo() returns (uint256) { return Parent.m_aMember; }\n" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class1) @@ -780,7 +756,7 @@ BOOST_AUTO_TEST_CASE(fallback_function) function() { x = 2; } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(fallback_function_with_arguments) @@ -817,7 +793,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_inheritance) function() { x = 2; } } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(event) @@ -827,7 +803,7 @@ BOOST_AUTO_TEST_CASE(event) event e(uint indexed a, string3 indexed s, bool indexed b); function f() { e(2, "abc", true); } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(event_too_many_indexed) @@ -847,7 +823,7 @@ BOOST_AUTO_TEST_CASE(event_call) event e(uint a, string3 indexed s, bool indexed b); function f() { e(2, "abc", true); } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(event_inheritance) @@ -859,7 +835,7 @@ BOOST_AUTO_TEST_CASE(event_inheritance) contract c is base { function f() { e(2, "abc", true); } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(multiple_events_argument_clash) @@ -869,7 +845,7 @@ BOOST_AUTO_TEST_CASE(multiple_events_argument_clash) event e1(uint a, uint e1, uint e2); event e2(uint a, uint e1, uint e2); })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(access_to_default_function_visibility) @@ -881,7 +857,7 @@ BOOST_AUTO_TEST_CASE(access_to_default_function_visibility) contract d { function g() { c(0).f(); } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(access_to_internal_function) @@ -917,7 +893,7 @@ BOOST_AUTO_TEST_CASE(access_to_internal_state_variable) contract d { function g() { c(0).a(); } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(error_count_in_named_args) @@ -963,7 +939,7 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter) function f(uint){ } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(empty_name_return_parameter) @@ -973,7 +949,7 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter) function f() returns(bool){ } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) @@ -984,7 +960,7 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) return k; } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(empty_name_return_parameter_with_named_one) @@ -1014,7 +990,8 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units) } uint256 a; })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCodeFine)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCodeFine), + "Parsing and Resolving names failed"); char const* sourceCode = R"( contract c { function c () @@ -1056,7 +1033,7 @@ BOOST_AUTO_TEST_CASE(enum_member_access) ActionChoices choices; } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(enum_invalid_member_access) @@ -1088,7 +1065,7 @@ BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) uint64 b; } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay) @@ -1105,7 +1082,7 @@ BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay) ActionChoices b; } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) @@ -1225,7 +1202,7 @@ BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type) function f(bytes _a) external returns (uint256 r) {r = 42;} } )"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(sourceCode)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode), "Parsing and Name Resolving failed"); } BOOST_AUTO_TEST_CASE(array_with_nonconstant_length) @@ -1267,7 +1244,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible) uint8[] b; function f() { a = b; } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic) @@ -1278,7 +1255,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic) uint8[80] b; function f() { a = b; } })"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); } BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static) diff --git a/SolidityNatspecJSON.cpp b/SolidityNatspecJSON.cpp index d1a443c21..edfe89861 100644 --- a/SolidityNatspecJSON.cpp +++ b/SolidityNatspecJSON.cpp @@ -20,7 +20,7 @@ * Unit tests for the solidity compiler JSON Interface output. */ -#include +#include "TestHelper.h" #include #include #include @@ -43,15 +43,7 @@ public: bool _userDocumentation) { std::string generatedDocumentationString; - try - { - m_compilerStack.parse(_code); - } - catch(boost::exception const& _e) - { - auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e); - BOOST_FAIL(msg); - } + ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parse(_code), "Parsing failed"); if (_userDocumentation) generatedDocumentationString = m_compilerStack.getMetadata("", DocumentationType::NatspecUser); From 4534ff8792ad9849845457ff063ed0d3f2a2181a Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 6 Mar 2015 12:58:08 +0100 Subject: [PATCH 7/9] Adding ETH_TEST macros to ABI and EndToEndTests --- SolidityABIJSON.cpp | 12 ++---------- solidityExecutionFramework.h | 14 +++----------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/SolidityABIJSON.cpp b/SolidityABIJSON.cpp index 10873b5ab..5f67a5667 100644 --- a/SolidityABIJSON.cpp +++ b/SolidityABIJSON.cpp @@ -20,7 +20,7 @@ * Unit tests for the solidity compiler JSON Interface output. */ -#include +#include "TestHelper.h" #include #include #include @@ -39,15 +39,7 @@ public: void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) { - try - { - m_compilerStack.parse(_code); - } - catch(boost::exception const& _e) - { - auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e); - BOOST_FAIL(msg); - } + ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parse(_code), "Parsing contract failed"); std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABIInterface); Json::Value generatedInterface; m_reader.parse(generatedInterfaceString, generatedInterface); diff --git a/solidityExecutionFramework.h b/solidityExecutionFramework.h index 4ef9bfdc8..e8776063f 100644 --- a/solidityExecutionFramework.h +++ b/solidityExecutionFramework.h @@ -25,7 +25,7 @@ #include #include -#include +#include "TestHelper.h" #include #include #include @@ -46,16 +46,8 @@ public: bytes const& compileAndRun(std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "") { dev::solidity::CompilerStack compiler(m_addStandardSources); - try - { - compiler.addSource("", _sourceCode); - compiler.compile(m_optimize); - } - catch(boost::exception const& _e) - { - auto msg = std::string("Compiling contract failed with: ") + boost::diagnostic_information(_e); - BOOST_FAIL(msg); - } + compiler.addSource("", _sourceCode); + ETH_TEST_REQUIRE_NO_THROW(compiler.compile(m_optimize), "Compiling contract failed"); bytes code = compiler.getBytecode(_contractName); sendMessage(code, true, _value); From e2c01948f45743bd90c89cf080fa4142786bf09b Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 6 Mar 2015 14:30:34 +0100 Subject: [PATCH 8/9] Style fixes and better exception message format --- TestHelper.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/TestHelper.h b/TestHelper.h index 37c90add5..91ec977db 100644 --- a/TestHelper.h +++ b/TestHelper.h @@ -49,34 +49,36 @@ namespace test /// @param _expression The expression for which to make sure no exceptions are thrown /// @param _message A message to act as a prefix to the expression's error information #define ETH_TEST_REQUIRE_NO_THROW(_expression, _message) \ - do { \ + do \ + { \ try \ { \ _expression; \ } \ catch (boost::exception const& _e) \ { \ - auto msg = std::string(_message) + boost::diagnostic_information(_e); \ + auto msg = std::string(_message"\n") + boost::diagnostic_information(_e); \ BOOST_FAIL(msg); \ } \ - }while (0) + } while (0) /// Check if an Exception is thrown during testing. If one is thrown show its info and continue the test /// Our version of BOOST_CHECK_NO_THROW() /// @param _expression The expression for which to make sure no exceptions are thrown /// @param _message A message to act as a prefix to the expression's error information #define ETH_TEST_CHECK_NO_THROW(_expression, _message) \ - do { \ + do \ + { \ try \ { \ _expression; \ } \ catch (boost::exception const& _e) \ { \ - auto msg = std::string(_message) + boost::diagnostic_information(_e); \ + auto msg = std::string(_message"\n") + boost::diagnostic_information(_e); \ BOOST_MESSAGE(msg); \ } \ - }while (0) + } while (0) class ImportTest From 2650703ecef1f08f3669f27d9f872ea24f698679 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 6 Mar 2015 15:40:02 +0100 Subject: [PATCH 9/9] Typo --- SolidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index ab6e572f1..ae2417052 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -3019,7 +3019,7 @@ BOOST_AUTO_TEST_CASE(array_copy_calldata_storage) m_data = a; m_data_dyn = a; m_byte_data = b; - return b[3][1]; // note that access and declaration[ are reversed to each other + return b[3][1]; // note that access and declaration are reversed to each other } function retrieve() returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) { a = m_data.length;