Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turn on compiler warnings #11

Merged
merged 12 commits into from
Aug 22, 2020
14 changes: 13 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@ install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

add_library(coverage_config INTERFACE)

# Warning options for the compiler
string(
APPEND _warning_opts
"$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-Wall;-Wextra;-Weffc++;-Werror;>"
"$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wthread-safety;-Wpedantic;>"
"$<$<CXX_COMPILER_ID:GNU>:-pedantic;-pedantic-errors;>"
)


if (COMPILE_TESTS)
if (CODE_COVERAGE)
message("Enabled coverage flags")
target_compile_options(coverage_config INTERFACE -O0 -g --coverage)
target_link_libraries(coverage_config INTERFACE --coverage)
endif ()
add_executable(jsonrpccpp-test test/main.cpp test/client.cpp test/typemapper.cpp test/dispatcher.cpp test/server.cpp test/batchclient.cpp test/testclientconnector.hpp examples/warehouse/warehouseapp.cpp test/warehouseapp.cpp)
target_compile_options(jsonrpccpp-test PUBLIC "${_warning_opts}")
target_include_directories(jsonrpccpp-test PRIVATE vendor examples)
target_link_libraries(jsonrpccpp-test coverage_config json-rpc-cxx)
enable_testing()
Expand All @@ -31,8 +41,10 @@ endif ()
if (COMPILE_EXAMPLES)
find_package(Threads)
add_executable(example-warehouse examples/warehouse/main.cpp examples/warehouse/warehouseapp.cpp examples/warehouse/types.h examples/inmemoryconnector.hpp)
target_compile_options(example-warehouse PUBLIC "${_warning_opts}")
target_link_libraries(example-warehouse json-rpc-cxx Threads::Threads)
target_include_directories(example-warehouse PRIVATE vendor examples)
target_include_directories(example-warehouse SYSTEM PRIVATE vendor)
target_include_directories(example-warehouse PRIVATE examples)
add_test(NAME example COMMAND example-warehouse)
endif ()

Expand Down
23 changes: 17 additions & 6 deletions examples/cpphttplibconnector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ class CppHttpLibClientConnector : public jsonrpccxx::IClientConnector {

class CppHttpLibServerConnector {
public:
explicit CppHttpLibServerConnector(jsonrpccxx::JsonRpcServer &server, int port) : server(server), port(port) {
httpServer.Post("/jsonrpc", [&](const httplib::Request &req, httplib::Response &res) {
res.status = 200;
res.set_content(server.HandleRequest(req.body), "application/json");
});
explicit CppHttpLibServerConnector(jsonrpccxx::JsonRpcServer &server, int port) :
thread(),
server(server),
httpServer(),
port(port) {
httpServer.Post("/jsonrpc",
[this](const httplib::Request &req, httplib::Response &res) {
this->PostAction(req, res);
});
}

virtual ~CppHttpLibServerConnector() { StopListening(); }

bool StartListening() {
Expand All @@ -49,4 +54,10 @@ class CppHttpLibServerConnector {
jsonrpccxx::JsonRpcServer &server;
httplib::Server httpServer;
int port;
};

void PostAction(const httplib::Request &req,
httplib::Response &res) {
res.status = 200;
res.set_content(this->server.HandleRequest(req.body), "application/json");
}
};
8 changes: 6 additions & 2 deletions examples/warehouse/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ class WareHouseClient {
void doWarehouseStuff(IClientConnector &clientConnector) {
JsonRpcClient client(clientConnector, version::v2);
WareHouseClient appClient(client);
Product p = {"0xff", 22.4, "Product 1", category::cash_carry};
Product p;
p.id = "0xff";
p.price = 22.4;
p.name = "Product 1";
p.cat = category::cash_carry;
cout << "Adding product: " << std::boolalpha << appClient.AddProduct(p) << "\n";

Product p2 = appClient.GetProduct("0xff");
Expand Down Expand Up @@ -54,4 +58,4 @@ int main() {
doWarehouseStuff(httpClient);

return 0;
}
}
16 changes: 13 additions & 3 deletions examples/warehouse/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@
#include <nlohmann/json.hpp>

enum class category { order, cash_carry };

struct Product {
public:
Product() : id(), price(), name(), cat() {}
std::string id;
double price;
std::string name;
category cat;
};

NLOHMANN_JSON_SERIALIZE_ENUM(category, {{category::order, "order"}, {category::cash_carry, "cc"}});
inline void to_json(nlohmann::json &j, const Product &p) { j = nlohmann::json{{"id", p.id}, {"price", p.price}, {"name", p.name}, {"category", p.cat}}; }
NLOHMANN_JSON_SERIALIZE_ENUM(category, {{category::order, "order"}, {category::cash_carry, "cc"}})

inline void to_json(nlohmann::json &j, const Product &p) {
j = nlohmann::json{{"id", p.id},
{"price", p.price},
{"name", p.name},
{"category", p.cat}};
}

inline void from_json(const nlohmann::json &j, Product &p) {
j.at("name").get_to(p.name);
j.at("id").get_to(p.id);
j.at("price").get_to(p.price);
j.at("category").get_to(p.cat);
}
}
3 changes: 3 additions & 0 deletions examples/warehouse/warehouseapp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

class WarehouseServer {
public:
WarehouseServer() :
products() {}

bool AddProduct(const Product &p);
const Product& GetProduct(const std::string& id);

Expand Down
4 changes: 2 additions & 2 deletions include/jsonrpccxx/batchclient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace jsonrpccxx {

class BatchResponse {
public:
explicit BatchResponse(json &&response) : response(response) {
explicit BatchResponse(json &&response) : response(response), results(), errors(), nullIds() {
for (auto &[key, value] : response.items()) {
if (value.is_object() && valid_id_not_null(value) && has_key(value, "result")) {
results[value["id"]] = std::stoi(key);
Expand Down Expand Up @@ -98,4 +98,4 @@ namespace jsonrpccxx {
}
}
};
}
}
7 changes: 6 additions & 1 deletion include/jsonrpccxx/dispatcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace jsonrpccxx {

class Dispatcher {
public:
Dispatcher() :
methods(),
notifications(),
mapping() {}

bool Add(const std::string &name, MethodHandle callback, const NamedParamMapping &mapping = NAMED_PARAM_MAPPING) {
if (contains(name))
return false;
Expand Down Expand Up @@ -98,4 +103,4 @@ namespace jsonrpccxx {
throw JsonRpcException(-32600, "invalid request: params field must be an array, object");
}
};
} // namespace jsonrpccxx
} // namespace jsonrpccxx
3 changes: 2 additions & 1 deletion include/jsonrpccxx/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace jsonrpccxx {
class JsonRpcServer {
public:
JsonRpcServer() : dispatcher() {}
virtual ~JsonRpcServer() = default;
virtual std::string HandleRequest(const std::string &request) = 0;

Expand Down Expand Up @@ -106,4 +107,4 @@ namespace jsonrpccxx {
}
}
};
}
}
4 changes: 2 additions & 2 deletions test/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct F {
TestClientConnector c;
JsonRpcClient clientV1;
JsonRpcClient clientV2;
F() : clientV1(c, version::v1), clientV2(c, version::v2) {}
F() : c(), clientV1(c, version::v1), clientV2(c, version::v2) {}
};

TEST_CASE_METHOD(F, "v2_method_noparams", TEST_MODULE) {
Expand Down Expand Up @@ -256,4 +256,4 @@ TEST_CASE_METHOD(F, "v1_notification_call_params_byposition", TEST_MODULE) {
CHECK(c.request["params"][2] == true);
}

// TODO: test cases with return type mapping and param mapping for v1/v2 method and notification
// TODO: test cases with return type mapping and param mapping for v1/v2 method and notification
4 changes: 2 additions & 2 deletions test/integrationtest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
using namespace jsonrpccxx;

struct IntegrationTest {
IntegrationTest() : connector(rpcServer), client(connector, version::v2) {}
IntegrationTest() : rpcServer(), connector(rpcServer), client(connector, version::v2) {}
JsonRpc2Server rpcServer;
InMemoryConnector connector;
JsonRpcClient client;
};
};
11 changes: 7 additions & 4 deletions test/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct Server2 {
JsonRpc2Server server;
TestServerConnector connector;

Server2() : connector(server) {}
Server2() : server(), connector(server) {}
};

TEST_CASE_METHOD(Server2, "v2_method_not_found", TEST_MODULE) {
Expand Down Expand Up @@ -61,9 +61,10 @@ TEST_CASE_METHOD(Server2, "v2_malformed_requests", TEST_MODULE) {

enum class category { ord, cc };

NLOHMANN_JSON_SERIALIZE_ENUM(category, {{category::ord, "order"}, {category::cc, "cc"}});
NLOHMANN_JSON_SERIALIZE_ENUM(category, {{category::ord, "order"}, {category::cc, "cc"}})

struct product {
product() : id(), price(), name(), cat() {}
int id;
double price;
string name;
Expand All @@ -75,6 +76,8 @@ void from_json(const json &j, product &p);

class TestServer {
public:
TestServer() : param_proc(), param_a(), param_b(), catalog() {}

unsigned int add_function(unsigned int a, unsigned int b) {
this->param_a = a;
this->param_b = b;
Expand All @@ -95,8 +98,8 @@ class TestServer {
};

void dirty_notification() { throw std::exception(); }
int dirty_method(int a, int b) { throw std::exception(); }
int dirty_method2(int a, int b) { throw - 7; }
int dirty_method(int a, int b) { to_string(a+b); throw std::exception(); }
int dirty_method2(int a, int b) { throw (a+b); }

string param_proc;
int param_a;
Expand Down
4 changes: 3 additions & 1 deletion test/testclientconnector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ using namespace std;

class TestClientConnector : public IClientConnector {
public:
TestClientConnector() : request(), raw_response() {}

json request;
string raw_response;

Expand Down Expand Up @@ -64,4 +66,4 @@ class TestClientConnector : public IClientConnector {
CHECK(has_key(request, "params"));
}
}
};
};
4 changes: 2 additions & 2 deletions test/testserverconnector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using namespace Catch::Matchers;

class TestServerConnector {
public:
explicit TestServerConnector(JsonRpcServer &handler) : handler(handler) {}
explicit TestServerConnector(JsonRpcServer &handler) : handler(handler), raw_response() {}

void SendRawRequest(const string &request) { this->raw_response = handler.HandleRequest(request); }
void SendRequest(const json &request) { SendRawRequest(request.dump()); }
Expand Down Expand Up @@ -60,4 +60,4 @@ class TestServerConnector {
private:
JsonRpcServer &handler;
string raw_response;
};
};
27 changes: 20 additions & 7 deletions test/typemapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,34 @@ TEST_CASE("test incorrect params", TEST_MODULE) {
enum class category { order, cash_carry };

struct product {
product() : id(), price(), name(), cat() {}
int id;
double price;
string name;
category cat;
};

NLOHMANN_JSON_SERIALIZE_ENUM(category, {{category::order, "order"}, {category::cash_carry, "cc"}});
NLOHMANN_JSON_SERIALIZE_ENUM(category, {{category::order, "order"}, {category::cash_carry, "cc"}})

void to_json(json &j, const product &p) { j = json{{"id", p.id}, {"price", p.price}, {"name", p.name}, {"category", p.cat}}; }

product get_product(int id) {
if (id == 1)
return product{1, 22.50, "some product", category::order};
else if (id == 2)
return product{2, 55.50, "some product 2", category::cash_carry};
if (id == 1) {
product p;
p.id = 1;
p.price = 22.50;
p.name = "some product";
p.cat = category::order;
return p;
}
else if (id == 2) {
product p;
p.id = 2;
p.price = 55.50;
p.name = "some product 2";
p.cat = category::cash_carry;
return p;
}
throw JsonRpcException(-50000, "product not found");
}

Expand Down Expand Up @@ -131,7 +144,7 @@ static vector<product> catalog;
bool add_products(const vector<product> &products) {
std::copy(products.begin(), products.end(), std::back_inserter(catalog));
return true;
};
}

TEST_CASE("test with custom params", TEST_MODULE) {
MethodHandle mh = GetHandle(&add_products);
Expand Down Expand Up @@ -175,4 +188,4 @@ TEST_CASE("test number range checking", TEST_MODULE) {
unsigned short max_ss = numeric_limits<short>::max();
CHECK(mh2({max_su, max_ss}) == max_su + max_ss);
REQUIRE_THROWS_WITH(mh2({max_su, max_su}), Contains("invalid parameter: exceeds value range of integer"));
}
}
8 changes: 6 additions & 2 deletions test/warehouseapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ TEST_CASE_METHOD(IntegrationTest, "warehouse_test", TEST_MODULE) {
rpcServer.Add("GetProduct", GetHandle(&WarehouseServer::GetProduct, app));
rpcServer.Add("AddProduct", GetHandle(&WarehouseServer::AddProduct, app));

Product p = {"0xff", 22.4, "Product 1", category::cash_carry};
Product p;
p.id = "0xff";
p.price = 22.4;
p.name = "Product 1";
p.cat = category::cash_carry;
CHECK(client.CallMethod<bool>(1, "AddProduct", {p}));

Product p2 = client.CallMethod<Product>(1, "GetProduct", {"0xff"});
CHECK((p2.id == p.id && p2.name == p.name && p2.price == p.price && p2.cat == p.cat));
}
}