diff options
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | docs/style-guide.rst | 81 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerUtils.cpp | 3 | ||||
-rw-r--r-- | test/libsolidity/SolidityABIJSON.cpp | 114 | ||||
-rw-r--r-- | test/libsolidity/SolidityExpressionCompiler.cpp | 126 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 820 | ||||
-rw-r--r-- | test/libsolidity/SolidityNatspecJSON.cpp | 342 |
7 files changed, 894 insertions, 593 deletions
diff --git a/Changelog.md b/Changelog.md index 1058fdf5..58cf1484 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Features: * Optimizer: Some dead code elimination. Bugfixes: + * Code generator: throw if calling the identity precompile failed during memory (array) copying. * Type checker: string literals that are not valid UTF-8 cannot be converted to string type ### 0.4.6 (2016-11-22) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 272a1b31..9aae3d7b 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -150,6 +150,74 @@ No:: ... } +Order of Functions +================== + +Ordering helps readers identify which functions they can call and to find the constructor and fallback definitions easier. + +Functions should be grouped according to their visibility and ordered: + +- constructor +- fallback function (if exists) +- external +- public +- internal +- private + +Within a grouping, place the `constant` functions last. + +Yes:: + + contract A { + function A() { + ... + } + + function() { + ... + } + + // External functions + // ... + + // External functions that are constant + // ... + + // Public functions + // ... + + // Internal functions + // ... + + // Private functions + // ... + } + +No:: + + contract A { + + // External functions + // ... + + // Private functions + // ... + + // Public functions + // ... + + function A() { + ... + } + + function() { + ... + } + + // Internal functions + // ... + } + Whitespace in Expressions ========================= @@ -194,6 +262,19 @@ No:: y = 2; long_variable = 3; +Don't include a whitespace in the fallback function: + +Yes:: + + function() { + ... + } + +No:: + + function () { + ... + } Control Structures ================== diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index d5361ac6..a8299626 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -312,7 +312,8 @@ void CompilerUtils::memoryCopy() m_context << Instruction::DIV << u256(c_identityWordGas) << Instruction::MUL; m_context << u256(c_identityGas) << Instruction::ADD; m_context << Instruction::CALL; - m_context << Instruction::POP; // ignore return value + m_context << Instruction::ISZERO; + m_context.appendConditionalJumpTo(m_context.errorTag()); } void CompilerUtils::splitExternalFunctionType(bool _leftAligned) diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index 890db241..043d74ed 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -63,9 +63,11 @@ BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, JSONInterfaceChecker) BOOST_AUTO_TEST_CASE(basic_test) { - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + } + )"; char const* interface = R"([ { @@ -93,8 +95,9 @@ BOOST_AUTO_TEST_CASE(basic_test) BOOST_AUTO_TEST_CASE(empty_contract) { - char const* sourceCode = "contract test {\n" - "}\n"; + char const* sourceCode = R"( + contract test { } + )"; char const* interface = "[]"; checkInterface(sourceCode, interface); @@ -102,10 +105,12 @@ BOOST_AUTO_TEST_CASE(empty_contract) BOOST_AUTO_TEST_CASE(multiple_methods) { - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - " function g(uint b) returns(uint e) { return b * 8; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + function g(uint b) returns(uint e) { return b * 8; } + } + )"; char const* interface = R"([ { @@ -151,9 +156,11 @@ BOOST_AUTO_TEST_CASE(multiple_methods) BOOST_AUTO_TEST_CASE(multiple_params) { - char const* sourceCode = "contract test {\n" - " function f(uint a, uint b) returns(uint d) { return a + b; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a, uint b) returns(uint d) { return a + b; } + } + )"; char const* interface = R"([ { @@ -186,10 +193,12 @@ BOOST_AUTO_TEST_CASE(multiple_params) BOOST_AUTO_TEST_CASE(multiple_methods_order) { // methods are expected to be in alpabetical order - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - " function c(uint b) returns(uint e) { return b * 8; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + function c(uint b) returns(uint e) { return b * 8; } + } + )"; char const* interface = R"([ { @@ -235,10 +244,12 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) BOOST_AUTO_TEST_CASE(const_function) { - char const* sourceCode = "contract test {\n" - " function foo(uint a, uint b) returns(uint d) { return a + b; }\n" - " function boo(uint32 a) constant returns(uint b) { return a * 4; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function foo(uint a, uint b) returns(uint d) { return a + b; } + function boo(uint32 a) constant returns(uint b) { return a * 4; } + } + )"; char const* interface = R"([ { @@ -286,11 +297,13 @@ BOOST_AUTO_TEST_CASE(const_function) BOOST_AUTO_TEST_CASE(events) { - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - " event e1(uint b, address indexed c); \n" - " event e2(); \n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + event e1(uint b, address indexed c); + event e2(); + } + )"; char const* interface = R"([ { "name": "f", @@ -341,9 +354,11 @@ BOOST_AUTO_TEST_CASE(events) BOOST_AUTO_TEST_CASE(events_anonymous) { - char const* sourceCode = "contract test {\n" - " event e() anonymous; \n" - "}\n"; + char const* sourceCode = R"( + contract test { + event e() anonymous; + } + )"; char const* interface = R"([ { "name": "e", @@ -359,15 +374,16 @@ BOOST_AUTO_TEST_CASE(events_anonymous) BOOST_AUTO_TEST_CASE(inherited) { - char const* sourceCode = - " contract Base { \n" - " function baseFunction(uint p) returns (uint i) { return p; } \n" - " event baseEvent(bytes32 indexed evtArgBase); \n" - " } \n" - " contract Derived is Base { \n" - " function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } \n" - " event derivedEvent(uint indexed evtArgDerived); \n" - " }"; + char const* sourceCode = R"( + contract Base { + function baseFunction(uint p) returns (uint i) { return p; } + event baseEvent(bytes32 indexed evtArgBase); + } + contract Derived is Base { + function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } + event derivedEvent(uint indexed evtArgDerived); + } + )"; char const* interface = R"([ { @@ -431,13 +447,14 @@ BOOST_AUTO_TEST_CASE(inherited) BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) { char const* sourceCode = R"( - contract test { - function f(uint, uint k) returns(uint ret_k, uint ret_g){ - uint g = 8; - ret_k = k; - ret_g = g; + contract test { + function f(uint, uint k) returns(uint ret_k, uint ret_g) { + uint g = 8; + ret_k = k; + ret_g = g; + } } - })"; + )"; char const* interface = R"([ { @@ -475,10 +492,11 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter) { char const* sourceCode = R"( contract test { - function f(uint k) returns(uint){ - return k; + function f(uint k) returns(uint) { + return k; + } } - })"; + )"; char const* interface = R"([ { @@ -542,7 +560,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi) contract test { enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test(ActionChoices param) {} - function ret() returns(ActionChoices){ + function ret() returns(ActionChoices) { ActionChoices action = ActionChoices.GoLeft; return action; } @@ -612,7 +630,7 @@ BOOST_AUTO_TEST_CASE(library_function) char const* sourceCode = R"( library test { struct StructType { uint a; } - function f(StructType storage b, uint[] storage c, test d) returns (uint[] e, StructType storage f){} + function f(StructType storage b, uint[] storage c, test d) returns (uint[] e, StructType storage f) {} } )"; diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index cab9f09f..0c5a09c3 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -168,9 +168,11 @@ BOOST_AUTO_TEST_SUITE(SolidityExpressionCompiler) BOOST_AUTO_TEST_CASE(literal_true) { - char const* sourceCode = "contract test {\n" - " function f() { var x = true; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = true; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x1}); @@ -179,9 +181,11 @@ BOOST_AUTO_TEST_CASE(literal_true) BOOST_AUTO_TEST_CASE(literal_false) { - char const* sourceCode = "contract test {\n" - " function f() { var x = false; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = false; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x0}); @@ -190,9 +194,11 @@ BOOST_AUTO_TEST_CASE(literal_false) BOOST_AUTO_TEST_CASE(int_literal) { - char const* sourceCode = "contract test {\n" - " function f() { var x = 0x12345678901234567890; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = 0x12345678901234567890; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90, @@ -204,11 +210,11 @@ BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination) { char const* sourceCode = R"( contract test { - function test () - { + function test () { var x = 1 wei; } - })"; + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x1}); @@ -219,11 +225,11 @@ BOOST_AUTO_TEST_CASE(int_with_szabo_ether_subdenomination) { char const* sourceCode = R"( contract test { - function test () - { + function test () { var x = 1 szabo; } - })"; + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00}); @@ -249,11 +255,11 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination) { char const* sourceCode = R"( contract test { - function test () - { + function test () { var x = 1 ether; } - })"; + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00}); @@ -262,9 +268,11 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination) BOOST_AUTO_TEST_CASE(comparison) { - char const* sourceCode = "contract test {\n" - " function f() { var x = (0x10aa < 0x11aa) != true; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = (0x10aa < 0x11aa) != true; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x1, byte(Instruction::ISZERO), byte(Instruction::ISZERO), @@ -278,9 +286,11 @@ BOOST_AUTO_TEST_CASE(comparison) BOOST_AUTO_TEST_CASE(short_circuiting) { - char const* sourceCode = "contract test {\n" - " function f() { var x = true != (4 <= 8 + 10 || 9 != 2); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = true != (4 <= 8 + 10 || 9 != 2); } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x12, // 8 + 10 @@ -305,9 +315,11 @@ BOOST_AUTO_TEST_CASE(short_circuiting) BOOST_AUTO_TEST_CASE(arithmetics) { - char const* sourceCode = "contract test {\n" - " function f(uint y) { var x = ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint y) { var x = ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}, {"test", "f", "x"}}); bytes expectation({byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0x2, @@ -339,9 +351,11 @@ BOOST_AUTO_TEST_CASE(arithmetics) BOOST_AUTO_TEST_CASE(unary_operators) { - char const* sourceCode = "contract test {\n" - " function f(int y) { var x = !(~+- y == 2); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(int y) { var x = !(~+- y == 2); } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}, {"test", "f", "x"}}); bytes expectation({byte(Instruction::PUSH1), 0x2, @@ -356,9 +370,11 @@ BOOST_AUTO_TEST_CASE(unary_operators) BOOST_AUTO_TEST_CASE(unary_inc_dec) { - char const* sourceCode = "contract test {\n" - " function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}}); // Stack: a, x @@ -406,9 +422,11 @@ BOOST_AUTO_TEST_CASE(unary_inc_dec) BOOST_AUTO_TEST_CASE(assignment) { - char const* sourceCode = "contract test {\n" - " function f(uint a, uint b) { (a += b) * 2; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a, uint b) { (a += b) * 2; } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}}); // Stack: a, b @@ -427,9 +445,11 @@ BOOST_AUTO_TEST_CASE(assignment) BOOST_AUTO_TEST_CASE(negative_literals_8bits) { - char const* sourceCode = "contract test {\n" - " function f() { int8 x = -0x80; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { int8 x = -0x80; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80)); @@ -438,9 +458,11 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits) BOOST_AUTO_TEST_CASE(negative_literals_16bits) { - char const* sourceCode = "contract test {\n" - " function f() { int64 x = ~0xabc; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { int64 x = ~0xabc; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43}); @@ -451,9 +473,11 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) { // first literal itself is too large for 256 bits but it fits after all constant operations // have been applied - char const* sourceCode = "contract test {\n" - " function f() { var x = (0xffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = (0xffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation(bytes({byte(Instruction::PUSH1), 0xbf})); @@ -462,11 +486,13 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) BOOST_AUTO_TEST_CASE(blockhash) { - char const* sourceCode = "contract test {\n" - " function f() {\n" - " block.blockhash(3);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { + block.blockhash(3); + } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {}, {make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::Block))}); diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 627aaa2f..cf0d41dd 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -187,98 +187,123 @@ BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution) BOOST_AUTO_TEST_CASE(smoke_test) { - char const* text = "contract test {\n" - " uint256 stateVariable1;\n" - " function fun(uint256 arg1) { uint256 y; }" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVariable1; + function fun(uint256 arg1) { uint256 y; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(double_stateVariable_declaration) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " uint128 variable;\n" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + uint128 variable; + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(double_function_declaration) { - char const* text = "contract test {\n" - " function fun() { uint x; }\n" - " function fun() { uint x; }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { uint x; } + function fun() { uint x; } + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(double_variable_declaration) { - char const* text = "contract test {\n" - " function f() { uint256 x; if (true) { uint256 x; } }\n" - "}\n"; + char const* text = R"( + contract test { + function f() { + uint256 x; + if (true) { uint256 x; } + } + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(name_shadowing) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " function f() { uint32 variable ; }" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + function f() { uint32 variable; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(name_references) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " function f(uint256 arg) returns (uint out) { f(variable); test; out; }" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + function f(uint256 arg) returns (uint out) { f(variable); test; out; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(undeclared_name) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " function f(uint256 arg) { f(notfound); }" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + function f(uint256 arg) { + f(notfound); + } + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(reference_to_later_declaration) { - char const* text = "contract test {\n" - " function g() { f(); }" - " function f() { }" - "}\n"; + char const* text = R"( + contract test { + function g() { f(); } + function f() {} + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive) { - char const* text = "contract test {\n" - " struct MyStructName {\n" - " address addr;\n" - " MyStructName x;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct MyStructName { + address addr; + MyStructName x; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive) { - char const* text = "contract test {\n" - " struct MyStructName1 {\n" - " address addr;\n" - " uint256 count;\n" - " MyStructName2 x;\n" - " }\n" - " struct MyStructName2 {\n" - " MyStructName1 x;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2 x; + } + struct MyStructName2 { + MyStructName1 x; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -295,179 +320,216 @@ BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive) BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping) { - char const* text = "contract test {\n" - " struct MyStructName1 {\n" - " address addr;\n" - " uint256 count;\n" - " mapping(uint => MyStructName1) x;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct MyStructName1 { + address addr; + uint256 count; + mapping(uint => MyStructName1) x; + } + } + )"; CHECK_SUCCESS(text); } 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"; + char const* text = R"( + contract test { + function f(uint256 arg1, uint32 arg2) returns (bool ret) { + var x = arg1 + arg2 == 8; ret = x; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_checking_return) { - char const* text = "contract test {\n" - " function f() returns (bool r) { return 1 >= 2; }" - "}\n"; + char const* text = R"( + contract test { + function f() returns (bool r) { return 1 >= 2; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number) { - char const* text = "contract test {\n" - " function f() returns (bool r1, bool r2) { return 1 >= 2; }" - "}\n"; + char const* text = R"( + contract test { + function f() returns (bool r1, bool r2) { return 1 >= 2; } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type) { - char const* text = "contract test {\n" - " function f() returns (uint256 r) { return 1 >= 2; }" - "}\n"; + char const* text = R"( + contract test { + function f() returns (uint256 r) { return 1 >= 2; } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(type_checking_function_call) { - char const* text = "contract test {\n" - " function f() returns (bool r) { return g(12, true) == 3; }\n" - " function g(uint256 a, bool b) returns (uint256 r) { }\n" - "}\n"; + char const* text = R"( + contract test { + function f() returns (bool r) { return g(12, true) == 3; } + function g(uint256 a, bool b) returns (uint256 r) { } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_conversion_for_comparison) { - char const* text = "contract test {\n" - " function f() { uint32(2) == int64(2); }" - "}\n"; + char const* text = R"( + contract test { + function f() { uint32(2) == int64(2); } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid) { - char const* text = "contract test {\n" - " function f() { int32(2) == uint64(2); }" - "}\n"; + char const* text = R"( + contract test { + function f() { int32(2) == uint64(2); } + } + )"; CHECK_ERROR(text, TypeError, ""); } 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"; + char const* text = R"( + contract test { + function f() returns (int256 r) { var x = int256(uint32(2)); return x; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(large_string_literal) { - char const* text = "contract test {\n" - " function f() { var x = \"123456789012345678901234567890123\"; }" - "}\n"; + char const* text = R"( + contract test { + function f() { var x = "123456789012345678901234567890123"; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(balance) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint256 x = address(0).balance;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint256 x = address(0).balance; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(balance_invalid) { - char const* text = "contract test {\n" - " function fun() {\n" - " address(0).balance = 7;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + address(0).balance = 7; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(assignment_to_mapping) { - char const* text = "contract test {\n" - " struct str {\n" - " mapping(uint=>uint) map;\n" - " }\n" - " str data;" - " function fun() {\n" - " var a = data.map;\n" - " data.map = a;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct str { + mapping(uint=>uint) map; + } + str data; + function fun() { + var a = data.map; + data.map = a; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(assignment_to_struct) { - char const* text = "contract test {\n" - " struct str {\n" - " mapping(uint=>uint) map;\n" - " }\n" - " str data;" - " function fun() {\n" - " var a = data;\n" - " data = a;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct str { + mapping(uint=>uint) map; + } + str data; + function fun() { + var a = data; + data = a; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(returns_in_constructor) { - char const* text = "contract test {\n" - " function test() returns (uint a) {\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function test() returns (uint a) { } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(forward_function_reference) { - char const* text = "contract First {\n" - " function fun() returns (bool ret) {\n" - " return Second(1).fun(1, true, 3) > 0;\n" - " }\n" - "}\n" - "contract Second {\n" - " function fun(uint a, bool b, uint c) returns (uint ret) {\n" - " if (First(2).fun() == true) return 1;\n" - " }\n" - "}\n"; + char const* text = R"( + contract First { + function fun() returns (bool ret) { + return Second(1).fun(1, true, 3) > 0; + } + } + contract Second { + function fun(uint a, bool b, uint c) returns (uint ret) { + if (First(2).fun() == true) return 1; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(comparison_bitop_precedence) { - char const* text = "contract First {\n" - " function fun() returns (bool ret) {\n" - " return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n" - " }\n" - "}\n"; + char const* text = R"( + contract First { + function fun() returns (bool ret) { + return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(function_no_implementation) { ASTPointer<SourceUnit> sourceUnit; - char const* text = "contract test {\n" - " function functionName(bytes32 input) returns (bytes32 out);\n" - "}\n"; + char const* text = R"( + contract test { + function functionName(bytes32 input) returns (bytes32 out); + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); ContractDefinition* contract = dynamic_cast<ContractDefinition*>(nodes[1].get()); @@ -482,7 +544,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract) char const* text = R"( contract base { function foo(); } contract derived is base { function foo() {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get()); @@ -501,7 +563,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload) char const* text = R"( contract base { function foo(bool); } contract derived is base { function foo(uint) {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get()); @@ -519,9 +581,9 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract) contract base { function foo(); } contract derived { base b; - function foo() { b = new base();} - } - )"; + function foo() { b = new base(); } + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -535,7 +597,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional) function derived(uint i) BaseBase(i){} function foo() {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Parsing and name resolving failed"); } @@ -549,7 +611,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_not_provided) function derived(uint i) {} function foo() {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); BOOST_CHECK_EQUAL(nodes.size(), 4); @@ -565,7 +627,7 @@ BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract) contract base { function foo(); } contract derived is base { function foo() {} } contract wrong is derived { function foo(); } - )"; + )"; CHECK_ERROR(text, TypeError, ""); } @@ -587,11 +649,13 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor) BOOST_AUTO_TEST_CASE(function_canonical_signature) { ASTPointer<SourceUnit> sourceUnit; - char const* text = "contract Test {\n" - " function foo(uint256 arg1, uint64 arg2, bool arg3) returns (uint256 ret) {\n" - " ret = arg1 + arg2;\n" - " }\n" - "}\n"; + char const* text = R"( + contract Test { + function foo(uint256 arg1, uint64 arg2, bool arg3) returns (uint256 ret) { + ret = arg1 + arg2; + } + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -604,11 +668,13 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature) BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases) { ASTPointer<SourceUnit> sourceUnit; - char const* text = "contract Test {\n" - " function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) {\n" - " ret = 5;\n" - " }\n" - "}\n"; + char const* text = R"( + contract Test { + function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) { + ret = 5; + } + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -629,9 +695,10 @@ BOOST_AUTO_TEST_CASE(function_external_types) } contract Test { function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg, address[] addresses) external returns (uint ret) { - ret = 5; + ret = 5; } - })"; + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -653,7 +720,8 @@ BOOST_AUTO_TEST_CASE(enum_external_type) function boo(ActionChoices enumArg) external returns (uint ret) { ret = 5; } - })"; + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -670,12 +738,13 @@ BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion) char const* text = R"( contract C {} contract Test { - function externalCall() { + function externalCall() { C arg; this.g(arg); } function g (C c) external {} - })"; + } + )"; CHECK_SUCCESS(text); } @@ -684,12 +753,13 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion) char const* text = R"( contract C {} contract Test { - function externalCall() { + function externalCall() { address arg; this.g(arg); } function g (C c) external {} - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -705,7 +775,8 @@ BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion) function internalCall() { g(a); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -721,18 +792,19 @@ BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion) function internalCall() { g(a); } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(hash_collision_in_interface) { - char const* text = "contract test {\n" - " function gsf() {\n" - " }\n" - " function tgeo() {\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function gsf() { } + function tgeo() { } + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -989,14 +1061,16 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value) BOOST_AUTO_TEST_CASE(state_variable_accessors) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "uint256 public foo;\n" - "mapping(uint=>bytes4) public map;\n" - "mapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + } + uint256 public foo; + mapping(uint=>bytes4) public map; + mapping(uint=>mapping(uint=>bytes4)) public multiple_map; + } + )"; ASTPointer<SourceUnit> source; ContractDefinition const* contract; @@ -1028,25 +1102,29 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "uint256 foo;\n" - " function foo() {}\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + } + uint256 foo; + function foo() {} + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(private_state_variable) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "uint256 private foo;\n" - "uint256 internal bar;\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + } + uint256 private foo; + uint256 internal bar; + } + )"; ASTPointer<SourceUnit> source; ContractDefinition const* contract; @@ -1075,12 +1153,14 @@ BOOST_AUTO_TEST_CASE(missing_state_variable) BOOST_AUTO_TEST_CASE(base_class_state_variable_accessor) { // test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126 - char const* text = "contract Parent {\n" - " uint256 public m_aMember;\n" - "}\n" - "contract Child is Parent{\n" - " function foo() returns (uint256) { return Parent.m_aMember; }\n" - "}\n"; + char const* text = R"( + contract Parent { + uint256 public m_aMember; + } + contract Child is Parent { + function foo() returns (uint256) { return Parent.m_aMember; } + } + )"; CHECK_SUCCESS(text); } @@ -1088,7 +1168,7 @@ BOOST_AUTO_TEST_CASE(struct_accessor_one_array_only) { char const* sourceCode = R"( contract test { - struct Data { uint[15] m_array; } + struct Data { uint[15] m_array; } Data public data; } )"; @@ -1097,41 +1177,47 @@ BOOST_AUTO_TEST_CASE(struct_accessor_one_array_only) BOOST_AUTO_TEST_CASE(base_class_state_variable_internal_member) { - char const* text = "contract Parent {\n" - " uint256 internal m_aMember;\n" - "}\n" - "contract Child is Parent{\n" - " function foo() returns (uint256) { return Parent.m_aMember; }\n" - "}\n"; + char const* text = R"( + contract Parent { + uint256 internal m_aMember; + } + contract Child is Parent{ + function foo() returns (uint256) { return Parent.m_aMember; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class1) { - char const* text = "contract Parent1 {\n" - " uint256 internal m_aMember1;\n" - "}\n" - "contract Parent2 is Parent1{\n" - " uint256 internal m_aMember2;\n" - "}\n" - "contract Child is Parent2{\n" - " function foo() returns (uint256) { return Parent2.m_aMember1; }\n" - "}\n"; + char const* text = R"( + contract Parent1 { + uint256 internal m_aMember1; + } + contract Parent2 is Parent1{ + uint256 internal m_aMember2; + } + contract Child is Parent2{ + function foo() returns (uint256) { return Parent2.m_aMember1; } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2) { - char const* text = "contract Parent1 {\n" - " uint256 internal m_aMember1;\n" - "}\n" - "contract Parent2 is Parent1{\n" - " uint256 internal m_aMember2;\n" - "}\n" - "contract Child is Parent2{\n" - " function foo() returns (uint256) { return Child.m_aMember2; }\n" - " uint256 public m_aMember3;\n" - "}\n"; + char const* text = R"( + contract Parent1 { + uint256 internal m_aMember1; + } + contract Parent2 is Parent1 { + uint256 internal m_aMember2; + } + contract Child is Parent2 { + function foo() returns (uint256) { return Child.m_aMember2; } + uint256 public m_aMember3; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1220,7 +1306,8 @@ BOOST_AUTO_TEST_CASE(event) contract c { event e(uint indexed a, bytes3 indexed s, bool indexed b); function f() { e(2, "abc", true); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1229,7 +1316,8 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed) char const* text = R"( contract c { event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d); - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1238,7 +1326,8 @@ BOOST_AUTO_TEST_CASE(anonymous_event_four_indexed) char const* text = R"( contract c { event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d) anonymous; - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1247,7 +1336,8 @@ BOOST_AUTO_TEST_CASE(anonymous_event_too_many_indexed) char const* text = R"( contract c { event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d, uint indexed e) anonymous; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1257,7 +1347,8 @@ BOOST_AUTO_TEST_CASE(event_call) contract c { event e(uint a, bytes3 indexed s, bool indexed b); function f() { e(2, "abc", true); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1269,7 +1360,8 @@ BOOST_AUTO_TEST_CASE(event_inheritance) } contract c is base { function f() { e(2, "abc", true); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1279,7 +1371,8 @@ BOOST_AUTO_TEST_CASE(multiple_events_argument_clash) contract c { event e1(uint a, uint e1, uint e2); event e2(uint a, uint e1, uint e2); - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1291,7 +1384,8 @@ BOOST_AUTO_TEST_CASE(access_to_default_function_visibility) } contract d { function g() { c(0).f(); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1303,7 +1397,8 @@ BOOST_AUTO_TEST_CASE(access_to_internal_function) } contract d { function g() { c(0).f(); } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1315,7 +1410,8 @@ BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility) } contract d { function g() { c(0).a(); } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1327,43 +1423,68 @@ BOOST_AUTO_TEST_CASE(access_to_internal_state_variable) } contract d { function g() { c(0).a(); } - })"; + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(error_count_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({a: 1}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({a: 1}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(empty_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({a: 1, a: 2}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({a: 1, a: 2}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({a: 1, c: 2}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({a: 1, c: 2}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1371,9 +1492,9 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter) { char const* text = R"( contract test { - function f(uint){ + function f(uint) { } } - })"; + )"; CHECK_SUCCESS(text); } @@ -1381,9 +1502,9 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter) { char const* text = R"( contract test { - function f() returns(bool){ + function f() returns(bool) { } } - })"; + )"; CHECK_SUCCESS(text); } @@ -1391,10 +1512,11 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) { char const* text = R"( contract test { - function f(uint, uint k) returns(uint ret_k){ + function f(uint, uint k) returns(uint ret_k) { return k; + } } - })"; + )"; CHECK_SUCCESS(text); } @@ -1402,16 +1524,21 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter_with_named_one) { char const* text = R"( contract test { - function f() returns(uint ret_k, uint){ + function f() returns(uint ret_k, uint) { return 5; + } } - })"; + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type) { - char const* sourceCode = "contract c { function f() { var (x) = f(); } }"; + char const* sourceCode = R"( + contract c { + function f() { var (x) = f(); } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1419,22 +1546,22 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units) { char const* sourceCodeFine = R"( contract c { - function c () - { - a = 115792089237316195423570985008687907853269984665640564039458; + function c () { + a = 115792089237316195423570985008687907853269984665640564039458; } uint256 a; - })"; + } + )"; ETH_TEST_CHECK_NO_THROW(parseAndAnalyse(sourceCodeFine), "Parsing and Resolving names failed"); char const* sourceCode = R"( contract c { - function c () - { + function c () { a = 115792089237316195423570985008687907853269984665640564039458 ether; } uint256 a; - })"; + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1443,21 +1570,22 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big) char const* sourceCode = R"( contract test { function f() returns(uint d) { return 2 ** 10000000000; } - })"; + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(enum_member_access) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - choices = ActionChoices.GoStraight; - } - ActionChoices choices; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() + { + choices = ActionChoices.GoStraight; } + ActionChoices choices; + } )"; CHECK_SUCCESS(text); } @@ -1465,14 +1593,14 @@ BOOST_AUTO_TEST_CASE(enum_member_access) BOOST_AUTO_TEST_CASE(enum_member_access_accross_contracts) { char const* text = R"( - contract Interface { - enum MyEnum { One, Two } - } - contract Impl { - function test() returns (Interface.MyEnum) { - return Interface.MyEnum.One; - } + contract Interface { + enum MyEnum { One, Two } + } + contract Impl { + function test() returns (Interface.MyEnum) { + return Interface.MyEnum.One; } + } )"; CHECK_SUCCESS(text); } @@ -1480,14 +1608,13 @@ BOOST_AUTO_TEST_CASE(enum_member_access_accross_contracts) BOOST_AUTO_TEST_CASE(enum_invalid_member_access) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - choices = ActionChoices.RunAroundWavingYourHands; - } - ActionChoices choices; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + choices = ActionChoices.RunAroundWavingYourHands; } + ActionChoices choices; + } )"; CHECK_ERROR(text, TypeError, ""); } @@ -1495,14 +1622,13 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access) BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - choices = Sit; - } - ActionChoices choices; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + choices = Sit; } + ActionChoices choices; + } )"; CHECK_ERROR(text, DeclarationError, ""); } @@ -1510,16 +1636,15 @@ BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access) BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - a = uint256(ActionChoices.GoStraight); - b = uint64(ActionChoices.Sit); - } - uint256 a; - uint64 b; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + a = uint256(ActionChoices.GoStraight); + b = uint64(ActionChoices.Sit); } + uint256 a; + uint64 b; + } )"; CHECK_SUCCESS(text); } @@ -1527,16 +1652,15 @@ BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - a = 2; - b = ActionChoices(a); - } - uint256 a; - ActionChoices b; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + a = 2; + b = ActionChoices(a); } + uint256 a; + ActionChoices b; + } )"; CHECK_SUCCESS(text); } @@ -1544,16 +1668,15 @@ BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay) BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - a = ActionChoices.GoStraight; - b = ActionChoices.Sit; - } - uint256 a; - uint64 b; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + a = ActionChoices.GoStraight; + b = ActionChoices.Sit; } + uint256 a; + uint64 b; + } )"; CHECK_ERROR(text, TypeError, ""); } @@ -1564,8 +1687,7 @@ BOOST_AUTO_TEST_CASE(enum_to_enum_conversion_is_not_okay) contract test { enum Paper { Up, Down, Left, Right } enum Ground { North, South, West, East } - function test() - { + function test() { Ground(Paper.Up); } } @@ -1609,7 +1731,7 @@ BOOST_AUTO_TEST_CASE(private_visibility) contract derived is base { function g() { f(); } } - )"; + )"; CHECK_ERROR(sourceCode, DeclarationError, ""); } @@ -1622,7 +1744,7 @@ BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access) contract derived is base { function g() { base.f(); } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1633,7 +1755,7 @@ BOOST_AUTO_TEST_CASE(external_visibility) function f() external {} function g() { f(); } } - )"; + )"; CHECK_ERROR(sourceCode, DeclarationError, ""); } @@ -1646,7 +1768,7 @@ BOOST_AUTO_TEST_CASE(external_base_visibility) contract derived is base { function g() { base.f(); } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1656,7 +1778,7 @@ BOOST_AUTO_TEST_CASE(external_argument_assign) contract c { function f(uint a) external { a = 1; } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1666,7 +1788,7 @@ BOOST_AUTO_TEST_CASE(external_argument_increment) contract c { function f(uint a) external { a++; } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1676,7 +1798,7 @@ BOOST_AUTO_TEST_CASE(external_argument_delete) contract c { function f(uint a) external { delete a; } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1689,7 +1811,7 @@ BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type) contract Bike is Vehicle { function f(bytes _a) external returns (uint256 r) {r = 42;} } - )"; + )"; ETH_TEST_CHECK_NO_THROW(parseAndAnalyse(sourceCode), "Parsing and Name Resolving failed"); } @@ -1698,7 +1820,8 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length) char const* text = R"( contract c { function f(uint a) { uint8[a] x; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1709,7 +1832,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types1) bytes a; uint[] b; function f() { b = a; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1720,7 +1844,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types2) uint32[] a; uint8[] b; function f() { b = a; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1731,7 +1856,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible) uint32[] a; uint8[] b; function f() { a = b; } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1742,7 +1868,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic) uint32[] a; uint8[80] b; function f() { a = b; } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1753,7 +1880,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static) uint[] a; uint[80] b; function f() { b = a; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1762,7 +1890,8 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int) char const* text = R"( contract c { uint8 a = 1000; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1771,7 +1900,8 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) char const* text = R"( contract c { uint a = "abc"; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1887,7 +2017,8 @@ BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1) contract c { bytes arr; function f() { byte a = arr[0];} - })"; + } + )"; ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Type resolving failed"); } @@ -1897,7 +2028,8 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable) contract Foo { function changeIt() { x = 9; } uint constant x = 56; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1907,7 +2039,8 @@ BOOST_AUTO_TEST_CASE(complex_const_variable) char const* text = R"( contract Foo { mapping(uint => bool) constant mapVar; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1916,7 +2049,8 @@ BOOST_AUTO_TEST_CASE(uninitialized_const_variable) char const* text = R"( contract Foo { uint constant y; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -4161,7 +4295,7 @@ BOOST_AUTO_TEST_CASE(invalid_array_as_statement) char const* text = R"( contract test { struct S { uint x; } - function test(uint k) { S[k]; } + function test(uint k) { S[k]; } } )"; CHECK_ERROR(text, TypeError, ""); diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp index 85bc2277..e32264c4 100644 --- a/test/libsolidity/SolidityNatspecJSON.cpp +++ b/test/libsolidity/SolidityNatspecJSON.cpp @@ -76,10 +76,12 @@ BOOST_FIXTURE_TEST_SUITE(SolidityNatspecJSON, DocumentationChecker) BOOST_AUTO_TEST_CASE(user_basic_test) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7\n" - " function mul(uint a) returns(uint d) { return a * 7; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 + function mul(uint a) returns(uint d) { return a * 7; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -91,11 +93,13 @@ BOOST_AUTO_TEST_CASE(user_basic_test) BOOST_AUTO_TEST_CASE(dev_and_user_basic_test) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7\n" - " /// @dev Multiplies a number by 7\n" - " function mul(uint a) returns(uint d) { return a * 7; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 + /// @dev Multiplies a number by 7 + function mul(uint a) returns(uint d) { return a * 7; } + } + )"; char const* devNatspec = "{" "\"methods\":{" @@ -116,14 +120,15 @@ BOOST_AUTO_TEST_CASE(dev_and_user_basic_test) BOOST_AUTO_TEST_CASE(user_multiline_comment) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7\n" - " /// and then adds `b`\n" - " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n" - " {\n" - " return (a * 7) + b;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 + /// and then adds `b` + function mul_and_add(uint a, uint256 b) returns(uint256 d) { + return (a * 7) + b; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -135,24 +140,24 @@ BOOST_AUTO_TEST_CASE(user_multiline_comment) BOOST_AUTO_TEST_CASE(user_multiple_functions) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7 and then adds `b`\n" - " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n" - " {\n" - " return (a * 7) + b;\n" - " }\n" - "\n" - " /// @notice Divides `input` by `div`\n" - " function divide(uint input, uint div) returns(uint d)\n" - " {\n" - " return input / div;\n" - " }\n" - " /// @notice Subtracts 3 from `input`\n" - " function sub(int input) returns(int d)\n" - " {\n" - " return input - 3;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 and then adds `b` + function mul_and_add(uint a, uint256 b) returns(uint256 d) { + return (a * 7) + b; + } + + /// @notice Divides `input` by `div` + function divide(uint input, uint div) returns(uint d) { + return input / div; + } + + /// @notice Subtracts 3 from `input` + function sub(int input) returns(int d) { + return input - 3; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -166,8 +171,9 @@ BOOST_AUTO_TEST_CASE(user_multiple_functions) BOOST_AUTO_TEST_CASE(user_empty_contract) { - char const* sourceCode = "contract test {\n" - "}\n"; + char const* sourceCode = R"( + contract test { } + )"; char const* natspec = "{\"methods\":{} }"; @@ -176,13 +182,16 @@ BOOST_AUTO_TEST_CASE(user_empty_contract) BOOST_AUTO_TEST_CASE(dev_and_user_no_doc) { - char const* sourceCode = "contract test {\n" - " function mul(uint a) returns(uint d) { return a * 7; }\n" - " function sub(int input) returns(int d)\n" - " {\n" - " return input - 3;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function mul(uint a) returns(uint d) { + return a * 7; + } + function sub(int input) returns(int d) { + return input - 3; + } + } + )"; char const* devNatspec = "{\"methods\":{}}"; char const* userNatspec = "{\"methods\":{}}"; @@ -193,13 +202,15 @@ BOOST_AUTO_TEST_CASE(dev_and_user_no_doc) BOOST_AUTO_TEST_CASE(dev_desc_after_nl) { - char const* sourceCode = "contract test {\n" - " /// @dev\n" - " /// Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev + /// Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -217,12 +228,14 @@ BOOST_AUTO_TEST_CASE(dev_desc_after_nl) BOOST_AUTO_TEST_CASE(dev_multiple_params) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -240,13 +253,15 @@ BOOST_AUTO_TEST_CASE(dev_multiple_params) BOOST_AUTO_TEST_CASE(dev_mutiline_param_description) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -264,26 +279,27 @@ BOOST_AUTO_TEST_CASE(dev_mutiline_param_description) BOOST_AUTO_TEST_CASE(dev_multiple_functions) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - " \n" - " /// @dev Divides 2 numbers\n" - " /// @param input Documentation for the input parameter\n" - " /// @param div Documentation for the div parameter\n" - " function divide(uint input, uint div) returns(uint d)\n" - " {\n" - " return input / div;\n" - " }\n" - " /// @dev Subtracts 3 from `input`\n" - " /// @param input Documentation for the input parameter\n" - " function sub(int input) returns(int d)\n" - " {\n" - " return input - 3;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + /// @dev Divides 2 numbers + /// @param input Documentation for the input parameter + /// @param div Documentation for the div parameter + function divide(uint input, uint div) returns(uint d) { + return input / div; + } + /// @dev Subtracts 3 from `input` + /// @param input Documentation for the input parameter + function sub(int input) returns(int d) { + return input - 3; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -314,14 +330,16 @@ BOOST_AUTO_TEST_CASE(dev_multiple_functions) BOOST_AUTO_TEST_CASE(dev_return) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " /// @return The result of the multiplication\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return The result of the multiplication + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -339,15 +357,19 @@ BOOST_AUTO_TEST_CASE(dev_return) } BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " /// @return\n" - " /// The result of the multiplication\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return + /// The result of the multiplication + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -367,15 +389,19 @@ BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl) BOOST_AUTO_TEST_CASE(dev_multiline_return) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " /// @return The result of the multiplication\n" - " /// and cookies with nutella\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return The result of the multiplication + /// and cookies with nutella + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -394,17 +420,21 @@ BOOST_AUTO_TEST_CASE(dev_multiline_return) BOOST_AUTO_TEST_CASE(dev_multiline_comment) { - char const* sourceCode = "contract test {\n" - " /**\n" - " * @dev Multiplies a number by 7 and adds second parameter\n" - " * @param a Documentation for the first parameter starts here.\n" - " * Since it's a really complicated parameter we need 2 lines\n" - " * @param second Documentation for the second parameter\n" - " * @return The result of the multiplication\n" - " * and cookies with nutella\n" - " */" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /** + * @dev Multiplies a number by 7 and adds second parameter + * @param a Documentation for the first parameter starts here. + * Since it's a really complicated parameter we need 2 lines + * @param second Documentation for the second parameter + * @return The result of the multiplication + * and cookies with nutella + */ + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -423,10 +453,12 @@ BOOST_AUTO_TEST_CASE(dev_multiline_comment) BOOST_AUTO_TEST_CASE(dev_contract_no_doc) { - char const* sourceCode = "contract test {\n" - " /// @dev Mul function\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Mul function + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" " \"methods\":{" @@ -441,12 +473,14 @@ BOOST_AUTO_TEST_CASE(dev_contract_no_doc) BOOST_AUTO_TEST_CASE(dev_contract_doc) { - char const* sourceCode = " /// @author Lefteris\n" - " /// @title Just a test contract\n" - "contract test {\n" - " /// @dev Mul function\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + /// @author Lefteris + /// @title Just a test contract + contract test { + /// @dev Mul function + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" " \"author\": \"Lefteris\"," @@ -463,13 +497,15 @@ BOOST_AUTO_TEST_CASE(dev_contract_doc) BOOST_AUTO_TEST_CASE(dev_author_at_function) { - char const* sourceCode = " /// @author Lefteris\n" - " /// @title Just a test contract\n" - "contract test {\n" - " /// @dev Mul function\n" - " /// @author John Doe\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + /// @author Lefteris + /// @title Just a test contract + contract test { + /// @dev Mul function + /// @author John Doe + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" " \"author\": \"Lefteris\"," @@ -549,25 +585,29 @@ BOOST_AUTO_TEST_CASE(empty_comment) BOOST_AUTO_TEST_CASE(dev_title_at_function_error) { - char const* sourceCode = " /// @author Lefteris\n" - " /// @title Just a test contract\n" - "contract test {\n" - " /// @dev Mul function\n" - " /// @title I really should not be here\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + /// @author Lefteris + /// @title Just a test contract + contract test { + /// @dev Mul function + /// @title I really should not be here + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; expectNatspecError(sourceCode); } BOOST_AUTO_TEST_CASE(dev_documenting_nonexistent_param) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param not_existing Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param not_existing Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; expectNatspecError(sourceCode); } |