diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/libdevcore/MiniMoustache.cpp | 127 | ||||
-rw-r--r-- | test/liblll/EndToEndTest.cpp | 146 | ||||
-rw-r--r-- | test/libsolidity/Assembly.cpp | 4 | ||||
-rw-r--r-- | test/libsolidity/JSONCompiler.cpp | 26 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 23 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 30 | ||||
-rw-r--r-- | test/libsolidity/StandardCompiler.cpp | 30 |
7 files changed, 363 insertions, 23 deletions
diff --git a/test/libdevcore/MiniMoustache.cpp b/test/libdevcore/MiniMoustache.cpp new file mode 100644 index 00000000..84149173 --- /dev/null +++ b/test/libdevcore/MiniMoustache.cpp @@ -0,0 +1,127 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * Unit tests for the mini moustache class. + */ + +#include <libdevcore/Whiskers.h> + +#include "../TestHelper.h" + +using namespace std; + +namespace dev +{ +namespace test +{ + +BOOST_AUTO_TEST_SUITE(WhiskersTest) + +BOOST_AUTO_TEST_CASE(no_templates) +{ + string templ = "this text does not contain templates"; + BOOST_CHECK_EQUAL(Whiskers(templ).render(), templ); +} + +BOOST_AUTO_TEST_CASE(basic_replacement) +{ + string templ = "a <b> x <c> -> <d>."; + string result = Whiskers(templ) + ("b", "BE") + ("c", "CE") + ("d", "DE") + .render(); + BOOST_CHECK_EQUAL(result, "a BE x CE -> DE."); +} + +BOOST_AUTO_TEST_CASE(tag_unavailable) +{ + string templ = "<b>"; + Whiskers m(templ); + BOOST_CHECK_THROW(m.render(), WhiskersError); +} + +BOOST_AUTO_TEST_CASE(complicated_replacement) +{ + string templ = "a <b> x <complicated> \n <nes<ted>>."; + string result = Whiskers(templ) + ("b", "BE") + ("complicated", "CO<M>PL") + ("nes<ted", "NEST") + .render(); + BOOST_CHECK_EQUAL(result, "a BE x CO<M>PL \n NEST>."); +} + +BOOST_AUTO_TEST_CASE(non_existing_list) +{ + string templ = "a <#b></b>"; + Whiskers m(templ); + BOOST_CHECK_THROW(m.render(), WhiskersError); +} + +BOOST_AUTO_TEST_CASE(empty_list) +{ + string templ = "a <#b></b>x"; + string result = Whiskers(templ)("b", vector<Whiskers::StringMap>{}).render(); + BOOST_CHECK_EQUAL(result, "a x"); +} + +BOOST_AUTO_TEST_CASE(list) +{ + string templ = "a<#b>( <g> - <h> )</b>x"; + vector<map<string, string>> list(2); + list[0]["g"] = "GE"; + list[0]["h"] = "H"; + list[1]["g"] = "2GE"; + list[1]["h"] = "2H"; + string result = Whiskers(templ)("b", list).render(); + BOOST_CHECK_EQUAL(result, "a( GE - H )( 2GE - 2H )x"); +} + +BOOST_AUTO_TEST_CASE(recursive_list) +{ + // Check that templates resulting from lists are not expanded again + string templ = "a<#b> 1<g>3 </b><x>"; + vector<map<string, string>> list(1); + list[0]["g"] = "<x>"; + string result = Whiskers(templ)("x", "X")("b", list).render(); + BOOST_CHECK_EQUAL(result, "a 1<x>3 X"); +} + +BOOST_AUTO_TEST_CASE(list_can_access_upper) +{ + string templ = "<#b>(<a>)</b>"; + vector<map<string, string>> list(2); + Whiskers m(templ); + string result = m("a", "A")("b", list).render(); + BOOST_CHECK_EQUAL(result, "(A)(A)"); +} + +BOOST_AUTO_TEST_CASE(parameter_collision) +{ + string templ = "a <#b></b>"; + vector<map<string, string>> list(1); + list[0]["a"] = "x"; + Whiskers m(templ); + m("a", "X")("b", list); + BOOST_CHECK_THROW(m.render(), WhiskersError); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} diff --git a/test/liblll/EndToEndTest.cpp b/test/liblll/EndToEndTest.cpp index 3928ff45..3037b14b 100644 --- a/test/liblll/EndToEndTest.cpp +++ b/test/liblll/EndToEndTest.cpp @@ -57,6 +57,88 @@ BOOST_AUTO_TEST_CASE(panic) BOOST_REQUIRE(m_output.empty()); } +BOOST_AUTO_TEST_CASE(variables) +{ + char const* sourceCode = R"( + (returnlll + (seq + (set 'x 1) + (set 'y 2) + ;; this should equal to 3 + (set 'z (add (get 'x) (get 'y))) + ;; overwriting it here + (set 'y 4) + ;; each variable has a 32 byte slot, starting from memory location 0x80 + ;; variable addresses can also be retrieved by x or (ref 'x) + (set 'k (add (add (ref 'x) (ref 'y)) z)) + (return (add (add (get 'x) (add (get 'y) (get 'z))) (get 'k))))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callFallback() == encodeArgs(u256(488))); +} + +BOOST_AUTO_TEST_CASE(when) +{ + char const* sourceCode = R"( + (returnlll + (seq + (when (= (calldatasize) 0) (return 1)) + (when (!= (calldatasize) 0) (return 2)))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2))); + BOOST_CHECK(callFallback() == toBigEndian(u256(1))); +} + +BOOST_AUTO_TEST_CASE(unless) +{ + char const* sourceCode = R"( + (returnlll + (seq + (unless (!= (calldatasize) 0) (return 1)) + (unless (= (calldatasize) 0) (return 2)))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2))); + BOOST_CHECK(callFallback() == toBigEndian(u256(1))); +} + +BOOST_AUTO_TEST_CASE(conditional_literal) +{ + char const* sourceCode = R"( + (returnlll + (seq + (return (if (= (calldatasize) 0) 1 2)))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2))); + BOOST_CHECK(callFallback() == toBigEndian(u256(1))); +} + +BOOST_AUTO_TEST_CASE(conditional) +{ + char const* sourceCode = R"( + (returnlll + (seq + (if (= (calldatasize) 0) (return 1) (return 2)))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2))); + BOOST_CHECK(callFallback() == toBigEndian(u256(1))); +} + +BOOST_AUTO_TEST_CASE(conditional_seq) +{ + char const* sourceCode = R"( + (returnlll + (seq + (return (if (= (calldatasize) 0) { 0 2 1 } { 0 1 2 })))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2))); + BOOST_CHECK(callFallback() == toBigEndian(u256(1))); +} + BOOST_AUTO_TEST_CASE(exp_operator_const) { char const* sourceCode = R"( @@ -304,6 +386,51 @@ BOOST_AUTO_TEST_CASE(keccak256_32bytes) fromHex("b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"))); } +BOOST_AUTO_TEST_CASE(msg_six_args) +{ + char const* sourceCode = R"( + (returnlll + (seq + (when (= 0 (calldatasize)) + (seq + (mstore 0x40 1) + (def 'outsize 0x20) + (return (msg 1000 (address) 42 0x40 0x20 outsize) outsize))) + (when (= 1 (calldataload 0x00)) + (return (callvalue))))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42))); +} + +BOOST_AUTO_TEST_CASE(create_1_arg) +{ + char const* sourceCode = R"( + (returnlll + (seq + (call allgas + (create (returnlll (return 42))) + 0 0 0 0x00 0x20) + (return 0x00 0x20))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callFallback() == encodeArgs(u256(42))); +} + +BOOST_AUTO_TEST_CASE(create_2_args) +{ + char const* sourceCode = R"( + (returnlll + (seq + (call allgas + (create 42 (returnlll (return (balance (address))))) + 0 0 0 0x00 0x20) + (return 0x00 0x20))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42))); +} + BOOST_AUTO_TEST_CASE(sha3_two_args) { char const* sourceCode = R"( @@ -328,6 +455,25 @@ BOOST_AUTO_TEST_CASE(sha3_one_arg) fromHex("b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"))); } +BOOST_AUTO_TEST_CASE(ecrecover) +{ + char const* sourceCode = R"( + (returnlll + (return + (ecrecover + ; Hash of 'hello world' + 0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad + ; v = 1 + 27 + 0x1c + ; r + 0xdebaaa0cddb321b2dcaaf846d39605de7b97e77ba6106587855b9106cb104215 + ; s + 0x61a22d94fa8b8a687ff9c911c844d1c016d1a685a9166858f9c7c1bc85128aca))) + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callFallback() == encodeArgs(fromHex("0x8743523d96a1b2cbe0c6909653a56da18ed484af"))); +} + BOOST_AUTO_TEST_CASE(shift_left) { char const* sourceCode = R"( diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index e52f4d50..99a2996e 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -119,8 +119,8 @@ BOOST_AUTO_TEST_CASE(location_test) shared_ptr<string const> n = make_shared<string>(""); AssemblyItems items = compileContract(sourceCode); vector<SourceLocation> locations = - vector<SourceLocation>(17, SourceLocation(2, 75, n)) + - vector<SourceLocation>(30, SourceLocation(20, 72, n)) + + vector<SourceLocation>(19, SourceLocation(2, 75, n)) + + vector<SourceLocation>(32, SourceLocation(20, 72, n)) + vector<SourceLocation>{SourceLocation(42, 51, n), SourceLocation(65, 67, n)} + vector<SourceLocation>(2, SourceLocation(58, 67, n)) + vector<SourceLocation>(3, SourceLocation(20, 72, n)); diff --git a/test/libsolidity/JSONCompiler.cpp b/test/libsolidity/JSONCompiler.cpp index f5154395..aa690f0b 100644 --- a/test/libsolidity/JSONCompiler.cpp +++ b/test/libsolidity/JSONCompiler.cpp @@ -73,28 +73,36 @@ BOOST_AUTO_TEST_CASE(basic_compilation) Json::Value contract = result["contracts"]["fileA:A"]; BOOST_CHECK(contract.isObject()); BOOST_CHECK(contract["interface"].isString()); - BOOST_CHECK(contract["interface"].asString() == "[]"); + BOOST_CHECK_EQUAL(contract["interface"].asString(), "[]"); BOOST_CHECK(contract["bytecode"].isString()); - BOOST_CHECK(dev::test::bytecodeSansMetadata(contract["bytecode"].asString()) == - "60606040523415600b57fe5b5b60338060196000396000f30060606040525bfe00"); + BOOST_CHECK_EQUAL( + dev::test::bytecodeSansMetadata(contract["bytecode"].asString()), + "60606040523415600e57600080fd5b5b603680601c6000396000f30060606040525b600080fd00" + ); BOOST_CHECK(contract["runtimeBytecode"].isString()); - BOOST_CHECK(dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()) == - "60606040525bfe00"); + BOOST_CHECK_EQUAL( + dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()), + "60606040525b600080fd00" + ); BOOST_CHECK(contract["functionHashes"].isObject()); BOOST_CHECK(contract["gasEstimates"].isObject()); - BOOST_CHECK(dev::jsonCompactPrint(contract["gasEstimates"]) == - "{\"creation\":[62,10200],\"external\":{},\"internal\":{}}"); + BOOST_CHECK_EQUAL( + dev::jsonCompactPrint(contract["gasEstimates"]), + "{\"creation\":[62,10800],\"external\":{},\"internal\":{}}" + ); BOOST_CHECK(contract["metadata"].isString()); BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString())); BOOST_CHECK(result["sources"].isObject()); BOOST_CHECK(result["sources"]["fileA"].isObject()); BOOST_CHECK(result["sources"]["fileA"]["AST"].isObject()); - BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["AST"]) == + BOOST_CHECK_EQUAL( + dev::jsonCompactPrint(result["sources"]["fileA"]["AST"]), "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}}," "\"children\":[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null]," "\"contractKind\":\"contract\",\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1]," "\"name\":\"A\",\"nodes\":[null],\"scope\":2},\"id\":1,\"name\":\"ContractDefinition\"," - "\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"); + "\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}" + ); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index ba507e0c..823a8eda 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -9469,6 +9469,29 @@ BOOST_AUTO_TEST_CASE(revert) BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(42))); } +BOOST_AUTO_TEST_CASE(literal_empty_string) +{ + char const* sourceCode = R"( + contract C { + bytes32 public x; + uint public a; + function f(bytes32 _x, uint _a) { + x = _x; + a = _a; + } + function g() { + this.f("", 2); + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(0))); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(0))); + BOOST_CHECK(callContractFunction("g()") == encodeArgs()); + BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(0))); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(2))); +} + BOOST_AUTO_TEST_CASE(scientific_notation) { char const* sourceCode = R"( diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index fc8cdc35..e18303f5 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1597,6 +1597,16 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter) CHECK_SUCCESS(text); } +BOOST_AUTO_TEST_CASE(constant_input_parameter) +{ + char const* text = R"( + contract test { + function f(uint[] constant a) { } + } + )"; + CHECK_ERROR_ALLOW_MULTI(text, TypeError, "Illegal use of \"constant\" specifier."); +} + BOOST_AUTO_TEST_CASE(empty_name_return_parameter) { char const* text = R"( @@ -2304,6 +2314,16 @@ BOOST_AUTO_TEST_CASE(constant_struct) CHECK_ERROR(text, TypeError, "implemented"); } +BOOST_AUTO_TEST_CASE(address_is_constant) +{ + char const* text = R"( + contract C { + address constant x = 0x1212121212121212121212121212121212121212; + } + )"; + CHECK_SUCCESS_NO_WARNINGS(text); +} + BOOST_AUTO_TEST_CASE(uninitialized_const_variable) { char const* text = R"( @@ -5612,6 +5632,16 @@ BOOST_AUTO_TEST_CASE(interface_variables) CHECK_ERROR(text, TypeError, "Variables cannot be declared in interfaces"); } +BOOST_AUTO_TEST_CASE(interface_function_parameters) +{ + char const* text = R"( + interface I { + function f(uint a) returns(bool); + } + )"; + success(text); +} + BOOST_AUTO_TEST_CASE(interface_enums) { char const* text = R"( diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 35644a4d..be13d46b 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -189,37 +189,43 @@ BOOST_AUTO_TEST_CASE(basic_compilation) Json::Value contract = getContractResult(result, "fileA", "A"); BOOST_CHECK(contract.isObject()); BOOST_CHECK(contract["abi"].isArray()); - BOOST_CHECK(dev::jsonCompactPrint(contract["abi"]) == "[]"); + BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[]"); BOOST_CHECK(contract["devdoc"].isObject()); - BOOST_CHECK(dev::jsonCompactPrint(contract["devdoc"]) == "{\"methods\":{}}"); + BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["devdoc"]), "{\"methods\":{}}"); BOOST_CHECK(contract["userdoc"].isObject()); - BOOST_CHECK(dev::jsonCompactPrint(contract["userdoc"]) == "{\"methods\":{}}"); + BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["userdoc"]), "{\"methods\":{}}"); BOOST_CHECK(contract["evm"].isObject()); /// @TODO check evm.methodIdentifiers, legacyAssembly, bytecode, deployedBytecode BOOST_CHECK(contract["evm"]["bytecode"].isObject()); BOOST_CHECK(contract["evm"]["bytecode"]["object"].isString()); - BOOST_CHECK(dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()) == - "60606040523415600b57fe5b5b60338060196000396000f30060606040525bfe00"); + BOOST_CHECK_EQUAL( + dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()), + "60606040523415600e57600080fd5b5b603680601c6000396000f30060606040525b600080fd00" + ); BOOST_CHECK(contract["evm"]["assembly"].isString()); BOOST_CHECK(contract["evm"]["assembly"].asString().find( " /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x60)\n jumpi(tag_1, iszero(callvalue))\n" - " invalid\ntag_1:\ntag_2:\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n" + " 0x0\n dup1\n revert\ntag_1:\ntag_2:\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n" " return\nstop\n\nsub_0: assembly {\n /* \"fileA\":0:14 contract A { } */\n" - " mstore(0x40, 0x60)\n tag_1:\n invalid\n\n" - " auxdata: 0xa165627a7a72305820") != std::string::npos); + " mstore(0x40, 0x60)\n tag_1:\n 0x0\n dup1\n revert\n\n" + " auxdata: 0xa165627a7a7230582") == 0); BOOST_CHECK(contract["evm"]["gasEstimates"].isObject()); - BOOST_CHECK(dev::jsonCompactPrint(contract["evm"]["gasEstimates"]) == - "{\"creation\":{\"codeDepositCost\":\"10200\",\"executionCost\":\"62\",\"totalCost\":\"10262\"}}"); + BOOST_CHECK_EQUAL( + dev::jsonCompactPrint(contract["evm"]["gasEstimates"]), + "{\"creation\":{\"codeDepositCost\":\"10800\",\"executionCost\":\"62\",\"totalCost\":\"10862\"}}" + ); BOOST_CHECK(contract["metadata"].isString()); BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString())); BOOST_CHECK(result["sources"].isObject()); BOOST_CHECK(result["sources"]["fileA"].isObject()); BOOST_CHECK(result["sources"]["fileA"]["legacyAST"].isObject()); - BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]) == + BOOST_CHECK_EQUAL( + dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]), "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},\"children\":" "[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null],\"contractKind\":\"contract\"," "\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],\"name\":\"A\",\"nodes\":[null],\"scope\":2}," - "\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"); + "\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}" + ); } BOOST_AUTO_TEST_SUITE_END() |