Updates from BitShares FC #22

Closed
nathanielhourt wants to merge 693 commits from dapp-support into latest-fc
2 changed files with 58 additions and 8 deletions
Showing only changes of commit f7a1e532ca - Show all commits

View file

@ -44,13 +44,18 @@ namespace fc {
}
template<typename R, typename Arg0, typename ... Args>
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth )
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0,
variants::const_iterator e, uint32_t max_depth )
{
bool optional_args = all_optionals<std::decay_t<Arg0>, std::decay_t<Args>...>::value;
FC_ASSERT( a0 != e || optional_args );
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
auto arg = (a0 == e)? std::decay_t<Arg0>() : a0->as<std::decay_t<Arg0>>(max_depth - 1);
return call_generic<R,Args...>( bind_first_arg<R,Arg0,Args...>( f, arg ), a0+1, e, max_depth - 1 );
if (a0==e)
return call_generic<R,Args...>( bind_first_arg<R,Arg0,Args...>( f, std::decay_t<Arg0>() ), a0,
e, max_depth - 1 );
auto arg = a0->as<std::decay_t<Arg0>>(max_depth - 1);
return call_generic<R,Args...>( bind_first_arg<R,Arg0,Args...>( f, std::move(arg) ), a0+1, e,
max_depth - 1 );
}
template<typename R, typename ... Args>
@ -180,13 +185,18 @@ namespace fc {
}
template<typename R, typename Arg0, typename ... Args>
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth )
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0,
variants::const_iterator e, uint32_t max_depth )
{
bool optional_args = detail::all_optionals<std::decay_t<Arg0>, std::decay_t<Args>...>::value;
FC_ASSERT( a0 != e || optional_args, "too few arguments passed to method" );
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
auto arg = (a0 == e)? std::decay_t<Arg0>() : a0->as<std::decay_t<Arg0>>(max_depth - 1);
return call_generic<R,Args...>( this->bind_first_arg<R,Arg0,Args...>( f, arg ), a0+1, e, max_depth - 1 );
if (a0==e)
return call_generic<R,Args...>( this->bind_first_arg<R,Arg0,Args...>( f, std::decay_t<Arg0>() ), a0,
e, max_depth - 1 );
auto arg = a0->as<std::decay_t<Arg0>>(max_depth - 1);
return call_generic<R,Args...>( this->bind_first_arg<R,Arg0,Args...>( f, std::move(arg) ), a0+1, e,
max_depth - 1 );
}
struct api_visitor

View file

@ -39,8 +39,12 @@ public:
const fc::optional<std::string>& third ) {
return fc::json::to_string(fc::variants{first, {second, 2}, {third, 2}});
}
std::string bar( fc::optional<std::string> first, fc::optional<std::string> second,
fc::optional<std::string> third ) {
return fc::json::to_string(fc::variants{{first,2}, {second, 2}, {third, 2}});
}
};
FC_API( optionals_api, (foo) );
FC_API( optionals_api, (foo)(bar) );
using namespace fc;
@ -106,6 +110,12 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
BOOST_CHECK_EQUAL(oapi->foo("a", "b", "c"), "[\"a\",\"b\",\"c\"]");
BOOST_CHECK_EQUAL(oapi->foo("a", {}, "c"), "[\"a\",null,\"c\"]");
BOOST_CHECK_EQUAL(oapi->bar(), "[null,null,null]");
BOOST_CHECK_EQUAL(oapi->bar("a"), "[\"a\",null,null]");
BOOST_CHECK_EQUAL(oapi->bar("a", "b"), "[\"a\",\"b\",null]");
BOOST_CHECK_EQUAL(oapi->bar("a", "b", "c"), "[\"a\",\"b\",\"c\"]");
BOOST_CHECK_EQUAL(oapi->bar("a", {}, "c"), "[\"a\",null,\"c\"]");
auto server = std::make_shared<fc::http::websocket_server>();
server->on_connection([&]( const websocket_connection_ptr& c ){
auto wsc = std::make_shared<websocket_api_connection>(c, MAX_DEPTH);
@ -119,7 +129,6 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
auto client = std::make_shared<fc::http::websocket_client>();
auto con = client->connect( "ws://localhost:" + std::to_string(listen_port) );
server->stop_listening();
auto apic = std::make_shared<websocket_api_connection>(con, MAX_DEPTH);
auto remote_optionals = apic->get_remote_api<optionals_api>();
@ -128,6 +137,37 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
BOOST_CHECK_EQUAL(remote_optionals->foo("a", "b", "c"), "[\"a\",\"b\",\"c\"]");
BOOST_CHECK_EQUAL(remote_optionals->foo("a", {}, "c"), "[\"a\",null,\"c\"]");
BOOST_CHECK_EQUAL(remote_optionals->bar(), "[null,null,null]");
BOOST_CHECK_EQUAL(remote_optionals->bar("a"), "[\"a\",null,null]");
BOOST_CHECK_EQUAL(remote_optionals->bar("a", "b"), "[\"a\",\"b\",null]");
BOOST_CHECK_EQUAL(remote_optionals->bar("a", "b", "c"), "[\"a\",\"b\",\"c\"]");
BOOST_CHECK_EQUAL(remote_optionals->bar("a", {}, "c"), "[\"a\",null,\"c\"]");
auto client2 = std::make_shared<fc::http::websocket_client>();
auto con2 = client2->connect( "ws://localhost:" + std::to_string(listen_port) );
string response;
con2->on_message_handler([&](const std::string& s){
response = s;
});
con2->send_message( "{\"id\":1,\"method\":\"call\",\"params\":[0,\"bar\",[\"a\",\"b\",\"c\"]]}" );
fc::usleep(fc::milliseconds(50));
BOOST_CHECK_EQUAL( response, "{\"id\":1,\"result\":\"[\\\"a\\\",\\\"b\\\",\\\"c\\\"]\"}" );
con2->send_message( "{\"id\":2,\"method\":\"call\",\"params\":[0,\"bar\",[\"a\",\"b\"]]}" );
fc::usleep(fc::milliseconds(50));
BOOST_CHECK_EQUAL( response, "{\"id\":2,\"result\":\"[\\\"a\\\",\\\"b\\\",null]\"}" );
con2->send_message( "{\"id\":3,\"method\":\"call\",\"params\":[0,\"bar\",[\"a\"]]}" );
fc::usleep(fc::milliseconds(50));
BOOST_CHECK_EQUAL( response, "{\"id\":3,\"result\":\"[\\\"a\\\",null,null]\"}" );
con2->send_message( "{\"id\":4,\"method\":\"call\",\"params\":[0,\"bar\",[]]}" );
fc::usleep(fc::milliseconds(50));
BOOST_CHECK_EQUAL( response, "{\"id\":4,\"result\":\"[null,null,null]\"}" );
server->stop_listening();
client->synchronous_close();
server->close();
fc::usleep(fc::milliseconds(50));