aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-01-25 04:43:48 +0800
committerchriseth <c@ethdev.com>2016-01-25 04:43:48 +0800
commit194679f77ada30b04f483e96197e890e41a0c22c (patch)
tree82ed4cec81cb9dd81cbdc3b8134b80fb7e3de780 /test
parent67c855c583042ddee6261a9921239a3afd086c14 (diff)
parent51caa04238ce78420e6efc2ce15842effddf3856 (diff)
downloaddexon-solidity-194679f77ada30b04f483e96197e890e41a0c22c.tar
dexon-solidity-194679f77ada30b04f483e96197e890e41a0c22c.tar.gz
dexon-solidity-194679f77ada30b04f483e96197e890e41a0c22c.tar.bz2
dexon-solidity-194679f77ada30b04f483e96197e890e41a0c22c.tar.lz
dexon-solidity-194679f77ada30b04f483e96197e890e41a0c22c.tar.xz
dexon-solidity-194679f77ada30b04f483e96197e890e41a0c22c.tar.zst
dexon-solidity-194679f77ada30b04f483e96197e890e41a0c22c.zip
Merge pull request #326 from guanqun/cond-expr
support conditional expression _ ? _ : _
Diffstat (limited to 'test')
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp186
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp176
-rw-r--r--test/libsolidity/SolidityParser.cpp67
3 files changed, 429 insertions, 0 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 3ef5ebbe..73e2d662 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -86,6 +86,192 @@ BOOST_AUTO_TEST_CASE(exp_operator_const_signed)
BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(-8)));
}
+BOOST_AUTO_TEST_CASE(conditional_expression_true_literal)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f() returns(uint d) {
+ return true ? 5 : 10;
+ }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(5)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_false_literal)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f() returns(uint d) {
+ return false ? 5 : 10;
+ }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(10)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_multiple)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint x) returns(uint d) {
+ return x > 100 ?
+ x > 1000 ? 1000 : 100
+ :
+ x > 50 ? 50 : 10;
+ }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(uint256)", u256(1001)) == toBigEndian(u256(1000)));
+ BOOST_CHECK(callContractFunction("f(uint256)", u256(500)) == toBigEndian(u256(100)));
+ BOOST_CHECK(callContractFunction("f(uint256)", u256(80)) == toBigEndian(u256(50)));
+ BOOST_CHECK(callContractFunction("f(uint256)", u256(40)) == toBigEndian(u256(10)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_with_return_values)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(bool cond, uint v) returns (uint a, uint b) {
+ cond ? a = v : b = v;
+ }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(bool,uint256)", true, u256(20)) == encodeArgs(u256(20), u256(0)));
+ BOOST_CHECK(callContractFunction("f(bool,uint256)", false, u256(20)) == encodeArgs(u256(0), u256(20)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_1)
+{
+ char const* sourceCode = R"(
+ contract test {
+ bytes2[2] data1;
+ function f(bool cond) returns (uint) {
+ bytes2[2] memory x;
+ x[0] = "aa";
+ bytes2[2] memory y;
+ y[0] = "bb";
+
+ data1 = cond ? x : y;
+
+ uint ret = 0;
+ if (data1[0] == "aa")
+ {
+ ret = 1;
+ }
+
+ if (data1[0] == "bb")
+ {
+ ret = 2;
+ }
+
+ return ret;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(u256(2)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_2)
+{
+ char const* sourceCode = R"(
+ contract test {
+ bytes2[2] data1;
+ function f(bool cond) returns (uint) {
+ data1[0] = "cc";
+
+ bytes2[2] memory x;
+ bytes2[2] memory y;
+ y[0] = "bb";
+
+ x = cond ? y : data1;
+
+ uint ret = 0;
+ if (x[0] == "bb")
+ {
+ ret = 1;
+ }
+
+ if (x[0] == "cc")
+ {
+ ret = 2;
+ }
+
+ return ret;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(u256(2)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_different_types)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(bool cond) returns (uint) {
+ uint8 x = 0xcd;
+ uint16 y = 0xabab;
+ return cond ? x : y;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(u256(0xcd)));
+ BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(u256(0xabab)));
+}
+
+/* let's add this back when I figure out the correct type conversion.
+BOOST_AUTO_TEST_CASE(conditional_expression_string_literal)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(bool cond) returns (bytes32) {
+ return cond ? "true" : "false";
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(string("true", 4)));
+ BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(string("false", 5)));
+}
+*/
+
+BOOST_AUTO_TEST_CASE(conditional_expression_tuples)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(bool cond) returns (uint, uint) {
+ return cond ? (1, 2) : (3, 4);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(u256(1), u256(2)));
+ BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(u256(3), u256(4)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_functions)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function x() returns (uint) { return 1; }
+ function y() returns (uint) { return 2; }
+
+ function f(bool cond) returns (uint) {
+ var z = cond ? x : y;
+ return z();
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(u256(2)));
+}
+
BOOST_AUTO_TEST_CASE(recursive_calls)
{
char const* sourceCode = "contract test {\n"
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index c8e901e4..820fd7d0 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -2960,6 +2960,182 @@ BOOST_AUTO_TEST_CASE(continue_not_in_loop_2)
BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
}
+BOOST_AUTO_TEST_CASE(invalid_different_types_for_conditional_expression)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ true ? true : 2;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ uint x;
+ uint y;
+ (true ? x : y) = 1;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct)
+{
+ char const* text = R"(
+ contract C {
+ struct s1 {
+ uint x;
+ }
+ struct s2 {
+ uint x;
+ }
+ function f() {
+ s1 x;
+ s2 y;
+ true ? x : y;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_with_different_function_type)
+{
+ char const* text = R"(
+ contract C {
+ function x(bool) {}
+ function y() {}
+
+ function f() {
+ true ? x : y;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_with_different_enum)
+{
+ char const* text = R"(
+ contract C {
+ enum small { A, B, C, D }
+ enum big { A, B, C, D }
+
+ function f() {
+ small x;
+ big y;
+
+ true ? x : y;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(conditional_expression_with_different_mapping)
+{
+ char const* text = R"(
+ contract C {
+ mapping(uint8 => uint8) table1;
+ mapping(uint32 => uint8) table2;
+
+ function f() {
+ true ? table1 : table2;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(conditional_with_all_types)
+{
+ char const* text = R"(
+ contract C {
+ struct s1 {
+ uint x;
+ }
+ s1 struct_x;
+ s1 struct_y;
+
+ function fun_x() {}
+ function fun_y() {}
+
+ enum small { A, B, C, D }
+
+ mapping(uint8 => uint8) table1;
+ mapping(uint8 => uint8) table2;
+
+ function f() {
+ // integers
+ uint x;
+ uint y;
+ true ? x : y;
+
+ // integer constants
+ true ? 1 : 3;
+
+ // string literal
+ true ? "hello" : "world";
+
+ // bool
+ true ? true : false;
+
+ // real is not there yet.
+
+ // array
+ byte[2] memory a;
+ byte[2] memory b;
+ true ? a : b;
+
+ bytes memory e;
+ bytes memory f;
+ true ? e : f;
+
+ // fixed bytes
+ bytes2 c;
+ bytes2 d;
+ true ? c : d;
+
+ // contract doesn't fit in here
+
+ // struct
+ true ? struct_x : struct_y;
+
+ // function
+ true ? fun_x : fun_y;
+
+ // enum
+ small enum_x;
+ small enum_y;
+ true ? enum_x : enum_y;
+
+ // tuple
+ true ? (1, 2) : (3, 4);
+
+ // mapping
+ true ? table1 : table2;
+
+ // typetype
+ true ? uint32(1) : uint32(2);
+
+ // modifier doesn't fit in here
+
+ // magic doesn't fit in here
+
+ // module doesn't fit in here
+ }
+ }
+ )";
+ BOOST_CHECK(success(text));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index 8e0bf77e..055fae49 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -1111,6 +1111,73 @@ BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue)
BOOST_CHECK(!successParse(text));
}
+BOOST_AUTO_TEST_CASE(conditional_true_false_literal)
+{
+ char const* text = R"(
+ contract A {
+ function f() {
+ uint x = true ? 1 : 0;
+ uint y = false ? 0 : 1;
+ }
+ }
+ )";
+ BOOST_CHECK(successParse(text));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_with_constants)
+{
+ char const* text = R"(
+ contract A {
+ function f() {
+ uint x = 3 > 0 ? 3 : 0;
+ uint y = (3 > 0) ? 3 : 0;
+ }
+ }
+ )";
+ BOOST_CHECK(successParse(text));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_with_variables)
+{
+ char const* text = R"(
+ contract A {
+ function f() {
+ uint x = 3;
+ uint y = 1;
+ uint z = (x > y) ? x : y;
+ uint w = x > y ? x : y;
+ }
+ }
+ )";
+ BOOST_CHECK(successParse(text));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_multiple)
+{
+ char const* text = R"(
+ contract A {
+ function f() {
+ uint x = 3 < 0 ? 2 > 1 ? 2 : 1 : 7 > 2 ? 7 : 6;
+ }
+ }
+ )";
+ BOOST_CHECK(successParse(text));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_with_assignment)
+{
+ char const* text = R"(
+ contract A {
+ function f() {
+ uint y = 1;
+ uint x = 3 < 0 ? x = 3 : 6;
+ true ? x = 3 : 4;
+ }
+ }
+ )";
+ BOOST_CHECK(successParse(text));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}