diff options
Diffstat (limited to 'test/libsolidity')
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 249 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 154 |
2 files changed, 403 insertions, 0 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 088fe4d1..8600443d 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -3314,6 +3314,57 @@ BOOST_AUTO_TEST_CASE(using_enums) BOOST_CHECK(callContractFunction("getChoice()") == encodeArgs(2)); } +BOOST_AUTO_TEST_CASE(using_contract_enums_with_explicit_contract_name) +{ + char const* sourceCode = R"( + contract test { + enum Choice { A, B, C } + function answer () returns (test.Choice _ret) + { + _ret = test.Choice.B; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(using_inherited_enum) +{ + char const* sourceCode = R"( + contract base { + enum Choice { A, B, C } + } + + contract test is base { + function answer () returns (Choice _ret) + { + _ret = Choice.B; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(using_inherited_enum_excplicitly) +{ + char const* sourceCode = R"( + contract base { + enum Choice { A, B, C } + } + + contract test is base { + function answer () returns (base.Choice _ret) + { + _ret = base.Choice.B; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1)); +} + BOOST_AUTO_TEST_CASE(constructing_enums_from_ints) { char const* sourceCode = R"( @@ -5615,6 +5666,120 @@ BOOST_AUTO_TEST_CASE(accessor_for_const_state_variable) BOOST_CHECK(callContractFunction("ticketPrice()") == encodeArgs(u256(555))); } +BOOST_AUTO_TEST_CASE(state_variable_under_contract_name) +{ + char const* text = R"( + contract Scope { + uint stateVar = 42; + + function getStateVar() constant returns (uint stateVar) { + stateVar = Scope.stateVar; + } + } + )"; + compileAndRun(text); + BOOST_CHECK(callContractFunction("getStateVar()") == encodeArgs(u256(42))); +} + +BOOST_AUTO_TEST_CASE(state_variable_local_variable_mixture) +{ + char const* sourceCode = R"( + contract A { + uint x = 1; + uint y = 2; + function a() returns (uint x) { + x = A.y; + } + } + )"; + + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(2))); +} + +BOOST_AUTO_TEST_CASE(inherited_function) { + char const* sourceCode = R"( + contract A { function f() internal returns (uint) { return 1; } } + contract B is A { + function f() internal returns (uint) { return 2; } + function g() returns (uint) { + return A.f(); + } + } + )"; + + compileAndRun(sourceCode, 0, "B"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(1))); +} + +BOOST_AUTO_TEST_CASE(inherited_function_from_a_library) { + char const* sourceCode = R"( + library A { function f() internal returns (uint) { return 1; } } + contract B { + function f() internal returns (uint) { return 2; } + function g() returns (uint) { + return A.f(); + } + } + )"; + + compileAndRun(sourceCode, 0, "B"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(1))); +} + +BOOST_AUTO_TEST_CASE(inherited_constant_state_var) +{ + char const* sourceCode = R"( + contract A { + uint constant x = 7; + } + contract B is A { + function f() returns (uint) { + return A.x; + } + } + )"; + + compileAndRun(sourceCode, 0, "B"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7))); +} + +BOOST_AUTO_TEST_CASE(multiple_inherited_state_vars) +{ + char const* sourceCode = R"( + contract A { + uint x = 7; + } + contract B { + uint x = 9; + } + contract C is A, B { + function a() returns (uint) { + return A.x; + } + function b() returns (uint) { + return B.x; + } + function a_set(uint _x) returns (uint) { + A.x = _x; + return 1; + } + function b_set(uint _x) returns (uint) { + B.x = _x; + return 1; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("b()") == encodeArgs(u256(9))); + BOOST_CHECK(callContractFunction("a_set(uint256)", u256(1)) == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("b_set(uint256)", u256(3)) == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("b()") == encodeArgs(u256(3))); +} + BOOST_AUTO_TEST_CASE(constant_string_literal) { char const* sourceCode = R"( @@ -5854,6 +6019,48 @@ BOOST_AUTO_TEST_CASE(using_library_structs) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7), u256(8))); } +BOOST_AUTO_TEST_CASE(library_struct_as_an_expression) +{ + char const* sourceCode = R"( + library Arst { + struct Foo { + int Things; + int Stuff; + } + } + + contract Tsra { + function f() returns(uint) { + Arst.Foo; + return 1; + } + } + )"; + compileAndRun(sourceCode, 0, "Tsra"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1))); +} + +BOOST_AUTO_TEST_CASE(library_enum_as_an_expression) +{ + char const* sourceCode = R"( + library Arst { + enum Foo { + Things, + Stuff + } + } + + contract Tsra { + function f() returns(uint) { + Arst.Foo; + return 1; + } + } + )"; + compileAndRun(sourceCode, 0, "Tsra"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1))); +} + BOOST_AUTO_TEST_CASE(short_strings) { // This test verifies that the byte array encoding that combines length and data works @@ -7304,6 +7511,48 @@ BOOST_AUTO_TEST_CASE(shift_negative_constant_right) BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(-0x42))); } +BOOST_AUTO_TEST_CASE(inline_assembly_in_modifiers) +{ + char const* sourceCode = R"( + contract C { + modifier m { + uint a = 1; + assembly { + a := 2 + } + if (a != 2) + throw; + _; + } + function f() m returns (bool) { + return true; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(true)); +} + +BOOST_AUTO_TEST_CASE(packed_storage_overflow) +{ + char const* sourceCode = R"( + contract C { + uint16 x = 0x1234; + uint16 a = 0xffff; + uint16 b; + function f() returns (uint, uint, uint, uint) { + a++; + uint c = b; + delete b; + a -= 2; + return (x, c, b, a); + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x1234), u256(0), u256(0), u256(0xfffe))); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 83472369..640cc108 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -854,6 +854,23 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) BOOST_CHECK(expectError(text) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(super_excludes_current_contract) +{ + char const* text = R"( + contract A { + function b() {} + } + + contract B is A { + function f() { + super.f(); + } + } + )"; + + BOOST_CHECK(expectError(text) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_CASE(function_modifier_invocation) { char const* text = R"( @@ -1019,6 +1036,19 @@ BOOST_AUTO_TEST_CASE(private_state_variable) BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of an internal variable should not exist"); } +BOOST_AUTO_TEST_CASE(missing_state_variable) +{ + char const* text = R"( + contract Scope { + function getStateVar() constant returns (uint stateVar) { + stateVar = Scope.stateVar; // should fail. + } + } + )"; + BOOST_CHECK(expectError(text) == Error::Type::TypeError); +} + + BOOST_AUTO_TEST_CASE(base_class_state_variable_accessor) { // test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126 @@ -1439,6 +1469,21 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access) BOOST_CHECK(expectError(text) == Error::Type::TypeError); } +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; + } + )"; + BOOST_CHECK(expectError(text) == Error::Type::DeclarationError); +} + BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) { char const* text = R"( @@ -1500,6 +1545,23 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) BOOST_CHECK(expectError(text) == Error::Type::DeclarationError); } +BOOST_AUTO_TEST_CASE(enum_name_resolution_under_current_contract_name) +{ + char const* text = R"( + contract A { + enum Foo { + First, + Second + } + + function a() { + A.Foo; + } + } + )"; + BOOST_CHECK(success(text)); +} + BOOST_AUTO_TEST_CASE(private_visibility) { char const* sourceCode = R"( @@ -2036,6 +2098,22 @@ BOOST_AUTO_TEST_CASE(integer_boolean_operators) BOOST_CHECK(expectError(sourceCode3) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(exp_signed_variable) +{ + char const* sourceCode1 = R"( + contract test { function() { uint x = 3; int y = -4; x ** y; } } + )"; + BOOST_CHECK(expectError(sourceCode1) == Error::Type::TypeError); + char const* sourceCode2 = R"( + contract test { function() { uint x = 3; int y = -4; y ** x; } } + )"; + BOOST_CHECK(expectError(sourceCode2) == Error::Type::TypeError); + char const* sourceCode3 = R"( + contract test { function() { int x = -3; int y = -4; x ** y; } } + )"; + BOOST_CHECK(expectError(sourceCode3) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_CASE(reference_compare_operators) { char const* sourceCode1 = R"( @@ -4039,6 +4117,18 @@ BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype) BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(invalid_fixed_point_literal) +{ + char const* text = R"( + contract A { + function a() { + .8E0; + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue) { char const* text = R"( @@ -4107,6 +4197,70 @@ BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_negative_stack) BOOST_CHECK(expectError(text, true) == Error::Type::Warning); } +BOOST_AUTO_TEST_CASE(inline_assembly_in_modifier) +{ + char const* text = R"( + contract test { + modifier m { + uint a = 1; + assembly { + a := 2 + } + _; + } + function f() m { + } + } + )"; + BOOST_CHECK(success(text)); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_storage) +{ + char const* text = R"( + contract test { + uint x = 1; + function f() { + assembly { + x := 2 + } + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers) +{ + char const* text = R"( + contract test { + uint x = 1; + modifier m { + assembly { + x := 2 + } + _; + } + function f() m { + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError); +} + +BOOST_AUTO_TEST_CASE(invalid_mobile_type) +{ + char const* text = R"( + contract C { + function f() { + // Invalid number + [1, 78901234567890123456789012345678901234567890123456789345678901234567890012345678012345678901234567]; + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } |