mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into develop
This commit is contained in:
commit
30db15c1a9
@ -21,8 +21,10 @@ target_link_libraries(testeth ethereum)
|
||||
target_link_libraries(testeth ethcore)
|
||||
target_link_libraries(testeth secp256k1)
|
||||
target_link_libraries(testeth solidity)
|
||||
target_link_libraries(testeth webthree)
|
||||
|
||||
if (NOT HEADLESS)
|
||||
target_link_libraries(testeth webthree)
|
||||
target_link_libraries(testeth natspec)
|
||||
endif()
|
||||
if (JSONRPC)
|
||||
target_link_libraries(testeth web3jsonrpc)
|
||||
target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES})
|
||||
|
@ -32,12 +32,12 @@ namespace solidity
|
||||
namespace test
|
||||
{
|
||||
|
||||
class InterfaceChecker
|
||||
class JSONInterfaceChecker
|
||||
{
|
||||
public:
|
||||
InterfaceChecker(): m_compilerStack(false) {}
|
||||
JSONInterfaceChecker(): m_compilerStack(false) {}
|
||||
|
||||
void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString, std::string const& expectedSolidityInterface)
|
||||
void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -48,8 +48,7 @@ public:
|
||||
auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e);
|
||||
BOOST_FAIL(msg);
|
||||
}
|
||||
std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_INTERFACE);
|
||||
std::string generatedSolidityInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_SOLIDITY_INTERFACE);
|
||||
std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABIInterface);
|
||||
Json::Value generatedInterface;
|
||||
m_reader.parse(generatedInterfaceString, generatedInterface);
|
||||
Json::Value expectedInterface;
|
||||
@ -57,9 +56,6 @@ public:
|
||||
BOOST_CHECK_MESSAGE(expectedInterface == generatedInterface,
|
||||
"Expected:\n" << expectedInterface.toStyledString() <<
|
||||
"\n but got:\n" << generatedInterface.toStyledString());
|
||||
BOOST_CHECK_MESSAGE(expectedSolidityInterface == generatedSolidityInterfaceString,
|
||||
"Expected:\n" << expectedSolidityInterface <<
|
||||
"\n but got:\n" << generatedSolidityInterfaceString);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -67,7 +63,7 @@ private:
|
||||
Json::Reader m_reader;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, InterfaceChecker)
|
||||
BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, JSONInterfaceChecker)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(basic_test)
|
||||
{
|
||||
@ -75,8 +71,6 @@ BOOST_AUTO_TEST_CASE(basic_test)
|
||||
" function f(uint a) returns(uint d) { return a * 7; }\n"
|
||||
"}\n";
|
||||
|
||||
char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}}";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
"name": "f",
|
||||
@ -97,18 +91,16 @@ BOOST_AUTO_TEST_CASE(basic_test)
|
||||
}
|
||||
])";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_contract)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
"}\n";
|
||||
char const* sourceInterface = "contract test{}";
|
||||
|
||||
char const* interface = "[]";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_methods)
|
||||
@ -117,7 +109,6 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
|
||||
" 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* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}function g(uint256 b)returns(uint256 e){}}";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
@ -156,7 +147,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
|
||||
}
|
||||
])";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_params)
|
||||
@ -164,7 +155,6 @@ 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* sourceInterface = "contract test{function f(uint256 a,uint256 b)returns(uint256 d){}}";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
@ -190,7 +180,7 @@ BOOST_AUTO_TEST_CASE(multiple_params)
|
||||
}
|
||||
])";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_methods_order)
|
||||
@ -200,7 +190,6 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
|
||||
" 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* sourceInterface = "contract test{function c(uint256 b)returns(uint256 e){}function f(uint256 a)returns(uint256 d){}}";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
@ -239,7 +228,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
|
||||
}
|
||||
])";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(const_function)
|
||||
@ -248,7 +237,6 @@ BOOST_AUTO_TEST_CASE(const_function)
|
||||
" 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* sourceInterface = "contract test{function foo(uint256 a,uint256 b)returns(uint256 d){}function boo(uint32 a)constant returns(uint256 b){}}";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
@ -289,17 +277,16 @@ BOOST_AUTO_TEST_CASE(const_function)
|
||||
}
|
||||
])";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(exclude_fallback_function)
|
||||
{
|
||||
char const* sourceCode = "contract test { function() {} }";
|
||||
char const* sourceInterface = "contract test{}";
|
||||
|
||||
char const* interface = "[]";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(events)
|
||||
@ -309,8 +296,6 @@ BOOST_AUTO_TEST_CASE(events)
|
||||
" event e1(uint b, address indexed c); \n"
|
||||
" event e2(); \n"
|
||||
"}\n";
|
||||
char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}event e1(uint256 b,address indexed c);event e2;}";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
"name": "f",
|
||||
@ -353,7 +338,7 @@ BOOST_AUTO_TEST_CASE(events)
|
||||
|
||||
])";
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
|
||||
@ -368,7 +353,6 @@ BOOST_AUTO_TEST_CASE(inherited)
|
||||
" function derivedFunction(string32 p) returns (string32 i) { return p; } \n"
|
||||
" event derivedEvent(uint indexed evtArgDerived); \n"
|
||||
" }";
|
||||
char const* sourceInterface = "contract Derived{function baseFunction(uint256 p)returns(uint256 i){}function derivedFunction(string32 p)returns(string32 i){}event derivedEvent(uint256 indexed evtArgDerived);event baseEvent(string32 indexed evtArgBase);}";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
@ -423,9 +407,80 @@ BOOST_AUTO_TEST_CASE(inherited)
|
||||
}])";
|
||||
|
||||
|
||||
checkInterface(sourceCode, interface, sourceInterface);
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
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;
|
||||
}
|
||||
})";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
"name": "f",
|
||||
"constant": false,
|
||||
"type": "function",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "k",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "ret_k",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "ret_g",
|
||||
"type": "uint256"
|
||||
}
|
||||
]
|
||||
}
|
||||
])";
|
||||
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function f(uint k) returns(uint){
|
||||
return k;
|
||||
}
|
||||
})";
|
||||
|
||||
char const* interface = R"([
|
||||
{
|
||||
"name": "f",
|
||||
"constant": false,
|
||||
"type": "function",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "k",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
]
|
||||
}
|
||||
])";
|
||||
checkInterface(sourceCode, interface);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
@ -92,6 +92,26 @@ BOOST_AUTO_TEST_CASE(multiple_functions)
|
||||
BOOST_CHECK(callContractFunction("i_am_not_there()", bytes()) == bytes());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(named_args)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
||||
" function b() returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(disorder_named_args)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
||||
" function b() returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(while_loop)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
@ -556,7 +576,7 @@ BOOST_AUTO_TEST_CASE(simple_mapping)
|
||||
" }\n"
|
||||
"}";
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
|
||||
BOOST_CHECK(callContractFunction("get(uint8)", byte(0)) == encodeArgs(byte(0x00)));
|
||||
BOOST_CHECK(callContractFunction("get(uint8)", byte(0x01)) == encodeArgs(byte(0x00)));
|
||||
BOOST_CHECK(callContractFunction("get(uint8)", byte(0xa7)) == encodeArgs(byte(0x00)));
|
||||
@ -885,7 +905,7 @@ BOOST_AUTO_TEST_CASE(constructor)
|
||||
BOOST_AUTO_TEST_CASE(simple_accessor)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" uint256 data;\n"
|
||||
" uint256 public data;\n"
|
||||
" function test() {\n"
|
||||
" data = 8;\n"
|
||||
" }\n"
|
||||
@ -897,10 +917,10 @@ BOOST_AUTO_TEST_CASE(simple_accessor)
|
||||
BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" uint256 data;\n"
|
||||
" string6 name;\n"
|
||||
" hash a_hash;\n"
|
||||
" address an_address;\n"
|
||||
" uint256 public data;\n"
|
||||
" string6 public name;\n"
|
||||
" hash public a_hash;\n"
|
||||
" address public an_address;\n"
|
||||
" function test() {\n"
|
||||
" data = 8;\n"
|
||||
" name = \"Celina\";\n"
|
||||
@ -908,17 +928,55 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
|
||||
" an_address = address(0x1337);\n"
|
||||
" super_secret_data = 42;\n"
|
||||
" }\n"
|
||||
" private:"
|
||||
" uint256 super_secret_data;"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("data()") == encodeArgs(8));
|
||||
BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina"));
|
||||
BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(toBigEndian(u256(123)))));
|
||||
BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes({0x7b}))));
|
||||
BOOST_CHECK(callContractFunction("an_address()") == encodeArgs(toBigEndian(u160(0x1337))));
|
||||
BOOST_CHECK(callContractFunction("super_secret_data()") == bytes());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(complex_accessors)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" mapping(uint256 => string4) public to_string_map;\n"
|
||||
" mapping(uint256 => bool) public to_bool_map;\n"
|
||||
" mapping(uint256 => uint256) public to_uint_map;\n"
|
||||
" mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n"
|
||||
" function test() {\n"
|
||||
" to_string_map[42] = \"24\";\n"
|
||||
" to_bool_map[42] = false;\n"
|
||||
" to_uint_map[42] = 12;\n"
|
||||
" to_multiple_map[42][23] = 31;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("to_string_map(uint256)", 42) == encodeArgs("24"));
|
||||
BOOST_CHECK(callContractFunction("to_bool_map(uint256)", 42) == encodeArgs(false));
|
||||
BOOST_CHECK(callContractFunction("to_uint_map(uint256)", 42) == encodeArgs(12));
|
||||
BOOST_CHECK(callContractFunction("to_multiple_map(uint256,uint256)", 42, 23) == encodeArgs(31));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(struct_accessor)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }
|
||||
mapping(uint => Data) public data;
|
||||
function test() {
|
||||
data[7].a = 1;
|
||||
data[7].b = 2;
|
||||
data[7].c[0] = 3;
|
||||
data[7].d = true;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("data(uint256)", 7) == encodeArgs(1, 2, true));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(balance)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
@ -1490,8 +1548,7 @@ BOOST_AUTO_TEST_CASE(functions_called_by_constructor)
|
||||
setName("abc");
|
||||
}
|
||||
function getName() returns (string3 ret) { return name; }
|
||||
private:
|
||||
function setName(string3 _name) { name = _name; }
|
||||
function setName(string3 _name) private { name = _name; }
|
||||
})";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_REQUIRE(callContractFunction("getName()") == encodeArgs("abc"));
|
||||
@ -2056,6 +2113,94 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data)
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,hash256,uint256,bool)")));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
})";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) != encodeArgs(5, 8));
|
||||
BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) == encodeArgs(9, 8));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function f(uint k) returns(uint){
|
||||
return k;
|
||||
}
|
||||
})";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("f(uint256)", 9) == encodeArgs(9));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sha3_multiple_arguments)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract c {
|
||||
function foo(uint a, uint b, uint c) returns (hash d)
|
||||
{
|
||||
d = sha3(a, b, c);
|
||||
}
|
||||
})";
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
BOOST_CHECK(callContractFunction("foo(uint256,uint256,uint256)", 10, 12, 13) == encodeArgs(
|
||||
dev::sha3(
|
||||
toBigEndian(u256(10)) +
|
||||
toBigEndian(u256(12)) +
|
||||
toBigEndian(u256(13)))));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract c {
|
||||
function foo(uint a, uint16 b) returns (hash d)
|
||||
{
|
||||
d = sha3(a, b, 145);
|
||||
}
|
||||
})";
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
BOOST_CHECK(callContractFunction("foo(uint256,uint16)", 10, 12) == encodeArgs(
|
||||
dev::sha3(
|
||||
toBigEndian(u256(10)) +
|
||||
bytes({0x0, 0xc}) +
|
||||
bytes({0x91}))));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract c {
|
||||
function foo() returns (hash d)
|
||||
{
|
||||
d = sha3("foo");
|
||||
}
|
||||
function bar(uint a, uint16 b) returns (hash d)
|
||||
{
|
||||
d = sha3(a, b, 145, "foo");
|
||||
}
|
||||
})";
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
BOOST_CHECK(callContractFunction("foo()") == encodeArgs(dev::sha3("foo")));
|
||||
|
||||
BOOST_CHECK(callContractFunction("bar(uint256,uint16)", 10, 12) == encodeArgs(
|
||||
dev::sha3(
|
||||
toBigEndian(u256(10)) +
|
||||
bytes({0x0, 0xc}) +
|
||||
bytes({0x91}) +
|
||||
bytes({0x66, 0x6f, 0x6f}))));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -91,7 +91,15 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _
|
||||
{
|
||||
Parser parser;
|
||||
ASTPointer<SourceUnit> sourceUnit;
|
||||
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
|
||||
try
|
||||
{
|
||||
sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)));
|
||||
}
|
||||
catch(boost::exception const& _e)
|
||||
{
|
||||
auto msg = std::string("Parsing source code failed with: \n") + boost::diagnostic_information(_e);
|
||||
BOOST_FAIL(msg);
|
||||
}
|
||||
|
||||
vector<Declaration const*> declarations;
|
||||
declarations.reserve(_globalDeclarations.size() + 1);
|
||||
@ -177,6 +185,66 @@ BOOST_AUTO_TEST_CASE(int_literal)
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function test ()
|
||||
{
|
||||
var x = 1 wei;
|
||||
}
|
||||
})";
|
||||
bytes code = compileFirstExpression(sourceCode);
|
||||
|
||||
bytes expectation({byte(eth::Instruction::PUSH1), 0x1});
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(int_with_szabo_ether_subdenomination)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function test ()
|
||||
{
|
||||
var x = 1 szabo;
|
||||
}
|
||||
})";
|
||||
bytes code = compileFirstExpression(sourceCode);
|
||||
|
||||
bytes expectation({byte(eth::Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00});
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(int_with_finney_ether_subdenomination)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function test ()
|
||||
{
|
||||
var x = 1 finney;
|
||||
}
|
||||
})";
|
||||
bytes code = compileFirstExpression(sourceCode);
|
||||
|
||||
bytes expectation({byte(eth::Instruction::PUSH7), 0x3, 0x8d, 0x7e, 0xa4, 0xc6, 0x80, 0x00});
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function test ()
|
||||
{
|
||||
var x = 1 ether;
|
||||
}
|
||||
})";
|
||||
bytes code = compileFirstExpression(sourceCode);
|
||||
|
||||
bytes expectation({byte(eth::Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparison)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
@ -409,7 +477,7 @@ BOOST_AUTO_TEST_CASE(blockhash)
|
||||
" }\n"
|
||||
"}\n";
|
||||
bytes code = compileFirstExpression(sourceCode, {}, {},
|
||||
{make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::BLOCK))});
|
||||
{make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::Block))});
|
||||
|
||||
bytes expectation({byte(eth::Instruction::PUSH1), 0x03,
|
||||
byte(eth::Instruction::BLOCKHASH)});
|
||||
|
173
SolidityInterface.cpp
Normal file
173
SolidityInterface.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
|
||||
cpp-ethereum 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.
|
||||
|
||||
cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
* @date 2015
|
||||
* Unit tests for generating source interfaces for Solidity contracts.
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <libsolidity/CompilerStack.h>
|
||||
#include <libsolidity/AST.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
class SolidityInterfaceChecker
|
||||
{
|
||||
public:
|
||||
SolidityInterfaceChecker(): m_compilerStack(false) {}
|
||||
|
||||
/// Compiles the given code, generates the interface and parses that again.
|
||||
ContractDefinition const& checkInterface(string const& _code, string const& _contractName = "")
|
||||
{
|
||||
m_code = _code;
|
||||
BOOST_REQUIRE_NO_THROW(m_compilerStack.parse(_code));
|
||||
m_interface = m_compilerStack.getMetadata("", DocumentationType::ABISolidityInterface);
|
||||
BOOST_REQUIRE_NO_THROW(m_reCompiler.parse(m_interface));
|
||||
return m_reCompiler.getContractDefinition(_contractName);
|
||||
}
|
||||
|
||||
string getSourcePart(ASTNode const& _node) const
|
||||
{
|
||||
Location location = _node.getLocation();
|
||||
BOOST_REQUIRE(!location.isEmpty());
|
||||
return m_interface.substr(location.start, location.end - location.start);
|
||||
}
|
||||
|
||||
protected:
|
||||
string m_code;
|
||||
string m_interface;
|
||||
CompilerStack m_compilerStack;
|
||||
CompilerStack m_reCompiler;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(SolidityInterface, SolidityInterfaceChecker)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_contract)
|
||||
{
|
||||
ContractDefinition const& contract = checkInterface("contract test {}");
|
||||
BOOST_CHECK_EQUAL(getSourcePart(contract), "contract test{}");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(single_function)
|
||||
{
|
||||
ContractDefinition const& contract = checkInterface(
|
||||
"contract test {\n"
|
||||
" function f(uint a) returns(uint d) { return a * 7; }\n"
|
||||
"}\n");
|
||||
BOOST_REQUIRE_EQUAL(1, contract.getDefinedFunctions().size());
|
||||
BOOST_CHECK_EQUAL(getSourcePart(*contract.getDefinedFunctions().front()),
|
||||
"function f(uint256 a)returns(uint256 d){}");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(single_constant_function)
|
||||
{
|
||||
ContractDefinition const& contract = checkInterface(
|
||||
"contract test { function f(uint a) constant returns(hash8 x) { 1==2; } }");
|
||||
BOOST_REQUIRE_EQUAL(1, contract.getDefinedFunctions().size());
|
||||
BOOST_CHECK_EQUAL(getSourcePart(*contract.getDefinedFunctions().front()),
|
||||
"function f(uint256 a)constant returns(hash8 x){}");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_functions)
|
||||
{
|
||||
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";
|
||||
ContractDefinition const& contract = checkInterface(sourceCode);
|
||||
set<string> expectation({"function f(uint256 a)returns(uint256 d){}",
|
||||
"function g(uint256 b)returns(uint256 e){}"});
|
||||
BOOST_REQUIRE_EQUAL(2, contract.getDefinedFunctions().size());
|
||||
BOOST_CHECK(expectation == set<string>({getSourcePart(*contract.getDefinedFunctions().at(0)),
|
||||
getSourcePart(*contract.getDefinedFunctions().at(1))}));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(exclude_fallback_function)
|
||||
{
|
||||
char const* sourceCode = "contract test { function() {} }";
|
||||
ContractDefinition const& contract = checkInterface(sourceCode);
|
||||
BOOST_CHECK_EQUAL(getSourcePart(contract), "contract test{}");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event)
|
||||
{
|
||||
ContractDefinition const& contract = checkInterface(
|
||||
"contract test { event Event; }");
|
||||
BOOST_REQUIRE_EQUAL(1, contract.getEvents().size());
|
||||
BOOST_CHECK_EQUAL(getSourcePart(*contract.getEvents().front()),
|
||||
"event Event;");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_arguments)
|
||||
{
|
||||
ContractDefinition const& contract = checkInterface(
|
||||
"contract test { event Event(uint a, uint indexed b); }");
|
||||
BOOST_REQUIRE_EQUAL(1, contract.getEvents().size());
|
||||
BOOST_CHECK_EQUAL(getSourcePart(*contract.getEvents().front()),
|
||||
"event Event(uint256 a,uint256 indexed b);");
|
||||
}
|
||||
|
||||
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";
|
||||
ContractDefinition const& contract = checkInterface(sourceCode);
|
||||
set<string> expectation({"event e1(uint256 b,address indexed c);", "event e2;"});
|
||||
BOOST_REQUIRE_EQUAL(2, contract.getEvents().size());
|
||||
BOOST_CHECK(expectation == set<string>({getSourcePart(*contract.getEvents().at(0)),
|
||||
getSourcePart(*contract.getEvents().at(1))}));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inheritance)
|
||||
{
|
||||
char const* sourceCode =
|
||||
" contract Base { \n"
|
||||
" function baseFunction(uint p) returns (uint i) { return p; } \n"
|
||||
" event baseEvent(string32 indexed evtArgBase); \n"
|
||||
" } \n"
|
||||
" contract Derived is Base { \n"
|
||||
" function derivedFunction(string32 p) returns (string32 i) { return p; } \n"
|
||||
" event derivedEvent(uint indexed evtArgDerived); \n"
|
||||
" }";
|
||||
ContractDefinition const& contract = checkInterface(sourceCode);
|
||||
set<string> expectedEvents({"event derivedEvent(uint256 indexed evtArgDerived);",
|
||||
"event baseEvent(string32 indexed evtArgBase);"});
|
||||
set<string> expectedFunctions({"function baseFunction(uint256 p)returns(uint256 i){}",
|
||||
"function derivedFunction(string32 p)returns(string32 i){}"});
|
||||
BOOST_CHECK(expectedEvents == set<string>({getSourcePart(*contract.getEvents().at(0)),
|
||||
getSourcePart(*contract.getEvents().at(1))}));
|
||||
BOOST_REQUIRE_EQUAL(2, contract.getDefinedFunctions().size());
|
||||
BOOST_CHECK(expectedFunctions == set<string>({getSourcePart(*contract.getDefinedFunctions().at(0)),
|
||||
getSourcePart(*contract.getDefinedFunctions().at(1))}));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -467,6 +467,24 @@ BOOST_AUTO_TEST_CASE(illegal_override_indirect)
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(illegal_override_visibility)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract B { function f() protected {} }
|
||||
contract C is B { function f() public {} }
|
||||
)";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(illegal_override_constness)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract B { function f() constant {} }
|
||||
contract C is B { function f() {} }
|
||||
)";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(complex_inheritance)
|
||||
{
|
||||
char const* text = R"(
|
||||
@ -636,7 +654,9 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
|
||||
" function fun() {\n"
|
||||
" uint64(2);\n"
|
||||
" }\n"
|
||||
"uint256 foo;\n"
|
||||
"uint256 public foo;\n"
|
||||
"mapping(uint=>string4) public map;\n"
|
||||
"mapping(uint=>mapping(uint=>string4)) public multiple_map;\n"
|
||||
"}\n";
|
||||
|
||||
ASTPointer<SourceUnit> source;
|
||||
@ -644,10 +664,27 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
|
||||
BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text));
|
||||
BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr);
|
||||
FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()");
|
||||
BOOST_REQUIRE(function->hasDeclaration());
|
||||
BOOST_REQUIRE(function && function->hasDeclaration());
|
||||
auto returnParams = function->getReturnParameterTypeNames();
|
||||
BOOST_CHECK_EQUAL(returnParams.at(0), "uint256");
|
||||
BOOST_CHECK(function->isConstant());
|
||||
|
||||
function = retrieveFunctionBySignature(contract, "map(uint256)");
|
||||
BOOST_REQUIRE(function && function->hasDeclaration());
|
||||
auto params = function->getParameterTypeNames();
|
||||
BOOST_CHECK_EQUAL(params.at(0), "uint256");
|
||||
returnParams = function->getReturnParameterTypeNames();
|
||||
BOOST_CHECK_EQUAL(returnParams.at(0), "string4");
|
||||
BOOST_CHECK(function->isConstant());
|
||||
|
||||
function = retrieveFunctionBySignature(contract, "multiple_map(uint256,uint256)");
|
||||
BOOST_REQUIRE(function && function->hasDeclaration());
|
||||
params = function->getParameterTypeNames();
|
||||
BOOST_CHECK_EQUAL(params.at(0), "uint256");
|
||||
BOOST_CHECK_EQUAL(params.at(1), "uint256");
|
||||
returnParams = function->getReturnParameterTypeNames();
|
||||
BOOST_CHECK_EQUAL(returnParams.at(0), "string4");
|
||||
BOOST_CHECK(function->isConstant());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor)
|
||||
@ -668,16 +705,19 @@ BOOST_AUTO_TEST_CASE(private_state_variable)
|
||||
" function fun() {\n"
|
||||
" uint64(2);\n"
|
||||
" }\n"
|
||||
"private:\n"
|
||||
"uint256 foo;\n"
|
||||
"uint256 private foo;\n"
|
||||
"uint256 protected bar;\n"
|
||||
"}\n";
|
||||
|
||||
ASTPointer<SourceUnit> source;
|
||||
ContractDefinition const* contract;
|
||||
BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text));
|
||||
BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr);
|
||||
FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()");
|
||||
FunctionTypePointer function;
|
||||
function = retrieveFunctionBySignature(contract, "foo()");
|
||||
BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a private variable should not exist");
|
||||
function = retrieveFunctionBySignature(contract, "bar()");
|
||||
BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a protected variable should not exist");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(fallback_function)
|
||||
@ -780,6 +820,160 @@ BOOST_AUTO_TEST_CASE(multiple_events_argument_clash)
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(access_to_default_function_visibility)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
function f() {}
|
||||
}
|
||||
contract d {
|
||||
function g() { c(0).f(); }
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(access_to_protected_function)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
function f() protected {}
|
||||
}
|
||||
contract d {
|
||||
function g() { c(0).f(); }
|
||||
})";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
uint a;
|
||||
}
|
||||
contract d {
|
||||
function g() { c(0).a(); }
|
||||
})";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(access_to_protected_state_variable)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
uint public a;
|
||||
}
|
||||
contract d {
|
||||
function g() { c(0).a(); }
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(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";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(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";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(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";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(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";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_name_input_parameter)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract test {
|
||||
function f(uint){
|
||||
}
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract test {
|
||||
function f() returns(bool){
|
||||
}
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
|
||||
}
|
||||
|
||||
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){
|
||||
return k;
|
||||
}
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_name_return_parameter_with_named_one)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract test {
|
||||
function f() returns(uint ret_k, uint){
|
||||
return 5;
|
||||
}
|
||||
})";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type)
|
||||
{
|
||||
char const* sourceCode = "contract c { function f() { var x = f(); } }";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
|
||||
{
|
||||
char const* sourceCodeFine = R"(
|
||||
contract c {
|
||||
function c ()
|
||||
{
|
||||
a = 115792089237316195423570985008687907853269984665640564039458;
|
||||
}
|
||||
uint256 a;
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCodeFine));
|
||||
char const* sourceCode = R"(
|
||||
contract c {
|
||||
function c ()
|
||||
{
|
||||
a = 115792089237316195423570985008687907853269984665640564039458 ether;
|
||||
}
|
||||
uint256 a;
|
||||
})";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -54,9 +54,9 @@ public:
|
||||
}
|
||||
|
||||
if (_userDocumentation)
|
||||
generatedDocumentationString = m_compilerStack.getMetadata("", DocumentationType::NATSPEC_USER);
|
||||
generatedDocumentationString = m_compilerStack.getMetadata("", DocumentationType::NatspecUser);
|
||||
else
|
||||
generatedDocumentationString = m_compilerStack.getMetadata("", DocumentationType::NATSPEC_DEV);
|
||||
generatedDocumentationString = m_compilerStack.getMetadata("", DocumentationType::NatspecDev);
|
||||
Json::Value generatedDocumentation;
|
||||
m_reader.parse(generatedDocumentationString, generatedDocumentation);
|
||||
Json::Value expectedDocumentation;
|
||||
|
@ -124,14 +124,30 @@ BOOST_AUTO_TEST_CASE(single_function_param)
|
||||
BOOST_CHECK_NO_THROW(parseText(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args)
|
||||
{
|
||||
char const* text = "contract test {\n"
|
||||
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
||||
" function b() returns (uint r) { r = a({: 1, : 2, : 3}); }\n"
|
||||
"}\n";
|
||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(missing_argument_in_named_args)
|
||||
{
|
||||
char const* text = "contract test {\n"
|
||||
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
||||
" function b() returns (uint r) { r = a({a: , b: , c: }); }\n"
|
||||
"}\n";
|
||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(function_natspec_documentation)
|
||||
{
|
||||
ASTPointer<ContractDefinition> contract;
|
||||
ASTPointer<FunctionDefinition> function;
|
||||
char const* text = "contract test {\n"
|
||||
" private:\n"
|
||||
" uint256 stateVar;\n"
|
||||
" public:\n"
|
||||
" uint256 stateVar;\n"
|
||||
" /// This is a test function\n"
|
||||
" function functionName(hash hashin) returns (hash hashout) {}\n"
|
||||
"}\n";
|
||||
@ -162,9 +178,7 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
|
||||
ASTPointer<ContractDefinition> contract;
|
||||
ASTPointer<FunctionDefinition> function;
|
||||
char const* text = "contract test {\n"
|
||||
" private:\n"
|
||||
" uint256 stateVar;\n"
|
||||
" public:\n"
|
||||
" /// This is test function 1\n"
|
||||
" function functionName1(hash hashin) returns (hash hashout) {}\n"
|
||||
" /// This is test function 2\n"
|
||||
@ -621,6 +635,63 @@ BOOST_AUTO_TEST_CASE(event_arguments_indexed)
|
||||
BOOST_CHECK_NO_THROW(parseText(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(visibility_specifiers)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
uint private a;
|
||||
uint protected b;
|
||||
uint public c;
|
||||
uint d;
|
||||
function f() {}
|
||||
function f_priv() private {}
|
||||
function f_public() public {}
|
||||
function f_protected() protected {}
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseText(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
uint private protected a;
|
||||
})";
|
||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
function c ()
|
||||
{
|
||||
a = 1 wei;
|
||||
b = 2 szabo;
|
||||
c = 3 finney;
|
||||
b = 4 ether;
|
||||
}
|
||||
uint256 a;
|
||||
uint256 b;
|
||||
uint256 c;
|
||||
uint256 d;
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expressions)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract c {
|
||||
function c ()
|
||||
{
|
||||
a = 1 wei * 100 wei + 7 szabo - 3;
|
||||
}
|
||||
uint256 a;
|
||||
})";
|
||||
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -41,17 +41,17 @@ BOOST_AUTO_TEST_CASE(test_empty)
|
||||
BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
{
|
||||
Scanner scanner(CharStream("function break;765 \t \"string1\",'string2'\nidentifier1"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::FUNCTION);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::BREAK);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SEMICOLON);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Function);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Break);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Number);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "765");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::STRING_LITERAL);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "string1");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::COMMA);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::STRING_LITERAL);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Comma);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "string2");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "identifier1");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
}
|
||||
@ -59,85 +59,85 @@ BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
BOOST_AUTO_TEST_CASE(string_escapes)
|
||||
{
|
||||
Scanner scanner(CharStream(" { \"a\\x61\""));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::LBRACE);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::STRING_LITERAL);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::LBrace);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "aa");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(string_escapes_with_zero)
|
||||
{
|
||||
Scanner scanner(CharStream(" { \"a\\x61\\x00abc\""));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::LBRACE);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::STRING_LITERAL);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::LBrace);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), std::string("aa\0abc", 6));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(string_escape_illegal)
|
||||
{
|
||||
Scanner scanner(CharStream(" bla \"\\x6rf\" (illegalescape)"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ILLEGAL);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "");
|
||||
// TODO recovery from illegal tokens should be improved
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ILLEGAL);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ILLEGAL);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(hex_numbers)
|
||||
{
|
||||
Scanner scanner(CharStream("var x = 0x765432536763762734623472346;"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::VAR);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ASSIGN);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Var);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Assign);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Number);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "0x765432536763762734623472346");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SEMICOLON);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(negative_numbers)
|
||||
{
|
||||
Scanner scanner(CharStream("var x = -.2 + -0x78 + -7.3 + 8.9;"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::VAR);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ASSIGN);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SUB);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Var);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Assign);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Sub);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Number);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), ".2");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ADD);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SUB);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Add);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Sub);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Number);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "0x78");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ADD);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SUB);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Add);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Sub);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Number);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "7.3");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ADD);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Add);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Number);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "8.9");
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SEMICOLON);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(locations)
|
||||
{
|
||||
Scanner scanner(CharStream("function_identifier has ; -0x743/*comment*/\n ident //comment"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 0);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 19);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 20);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 23);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SEMICOLON);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 24);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 25);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SUB);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Sub);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Number);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 27);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 32);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 45);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 50);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
@ -147,13 +147,13 @@ BOOST_AUTO_TEST_CASE(ambiguities)
|
||||
{
|
||||
// test scanning of some operators which need look-ahead
|
||||
Scanner scanner(CharStream("<=""<""+ +=a++ =>""<<"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::LTE);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::LT);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ADD);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ASSIGN_ADD);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::INC);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::ARROW);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::LessThanOrEqual);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::LessThan);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Add);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::AssignAdd);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Inc);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Arrow);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SHL);
|
||||
}
|
||||
|
||||
@ -174,9 +174,9 @@ BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed_begin)
|
||||
BOOST_AUTO_TEST_CASE(documentation_comments_parsed)
|
||||
{
|
||||
Scanner scanner(CharStream("some other tokens /// Send $(value / 1000) chocolates to the user"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
|
||||
}
|
||||
@ -186,9 +186,9 @@ BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed)
|
||||
Scanner scanner(CharStream("some other tokens /**\n"
|
||||
"* Send $(value / 1000) chocolates to the user\n"
|
||||
"*/"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
|
||||
}
|
||||
@ -198,9 +198,9 @@ BOOST_AUTO_TEST_CASE(multiline_documentation_no_stars)
|
||||
Scanner scanner(CharStream("some other tokens /**\n"
|
||||
" Send $(value / 1000) chocolates to the user\n"
|
||||
"*/"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
|
||||
}
|
||||
@ -210,9 +210,9 @@ BOOST_AUTO_TEST_CASE(multiline_documentation_whitespace_hell)
|
||||
Scanner scanner(CharStream("some other tokens /** \t \r \n"
|
||||
"\t \r * Send $(value / 1000) chocolates to the user\n"
|
||||
"*/"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
|
||||
}
|
||||
@ -250,11 +250,20 @@ BOOST_AUTO_TEST_CASE(comments_mixed_in_sequence)
|
||||
Scanner scanner(CharStream("hello_world ///documentation comment \n"
|
||||
"//simple comment \n"
|
||||
"<<"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::Identifier);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SHL);
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "documentation comment ");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ether_subdenominations)
|
||||
{
|
||||
Scanner scanner(CharStream("wei szabo finney ether"));
|
||||
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::SubWei);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SubSzabo);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SubFinney);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::SubEther);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,8 @@
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <libdevcore/CommonJS.h>
|
||||
#include <libdevcore/Log.h>
|
||||
#include <libethcore/CommonJS.h>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(commonjs)
|
||||
using namespace std;
|
||||
@ -41,7 +42,7 @@ BOOST_AUTO_TEST_CASE(jsToAddress)
|
||||
cnote << "Testing jsToPublic...";
|
||||
KeyPair kp = KeyPair::create();
|
||||
string string = toJS(kp.address());
|
||||
Address address = dev::jsToAddress(string);
|
||||
Address address = dev::eth::jsToAddress(string);
|
||||
BOOST_CHECK_EQUAL(kp.address(), address);
|
||||
}
|
||||
|
||||
|
2
fork.cpp
2
fork.cpp
@ -23,7 +23,7 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <libethereum/Client.h>
|
||||
#include <libethereum/BlockChain.h>
|
||||
#include <libethereum/CanonBlockChain.h>
|
||||
#include <libethereum/EthereumHost.h>
|
||||
#include "TestHelper.h"
|
||||
using namespace std;
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <random>
|
||||
#include "JsonSpiritHeaders.h"
|
||||
#include <libdevcore/CommonIO.h>
|
||||
#include <libethereum/BlockChain.h>
|
||||
#include <libethereum/CanonBlockChain.h>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "TestHelper.h"
|
||||
|
||||
@ -58,9 +58,9 @@ BOOST_AUTO_TEST_CASE(genesis_tests)
|
||||
|
||||
js::mObject o = v.get_obj();
|
||||
|
||||
BOOST_CHECK_EQUAL(BlockChain::genesis().stateRoot, h256(o["genesis_state_root"].get_str()));
|
||||
BOOST_CHECK_EQUAL(toHex(BlockChain::createGenesisBlock()), toHex(fromHex(o["genesis_rlp_hex"].get_str())));
|
||||
BOOST_CHECK_EQUAL(BlockInfo::headerHash(BlockChain::createGenesisBlock()), h256(o["genesis_hash"].get_str()));
|
||||
BOOST_CHECK_EQUAL(CanonBlockChain::genesis().stateRoot, h256(o["genesis_state_root"].get_str()));
|
||||
BOOST_CHECK_EQUAL(toHex(CanonBlockChain::createGenesisBlock()), toHex(fromHex(o["genesis_rlp_hex"].get_str())));
|
||||
BOOST_CHECK_EQUAL(BlockInfo::headerHash(CanonBlockChain::createGenesisBlock()), h256(o["genesis_hash"].get_str()));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <libdevcore/Log.h>
|
||||
#include <libdevcore/CommonIO.h>
|
||||
#include <libdevcore/CommonJS.h>
|
||||
#include <libethcore/CommonJS.h>
|
||||
#include <libwebthree/WebThree.h>
|
||||
#include <libweb3jsonrpc/WebThreeStubServer.h>
|
||||
#include <jsonrpccpp/server/connectors/httpserver.h>
|
||||
|
116
natspec.cpp
Normal file
116
natspec.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
|
||||
cpp-ethereum 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.
|
||||
|
||||
cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file natspec.cpp
|
||||
* @author Marek Kotewicz <marek@ethdev.com>
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
#if !ETH_HEADLESS
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <libdevcore/Log.h>
|
||||
#include <libnatspec/NatspecExpressionEvaluator.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(natspec)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_eval_function_exists)
|
||||
{
|
||||
// given
|
||||
NatspecExpressionEvaluator e;
|
||||
// when
|
||||
string result = e.evalExpression("`typeof evaluateExpression`").toStdString();
|
||||
// then
|
||||
BOOST_CHECK_EQUAL(result, "function");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_js_eval)
|
||||
{
|
||||
// given
|
||||
NatspecExpressionEvaluator e;
|
||||
// when
|
||||
string result = e.evalExpression("`1 + 2`").toStdString();
|
||||
// then
|
||||
BOOST_CHECK_EQUAL(result, "3");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_create_custom_function)
|
||||
{
|
||||
// given
|
||||
NatspecExpressionEvaluator e;
|
||||
// when
|
||||
auto x = e.evalExpression("`test = function (x) { return x + 'ok'; }`"); // ommit var, make it global
|
||||
string result = e.evalExpression("`test(5)`").toStdString();
|
||||
string result2 = e.evalExpression("`typeof test`").toStdString();
|
||||
// then
|
||||
BOOST_CHECK_EQUAL(result, "5ok");
|
||||
BOOST_CHECK_EQUAL(result2, "function");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_js_eval_separated_expressions)
|
||||
{
|
||||
// given
|
||||
NatspecExpressionEvaluator e;
|
||||
// when
|
||||
string result = e.evalExpression("`x = 1` + `y = 2` will be equal `x + y`").toStdString();
|
||||
// then
|
||||
BOOST_CHECK_EQUAL(result, "1 + 2 will be equal 3");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_js_eval_input_params)
|
||||
{
|
||||
// given
|
||||
char const* abi = R"([
|
||||
{
|
||||
"name": "f",
|
||||
"constant": false,
|
||||
"type": "function",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "a",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "d",
|
||||
"type": "uint256"
|
||||
}
|
||||
]
|
||||
}
|
||||
])";
|
||||
NatspecExpressionEvaluator e(abi, "'f'", "[4]");
|
||||
// when
|
||||
string result = e.evalExpression("Will multiply `a` by 7 and return `a * 7`.").toStdString();
|
||||
// then
|
||||
BOOST_CHECK_EQUAL(result, "Will multiply 4 by 7 and return 28.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_js_eval_error)
|
||||
{
|
||||
// given
|
||||
NatspecExpressionEvaluator e;
|
||||
// when
|
||||
string result = e.evalExpression("`test(`").toStdString();
|
||||
// then
|
||||
BOOST_CHECK_EQUAL(result, "`test(`");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
#endif
|
@ -303,6 +303,34 @@
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"data" : ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"RefundOverflow" : {
|
||||
"env" : {
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
|
||||
"currentDifficulty" : "45678256",
|
||||
"currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
|
||||
"currentNumber" : "0",
|
||||
"currentTimestamp" : 1,
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
|
||||
},
|
||||
"pre" : {
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "400",
|
||||
"code" : "0x",
|
||||
"nonce" : "0",
|
||||
"storage" : {
|
||||
}
|
||||
}
|
||||
},
|
||||
"transaction" : {
|
||||
"data" : "",
|
||||
"gasLimit" : "5789604461865809771178549250434395392663499233282028201972879200395656482016",
|
||||
"gasPrice" : "20",
|
||||
"nonce" : "0",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"value" : ""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,76 @@
|
||||
}
|
||||
},
|
||||
|
||||
"testRandomTest": {
|
||||
"env" : {
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
|
||||
"currentDifficulty" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
|
||||
"currentGasLimit" : "1000000",
|
||||
"currentNumber" : "300",
|
||||
"currentTimestamp" : "2",
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
|
||||
},
|
||||
"pre" : {
|
||||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
|
||||
"balance" : "1000000000000000000",
|
||||
"code" : "0x424443444243434383f0155af055",
|
||||
"nonce" : "0",
|
||||
"storage" : {
|
||||
}
|
||||
},
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "1000000000000000000",
|
||||
"code" : "0x",
|
||||
"nonce" : "0",
|
||||
"storage" : {
|
||||
}
|
||||
}
|
||||
},
|
||||
"transaction" : {
|
||||
"data" : "",
|
||||
"gasLimit" : "10000",
|
||||
"gasPrice" : "1",
|
||||
"nonce" : "0",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||
"value" : "100000"
|
||||
}
|
||||
},
|
||||
|
||||
"createWithInvalidOpcode": {
|
||||
"env" : {
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
|
||||
"currentDifficulty" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
|
||||
"currentGasLimit" : "1000000",
|
||||
"currentNumber" : "300",
|
||||
"currentTimestamp" : "2",
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
|
||||
},
|
||||
"pre" : {
|
||||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
|
||||
"balance" : "1000000000000000000",
|
||||
"nonce" : 0,
|
||||
"code" : "0x444242424245434253f0",
|
||||
"storage": {}
|
||||
},
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "1000000000000000000",
|
||||
"nonce" : 0,
|
||||
"code" : "",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"transaction" : {
|
||||
"nonce" : "0",
|
||||
"gasPrice" : "1",
|
||||
"gasLimit" : "10000",
|
||||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
|
||||
"value" : "100000",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"data" : ""
|
||||
}
|
||||
},
|
||||
|
||||
"createNameRegistratorOOG_MemExpansionInsufficientBalance": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
|
@ -169,7 +169,7 @@
|
||||
},
|
||||
"pre" :
|
||||
{
|
||||
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "1000",
|
||||
"code" : "",
|
||||
"nonce" : "0",
|
||||
@ -189,6 +189,68 @@
|
||||
}
|
||||
},
|
||||
|
||||
"TransactionFromCoinbaseHittingBlockGasLimit" : {
|
||||
"env" : {
|
||||
"currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"currentDifficulty" : "45678256",
|
||||
"currentGasLimit" : "1100",
|
||||
"currentNumber" : "0",
|
||||
"currentTimestamp" : 1,
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
|
||||
},
|
||||
"pre" :
|
||||
{
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "1000000",
|
||||
"code" : "",
|
||||
"nonce" : "0",
|
||||
"storage" : {
|
||||
}
|
||||
}
|
||||
},
|
||||
"transaction" :
|
||||
{
|
||||
"data" : "",
|
||||
"gasLimit" : "1100",
|
||||
"gasPrice" : "1",
|
||||
"nonce" : "",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"value" : "10"
|
||||
}
|
||||
},
|
||||
|
||||
"TransactionFromCoinbaseHittingBlockGasLimit1" : {
|
||||
"env" : {
|
||||
"currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"currentDifficulty" : "45678256",
|
||||
"currentGasLimit" : "1100",
|
||||
"currentNumber" : "0",
|
||||
"currentTimestamp" : 1,
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
|
||||
},
|
||||
"pre" :
|
||||
{
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "100000",
|
||||
"code" : "",
|
||||
"nonce" : "0",
|
||||
"storage" : {
|
||||
}
|
||||
}
|
||||
},
|
||||
"transaction" :
|
||||
{
|
||||
"data" : "",
|
||||
"gasLimit" : "1101",
|
||||
"gasPrice" : "1",
|
||||
"nonce" : "",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"value" : "10"
|
||||
}
|
||||
},
|
||||
|
||||
"ContractStoreClearsSuccess" : {
|
||||
"env" : {
|
||||
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "JsonSpiritHeaders.h"
|
||||
#include <libdevcore/CommonIO.h>
|
||||
#include <libethereum/BlockChain.h>
|
||||
#include <libethereum/CanonBlockChain.h>
|
||||
#include <libethereum/State.h>
|
||||
#include <libethereum/ExtVM.h>
|
||||
#include <libethereum/Defaults.h>
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <secp256k1/secp256k1.h>
|
||||
#include <libethereum/BlockChain.h>
|
||||
#include <libethereum/CanonBlockChain.h>
|
||||
#include <libethereum/State.h>
|
||||
#include <libethereum/Defaults.h>
|
||||
using namespace std;
|
||||
@ -40,7 +40,7 @@ int stateTest()
|
||||
Defaults::setDBPath(boost::filesystem::temp_directory_path().string());
|
||||
|
||||
OverlayDB stateDB = State::openDB();
|
||||
BlockChain bc;
|
||||
CanonBlockChain bc;
|
||||
State s(myMiner.address(), stateDB);
|
||||
|
||||
cout << bc;
|
||||
@ -75,7 +75,8 @@ int stateTest()
|
||||
|
||||
// Mine to get some ether and set in stone.
|
||||
s.commitToMine(bc);
|
||||
while (!s.mine(100).completed) {}
|
||||
s.commitToMine(bc);
|
||||
while (!s.mine(50).completed) { s.commitToMine(bc); }
|
||||
s.completeMine();
|
||||
bc.attemptImport(s.blockData(), stateDB);
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <libethereum/Client.h>
|
||||
#include <libethereum/BlockChain.h>
|
||||
#include <libethereum/CanonBlockChain.h>
|
||||
#include <libethereum/EthereumHost.h>
|
||||
#include "TestHelper.h"
|
||||
using namespace std;
|
||||
|
@ -193,5 +193,89 @@
|
||||
"gasPrice" : "100000000000000",
|
||||
"gas" : "10000"
|
||||
}
|
||||
},
|
||||
|
||||
"sha3_bigSize": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
"currentGasLimit" : "1000000",
|
||||
"currentDifficulty" : "256",
|
||||
"currentTimestamp" : 1,
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
|
||||
},
|
||||
"pre" : {
|
||||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
|
||||
"balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"nonce" : 0,
|
||||
"code" : "{ [[ 0 ]] (SHA3 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)}",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"exec" : {
|
||||
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
|
||||
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
|
||||
"value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"data" : "",
|
||||
"gasPrice" : "1",
|
||||
"gas" : "0x10000000000"
|
||||
}
|
||||
},
|
||||
|
||||
"sha3_bigOffset": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
"currentGasLimit" : "1000000",
|
||||
"currentDifficulty" : "256",
|
||||
"currentTimestamp" : 1,
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
|
||||
},
|
||||
"pre" : {
|
||||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
|
||||
"balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"nonce" : 0,
|
||||
"code" : "{ [[ 0 ]] (SHA3 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2)}",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"exec" : {
|
||||
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
|
||||
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
|
||||
"value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"data" : "",
|
||||
"gasPrice" : "1",
|
||||
"gas" : "0x10000000000"
|
||||
}
|
||||
},
|
||||
|
||||
"sha3_bigOffset2": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
"currentGasLimit" : "1000000",
|
||||
"currentDifficulty" : "256",
|
||||
"currentTimestamp" : 1,
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
|
||||
},
|
||||
"pre" : {
|
||||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
|
||||
"balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"nonce" : 0,
|
||||
"code" : "{ [[ 0 ]] (SHA3 0x1000000 2)}",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"exec" : {
|
||||
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
|
||||
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
|
||||
"value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"data" : "",
|
||||
"gasPrice" : "1",
|
||||
"gas" : "0x100000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +213,16 @@ class WebThreeStubClient : public jsonrpc::Client
|
||||
else
|
||||
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
|
||||
}
|
||||
bool eth_flush() throw (jsonrpc::JsonRpcException)
|
||||
{
|
||||
Json::Value p;
|
||||
p = Json::nullValue;
|
||||
Json::Value result = this->CallMethod("eth_flush",p);
|
||||
if (result.isBool())
|
||||
return result.asBool();
|
||||
else
|
||||
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
|
||||
}
|
||||
Json::Value eth_blockByHash(const std::string& param1) throw (jsonrpc::JsonRpcException)
|
||||
{
|
||||
Json::Value p;
|
||||
@ -347,13 +357,13 @@ class WebThreeStubClient : public jsonrpc::Client
|
||||
else
|
||||
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
|
||||
}
|
||||
bool eth_changed(const int& param1) throw (jsonrpc::JsonRpcException)
|
||||
Json::Value eth_changed(const int& param1) throw (jsonrpc::JsonRpcException)
|
||||
{
|
||||
Json::Value p;
|
||||
p.append(param1);
|
||||
Json::Value result = this->CallMethod("eth_changed",p);
|
||||
if (result.isBool())
|
||||
return result.asBool();
|
||||
if (result.isArray())
|
||||
return result;
|
||||
else
|
||||
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
|
||||
}
|
||||
@ -377,6 +387,26 @@ class WebThreeStubClient : public jsonrpc::Client
|
||||
else
|
||||
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
|
||||
}
|
||||
Json::Value eth_getWork() throw (jsonrpc::JsonRpcException)
|
||||
{
|
||||
Json::Value p;
|
||||
p = Json::nullValue;
|
||||
Json::Value result = this->CallMethod("eth_getWork",p);
|
||||
if (result.isArray())
|
||||
return result;
|
||||
else
|
||||
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
|
||||
}
|
||||
bool eth_submitWork(const std::string& param1) throw (jsonrpc::JsonRpcException)
|
||||
{
|
||||
Json::Value p;
|
||||
p.append(param1);
|
||||
Json::Value result = this->CallMethod("eth_submitWork",p);
|
||||
if (result.isBool())
|
||||
return result.asBool();
|
||||
else
|
||||
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
|
||||
}
|
||||
bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
|
||||
{
|
||||
Json::Value p;
|
||||
|
@ -50,6 +50,7 @@ BOOST_AUTO_TEST_CASE(topic)
|
||||
auto w = wh->installWatch(BuildTopicMask("odd"));
|
||||
|
||||
started = true;
|
||||
set<unsigned> received;
|
||||
|
||||
for (int iterout = 0, last = 0; iterout < 200 && last < 81; ++iterout)
|
||||
{
|
||||
@ -57,6 +58,9 @@ BOOST_AUTO_TEST_CASE(topic)
|
||||
{
|
||||
Message msg = wh->envelope(i).open(wh->fullTopic(w));
|
||||
last = RLP(msg.payload()).toInt<unsigned>();
|
||||
if (received.count(last))
|
||||
continue;
|
||||
received.insert(last);
|
||||
cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt<unsigned>();
|
||||
result += last;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user