diff options
Diffstat (limited to 'src/crow_test.cpp')
-rw-r--r-- | src/crow_test.cpp | 1508 |
1 files changed, 790 insertions, 718 deletions
diff --git a/src/crow_test.cpp b/src/crow_test.cpp index cd668171db..96b90b0ed2 100644 --- a/src/crow_test.cpp +++ b/src/crow_test.cpp @@ -1,7 +1,9 @@ -#include "crow.h" #include <iostream> #include <sstream> #include <vector> + +#include "crow.h" + #include "gtest/gtest.h" #undef BMCWEB_LOG_LEVEL #define BMCWEB_LOG_LEVEL 0 @@ -10,864 +12,934 @@ using namespace std; using namespace crow; bool failed__ = false; -void error_print() { cerr << endl; } +void error_print() +{ + cerr << endl; +} template <typename A, typename... Args> -void error_print(const A& a, Args... args) { - cerr << a; - error_print(args...); +void error_print(const A& a, Args... args) +{ + cerr << a; + error_print(args...); } -template <typename... Args> -void fail(Args... args) { - error_print(args...); - failed__ = true; +template <typename... Args> void fail(Args... args) +{ + error_print(args...); + failed__ = true; } -#define ASSERT_EQUAL(a, b) \ - if ((a) != (b)) \ - fail(__FILE__ ":", __LINE__, ": Assert fail: expected ", (a), " actual ", \ - (b), ", " #a " == " #b ", at " __FILE__ ":", __LINE__) -#define ASSERT_NOTEQUAL(a, b) \ - if ((a) == (b)) \ - fail(__FILE__ ":", __LINE__, ": Assert fail: not expected ", (a), \ - ", " #a " != " #b ", at " __FILE__ ":", __LINE__) - -#define DISABLE_TEST(x) \ - struct test##x { \ - void test(); \ - } x##_; \ - void test##x::test() +#define ASSERT_EQUAL(a, b) \ + if ((a) != (b)) \ + fail(__FILE__ ":", __LINE__, ": Assert fail: expected ", (a), " actual ", \ + (b), ", " #a " == " #b ", at " __FILE__ ":", __LINE__) +#define ASSERT_NOTEQUAL(a, b) \ + if ((a) == (b)) \ + fail(__FILE__ ":", __LINE__, ": Assert fail: not expected ", (a), \ + ", " #a " != " #b ", at " __FILE__ ":", __LINE__) + +#define DISABLE_TEST(x) \ + struct test##x \ + { \ + void test(); \ + } x##_; \ + void test##x::test() #define LOCALHOST_ADDRESS "127.0.0.1" -TEST(Crow, Rule) { - TaggedRule<> r("/http/"); - r.name("abc"); +TEST(Crow, Rule) +{ + TaggedRule<> r("/http/"); + r.name("abc"); - // empty handler - fail to validate - try { - r.validate(); - fail("empty handler should fail to validate"); - } catch (runtime_error& e) { - } + // empty handler - fail to validate + try + { + r.validate(); + fail("empty handler should fail to validate"); + } + catch (runtime_error& e) + { + } - int x = 0; + int x = 0; - // registering handler - r([&x] { - x = 1; - return ""; - }); + // registering handler + r([&x] { + x = 1; + return ""; + }); - r.validate(); + r.validate(); - Response res; + Response res; - // executing handler - ASSERT_EQUAL(0, x); - boost::beast::http::request<boost::beast::http::string_body> req{}; - r.handle(Request(req), res, RoutingParams()); - ASSERT_EQUAL(1, x); + // executing handler + ASSERT_EQUAL(0, x); + boost::beast::http::request<boost::beast::http::string_body> req{}; + r.handle(Request(req), res, RoutingParams()); + ASSERT_EQUAL(1, x); - // registering handler with Request argument - r([&x](const crow::Request&) { - x = 2; - return ""; - }); + // registering handler with Request argument + r([&x](const crow::Request&) { + x = 2; + return ""; + }); - r.validate(); + r.validate(); - // executing handler - ASSERT_EQUAL(1, x); - r.handle(Request(req), res, RoutingParams()); - ASSERT_EQUAL(2, x); + // executing handler + ASSERT_EQUAL(1, x); + r.handle(Request(req), res, RoutingParams()); + ASSERT_EQUAL(2, x); } -TEST(Crow, ParameterTagging) { - static_assert(black_magic::isValid("<int><int><int>"), "valid url"); - static_assert(!black_magic::isValid("<int><int<<int>"), "invalid url"); - static_assert(!black_magic::isValid("nt>"), "invalid url"); - ASSERT_EQUAL(1, black_magic::get_parameter_tag("<int>")); - ASSERT_EQUAL(2, black_magic::get_parameter_tag("<uint>")); - ASSERT_EQUAL(3, black_magic::get_parameter_tag("<float>")); - ASSERT_EQUAL(3, black_magic::get_parameter_tag("<double>")); - ASSERT_EQUAL(4, black_magic::get_parameter_tag("<str>")); - ASSERT_EQUAL(4, black_magic::get_parameter_tag("<string>")); - ASSERT_EQUAL(5, black_magic::get_parameter_tag("<path>")); - ASSERT_EQUAL(6 * 6 + 6 + 1, - black_magic::get_parameter_tag("<int><int><int>")); - ASSERT_EQUAL(6 * 6 + 6 + 2, - black_magic::get_parameter_tag("<uint><int><int>")); - ASSERT_EQUAL(6 * 6 + 6 * 3 + 2, - black_magic::get_parameter_tag("<uint><double><int>")); - - // url definition parsed in compile time, build into *one number*, and given - // to template argument - static_assert( - std::is_same<black_magic::S<uint64_t, double, int64_t>, - black_magic::Arguments<6 * 6 + 6 * 3 + 2>::type>::value, - "tag to type container"); +TEST(Crow, ParameterTagging) +{ + static_assert(black_magic::isValid("<int><int><int>"), "valid url"); + static_assert(!black_magic::isValid("<int><int<<int>"), "invalid url"); + static_assert(!black_magic::isValid("nt>"), "invalid url"); + ASSERT_EQUAL(1, black_magic::get_parameter_tag("<int>")); + ASSERT_EQUAL(2, black_magic::get_parameter_tag("<uint>")); + ASSERT_EQUAL(3, black_magic::get_parameter_tag("<float>")); + ASSERT_EQUAL(3, black_magic::get_parameter_tag("<double>")); + ASSERT_EQUAL(4, black_magic::get_parameter_tag("<str>")); + ASSERT_EQUAL(4, black_magic::get_parameter_tag("<string>")); + ASSERT_EQUAL(5, black_magic::get_parameter_tag("<path>")); + ASSERT_EQUAL(6 * 6 + 6 + 1, + black_magic::get_parameter_tag("<int><int><int>")); + ASSERT_EQUAL(6 * 6 + 6 + 2, + black_magic::get_parameter_tag("<uint><int><int>")); + ASSERT_EQUAL(6 * 6 + 6 * 3 + 2, + black_magic::get_parameter_tag("<uint><double><int>")); + + // url definition parsed in compile time, build into *one number*, and given + // to template argument + static_assert( + std::is_same<black_magic::S<uint64_t, double, int64_t>, + black_magic::Arguments<6 * 6 + 6 * 3 + 2>::type>::value, + "tag to type container"); } -TEST(Crow, PathRouting) { - SimpleApp app; +TEST(Crow, PathRouting) +{ + SimpleApp app; - BMCWEB_ROUTE(app, "/file") - ([] { return "file"; }); + BMCWEB_ROUTE(app, "/file") + ([] { return "file"; }); - BMCWEB_ROUTE(app, "/path/") - ([] { return "path"; }); + BMCWEB_ROUTE(app, "/path/") + ([] { return "path"; }); - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - req.url = "/file"; + req.url = "/file"; - app.handle(req, res); + app.handle(req, res); - ASSERT_EQUAL(200, res.resultInt()); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + ASSERT_EQUAL(200, res.resultInt()); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - req.url = "/file/"; + req.url = "/file/"; - app.handle(req, res); - ASSERT_EQUAL(404, res.resultInt()); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + app.handle(req, res); + ASSERT_EQUAL(404, res.resultInt()); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - req.url = "/path"; + req.url = "/path"; - app.handle(req, res); - ASSERT_NOTEQUAL(404, res.resultInt()); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + app.handle(req, res); + ASSERT_NOTEQUAL(404, res.resultInt()); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - req.url = "/path/"; + req.url = "/path/"; - app.handle(req, res); - ASSERT_EQUAL(200, res.resultInt()); - } + app.handle(req, res); + ASSERT_EQUAL(200, res.resultInt()); + } } -TEST(Crow, RoutingTest) { - SimpleApp app; - int A{}; - uint32_t b{}; - double C{}; - string D{}; - string E{}; - - BMCWEB_ROUTE(app, "/0/<uint>") - ([&](uint32_t b) { - b = b; - return "OK"; - }); - - BMCWEB_ROUTE(app, "/1/<int>/<uint>") - ([&](int a, uint32_t b) { - A = a; - b = b; - return "OK"; - }); - - BMCWEB_ROUTE(app, "/4/<int>/<uint>/<double>/<string>") - ([&](int a, uint32_t b, double c, string d) { - A = a; - b = b; - C = c; - D = d; - return "OK"; - }); - - BMCWEB_ROUTE(app, "/5/<int>/<uint>/<double>/<string>/<path>") - ([&](int a, uint32_t b, double c, string d, string e) { - A = a; - b = b; - C = c; - D = d; - E = e; - return "OK"; - }); - - app.validate(); - // app.debugPrint(); - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; +TEST(Crow, RoutingTest) +{ + SimpleApp app; + int A{}; + uint32_t b{}; + double C{}; + string D{}; + string E{}; + + BMCWEB_ROUTE(app, "/0/<uint>") + ([&](uint32_t b) { + b = b; + return "OK"; + }); + + BMCWEB_ROUTE(app, "/1/<int>/<uint>") + ([&](int a, uint32_t b) { + A = a; + b = b; + return "OK"; + }); + + BMCWEB_ROUTE(app, "/4/<int>/<uint>/<double>/<string>") + ([&](int a, uint32_t b, double c, string d) { + A = a; + b = b; + C = c; + D = d; + return "OK"; + }); + + BMCWEB_ROUTE(app, "/5/<int>/<uint>/<double>/<string>/<path>") + ([&](int a, uint32_t b, double c, string d, string e) { + A = a; + b = b; + C = c; + D = d; + E = e; + return "OK"; + }); - req.url = "/-1"; + app.validate(); + // app.debugPrint(); + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - app.handle(req, res); + req.url = "/-1"; - ASSERT_EQUAL(404, res.resultInt()); - } + app.handle(req, res); - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + ASSERT_EQUAL(404, res.resultInt()); + } - req.url = "/0/1001999"; + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - app.handle(req, res); + req.url = "/0/1001999"; - ASSERT_EQUAL(200, res.resultInt()); + app.handle(req, res); - ASSERT_EQUAL(1001999, b); - } + ASSERT_EQUAL(200, res.resultInt()); - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + ASSERT_EQUAL(1001999, b); + } - req.url = "/1/-100/1999"; + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - app.handle(req, res); + req.url = "/1/-100/1999"; - ASSERT_EQUAL(200, res.resultInt()); + app.handle(req, res); - ASSERT_EQUAL(-100, A); - ASSERT_EQUAL(1999, b); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + ASSERT_EQUAL(200, res.resultInt()); - req.url = "/4/5000/3/-2.71828/hellhere"; + ASSERT_EQUAL(-100, A); + ASSERT_EQUAL(1999, b); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - app.handle(req, res); + req.url = "/4/5000/3/-2.71828/hellhere"; - ASSERT_EQUAL(200, res.resultInt()); + app.handle(req, res); - ASSERT_EQUAL(5000, A); - ASSERT_EQUAL(3, b); - ASSERT_EQUAL(-2.71828, C); - ASSERT_EQUAL("hellhere", D); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + ASSERT_EQUAL(200, res.resultInt()); - req.url = "/5/-5/999/3.141592/hello_there/a/b/c/d"; + ASSERT_EQUAL(5000, A); + ASSERT_EQUAL(3, b); + ASSERT_EQUAL(-2.71828, C); + ASSERT_EQUAL("hellhere", D); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - app.handle(req, res); + req.url = "/5/-5/999/3.141592/hello_there/a/b/c/d"; - ASSERT_EQUAL(200, res.resultInt()); + app.handle(req, res); - ASSERT_EQUAL(-5, A); - ASSERT_EQUAL(999, b); - ASSERT_EQUAL(3.141592, C); - ASSERT_EQUAL("hello_there", D); - ASSERT_EQUAL("a/b/c/d", E); - } + ASSERT_EQUAL(200, res.resultInt()); + + ASSERT_EQUAL(-5, A); + ASSERT_EQUAL(999, b); + ASSERT_EQUAL(3.141592, C); + ASSERT_EQUAL("hello_there", D); + ASSERT_EQUAL("a/b/c/d", E); + } } -TEST(Crow, simple_response_RoutingParams) { - ASSERT_EQUAL(100, - Response(boost::beast::http::status::continue_).resultInt()); - ASSERT_EQUAL(200, Response("Hello there").resultInt()); - ASSERT_EQUAL(500, Response(boost::beast::http::status::internal_server_error, - "Internal Error?") - .resultInt()); - - RoutingParams rp; - rp.intParams.push_back(1); - rp.intParams.push_back(5); - rp.uintParams.push_back(2); - rp.doubleParams.push_back(3); - rp.stringParams.push_back("hello"); - ASSERT_EQUAL(1, rp.get<int64_t>(0)); - ASSERT_EQUAL(5, rp.get<int64_t>(1)); - ASSERT_EQUAL(2, rp.get<uint64_t>(0)); - ASSERT_EQUAL(3, rp.get<double>(0)); - ASSERT_EQUAL("hello", rp.get<string>(0)); +TEST(Crow, simple_response_RoutingParams) +{ + ASSERT_EQUAL(100, + Response(boost::beast::http::status::continue_).resultInt()); + ASSERT_EQUAL(200, Response("Hello there").resultInt()); + ASSERT_EQUAL(500, + Response(boost::beast::http::status::internal_server_error, + "Internal Error?") + .resultInt()); + + RoutingParams rp; + rp.intParams.push_back(1); + rp.intParams.push_back(5); + rp.uintParams.push_back(2); + rp.doubleParams.push_back(3); + rp.stringParams.push_back("hello"); + ASSERT_EQUAL(1, rp.get<int64_t>(0)); + ASSERT_EQUAL(5, rp.get<int64_t>(1)); + ASSERT_EQUAL(2, rp.get<uint64_t>(0)); + ASSERT_EQUAL(3, rp.get<double>(0)); + ASSERT_EQUAL("hello", rp.get<string>(0)); } -TEST(Crow, handler_with_response) { - SimpleApp app; - BMCWEB_ROUTE(app, "/")([](const crow::Request&, crow::Response&) {}); +TEST(Crow, handler_with_response) +{ + SimpleApp app; + BMCWEB_ROUTE(app, "/")([](const crow::Request&, crow::Response&) {}); } -TEST(Crow, http_method) { - SimpleApp app; - - BMCWEB_ROUTE(app, "/").methods("POST"_method, - "GET"_method)([](const Request& req) { - if (req.method() == "GET"_method) - return "2"; - else - return "1"; - }); - - BMCWEB_ROUTE(app, "/get_only") - .methods("GET"_method)([](const Request& /*req*/) { return "get"; }); - BMCWEB_ROUTE(app, "/post_only") - .methods("POST"_method)([](const Request& /*req*/) { return "post"; }); - - // cannot have multiple handlers for the same url - // BMCWEB_ROUTE(app, "/") - //.methods("GET"_method) - //([]{ return "2"; }); - - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; +TEST(Crow, http_method) +{ + SimpleApp app; - req.url = "/"; - app.handle(req, res); + BMCWEB_ROUTE(app, "/").methods("POST"_method, + "GET"_method)([](const Request& req) { + if (req.method() == "GET"_method) + return "2"; + else + return "1"; + }); - ASSERT_EQUAL("2", res.body()); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + BMCWEB_ROUTE(app, "/get_only") + .methods("GET"_method)([](const Request& /*req*/) { return "get"; }); + BMCWEB_ROUTE(app, "/post_only") + .methods("POST"_method)([](const Request& /*req*/) { return "post"; }); - req.url = "/"; - r.method("POST"_method); - app.handle(req, res); + // cannot have multiple handlers for the same url + // BMCWEB_ROUTE(app, "/") + //.methods("GET"_method) + //([]{ return "2"; }); - ASSERT_EQUAL("1", res.body()); - } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + req.url = "/"; + app.handle(req, res); + + ASSERT_EQUAL("2", res.body()); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - req.url = "/get_only"; - app.handle(req, res); + req.url = "/"; + r.method("POST"_method); + app.handle(req, res); - ASSERT_EQUAL("get", res.body()); - } + ASSERT_EQUAL("1", res.body()); + } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; - req.url = "/get_only"; - r.method("POST"_method); - app.handle(req, res); + req.url = "/get_only"; + app.handle(req, res); - ASSERT_NOTEQUAL("get", res.body()); - } -} + ASSERT_EQUAL("get", res.body()); + } -TEST(Crow, server_handling_error_request) { - static char buf[2048]; - SimpleApp app; - BMCWEB_ROUTE(app, "/")([] { return "A"; }); - Server<SimpleApp> server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - std::string sendmsg = "POX"; - asio::io_service is; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - - c.send(asio::buffer(sendmsg)); - - try { - c.receive(asio::buffer(buf, 2048)); - fail(); - } catch (std::exception& e) { - // std::cerr << e.what() << std::endl; - } - } - server.stop(); + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; + + req.url = "/get_only"; + r.method("POST"_method); + app.handle(req, res); + + ASSERT_NOTEQUAL("get", res.body()); + } } -TEST(Crow, multi_server) { - static char buf[2048]; - SimpleApp app1, app2; - BMCWEB_ROUTE(app1, "/").methods("GET"_method, - "POST"_method)([] { return "A"; }); - BMCWEB_ROUTE(app2, "/").methods("GET"_method, - "POST"_method)([] { return "B"; }); +TEST(Crow, server_handling_error_request) +{ + static char buf[2048]; + SimpleApp app; + BMCWEB_ROUTE(app, "/")([] { return "A"; }); + Server<SimpleApp> server(&app, LOCALHOST_ADDRESS, 45451); + auto _ = async(launch::async, [&] { server.run(); }); + std::string sendmsg = "POX"; + asio::io_service is; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - Server<SimpleApp> server1(&app1, LOCALHOST_ADDRESS, 45451); - Server<SimpleApp> server2(&app2, LOCALHOST_ADDRESS, 45452); + c.send(asio::buffer(sendmsg)); - auto _ = async(launch::async, [&] { server1.run(); }); - auto _2 = async(launch::async, [&] { server2.run(); }); + try + { + c.receive(asio::buffer(buf, 2048)); + fail(); + } + catch (std::exception& e) + { + // std::cerr << e.what() << std::endl; + } + } + server.stop(); +} - std::string sendmsg = - "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=b\r\n"; - asio::io_service is; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); +TEST(Crow, multi_server) +{ + static char buf[2048]; + SimpleApp app1, app2; + BMCWEB_ROUTE(app1, "/").methods("GET"_method, + "POST"_method)([] { return "A"; }); + BMCWEB_ROUTE(app2, "/").methods("GET"_method, + "POST"_method)([] { return "B"; }); - c.send(asio::buffer(sendmsg)); + Server<SimpleApp> server1(&app1, LOCALHOST_ADDRESS, 45451); + Server<SimpleApp> server2(&app2, LOCALHOST_ADDRESS, 45452); - size_t recved = c.receive(asio::buffer(buf, 2048)); - ASSERT_EQUAL('A', buf[recved - 1]); - } + auto _ = async(launch::async, [&] { server1.run(); }); + auto _2 = async(launch::async, [&] { server2.run(); }); - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452)); + std::string sendmsg = + "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=b\r\n"; + asio::io_service is; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + + c.send(asio::buffer(sendmsg)); - for (auto ch : sendmsg) { - char buf[1] = {ch}; - c.send(asio::buffer(buf)); + size_t recved = c.receive(asio::buffer(buf, 2048)); + ASSERT_EQUAL('A', buf[recved - 1]); } - size_t recved = c.receive(asio::buffer(buf, 2048)); - ASSERT_EQUAL('b', buf[recved - 1]); - } + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452)); + + for (auto ch : sendmsg) + { + char buf[1] = {ch}; + c.send(asio::buffer(buf)); + } + + size_t recved = c.receive(asio::buffer(buf, 2048)); + ASSERT_EQUAL('b', buf[recved - 1]); + } - server1.stop(); - server2.stop(); + server1.stop(); + server2.stop(); } -TEST(Crow, black_magic) { - using namespace black_magic; - static_assert( - std::is_same<void, LastElementType<int, char, void>::type>::value, - "LastElementType"); - static_assert( - std::is_same< - char, PopBack<int, char, void>::rebind<LastElementType>::type>::value, - "pop_back"); - static_assert( - std::is_same<int, PopBack<int, char, void>::rebind<PopBack>::rebind< - LastElementType>::type>::value, - "pop_back"); +TEST(Crow, black_magic) +{ + using namespace black_magic; + static_assert( + std::is_same<void, LastElementType<int, char, void>::type>::value, + "LastElementType"); + static_assert( + std::is_same<char, PopBack<int, char, + void>::rebind<LastElementType>::type>::value, + "pop_back"); + static_assert( + std::is_same<int, PopBack<int, char, void>::rebind<PopBack>::rebind< + LastElementType>::type>::value, + "pop_back"); } -struct NullMiddleware { - struct Context {}; +struct NullMiddleware +{ + struct Context + { + }; - template <typename AllContext> - void beforeHandle(Request&, Response&, Context&, AllContext&) {} + template <typename AllContext> + void beforeHandle(Request&, Response&, Context&, AllContext&) + { + } - template <typename AllContext> - void afterHandle(Request&, Response&, Context&, AllContext&) {} + template <typename AllContext> + void afterHandle(Request&, Response&, Context&, AllContext&) + { + } }; -struct NullSimpleMiddleware { - struct Context {}; +struct NullSimpleMiddleware +{ + struct Context + { + }; - void beforeHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) {} + void beforeHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) + { + } - void afterHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) {} + void afterHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) + { + } }; -TEST(Crow, middleware_simple) { - App<NullMiddleware, NullSimpleMiddleware> app; - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - BMCWEB_ROUTE(app, "/") - ([&](const crow::Request& req) { - app.getContext<NullMiddleware>(req); - app.getContext<NullSimpleMiddleware>(req); - return ""; - }); +TEST(Crow, middleware_simple) +{ + App<NullMiddleware, NullSimpleMiddleware> app; + decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); + BMCWEB_ROUTE(app, "/") + ([&](const crow::Request& req) { + app.getContext<NullMiddleware>(req); + app.getContext<NullSimpleMiddleware>(req); + return ""; + }); } -struct IntSettingMiddleware { - struct Context { - int val; - }; +struct IntSettingMiddleware +{ + struct Context + { + int val; + }; - template <typename AllContext> - void beforeHandle(Request&, Response&, Context& ctx, AllContext&) { - ctx.val = 1; - } + template <typename AllContext> + void beforeHandle(Request&, Response&, Context& ctx, AllContext&) + { + ctx.val = 1; + } - template <typename AllContext> - void afterHandle(Request&, Response&, Context& ctx, AllContext&) { - ctx.val = 2; - } + template <typename AllContext> + void afterHandle(Request&, Response&, Context& ctx, AllContext&) + { + ctx.val = 2; + } }; std::vector<std::string> test_middleware_context_vector; -struct FirstMW { - struct Context { - std::vector<string> v; - }; +struct FirstMW +{ + struct Context + { + std::vector<string> v; + }; - void beforeHandle(Request& /*req*/, Response& /*res*/, Context& ctx) { - ctx.v.push_back("1 before"); - } + void beforeHandle(Request& /*req*/, Response& /*res*/, Context& ctx) + { + ctx.v.push_back("1 before"); + } - void afterHandle(Request& /*req*/, Response& /*res*/, Context& ctx) { - ctx.v.push_back("1 after"); - test_middleware_context_vector = ctx.v; - } + void afterHandle(Request& /*req*/, Response& /*res*/, Context& ctx) + { + ctx.v.push_back("1 after"); + test_middleware_context_vector = ctx.v; + } }; -struct SecondMW { - struct Context {}; - template <typename AllContext> - void beforeHandle(Request& req, Response& res, Context&, - AllContext& all_ctx) { - all_ctx.template get<FirstMW>().v.push_back("2 before"); - if (req.url == "/break") res.end(); - } - - template <typename AllContext> - void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) { - all_ctx.template get<FirstMW>().v.push_back("2 after"); - } +struct SecondMW +{ + struct Context + { + }; + template <typename AllContext> + void beforeHandle(Request& req, Response& res, Context&, + AllContext& all_ctx) + { + all_ctx.template get<FirstMW>().v.push_back("2 before"); + if (req.url == "/break") + res.end(); + } + + template <typename AllContext> + void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) + { + all_ctx.template get<FirstMW>().v.push_back("2 after"); + } }; -struct ThirdMW { - struct Context {}; - template <typename AllContext> - void beforeHandle(Request&, Response&, Context&, AllContext& all_ctx) { - all_ctx.template get<FirstMW>().v.push_back("3 before"); - } - - template <typename AllContext> - void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) { - all_ctx.template get<FirstMW>().v.push_back("3 after"); - } +struct ThirdMW +{ + struct Context + { + }; + template <typename AllContext> + void beforeHandle(Request&, Response&, Context&, AllContext& all_ctx) + { + all_ctx.template get<FirstMW>().v.push_back("3 before"); + } + + template <typename AllContext> + void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) + { + all_ctx.template get<FirstMW>().v.push_back("3 after"); + } }; -TEST(Crow, middlewareContext) { - static char buf[2048]; - // SecondMW depends on FirstMW (it uses all_ctx.get<FirstMW>) - // so it leads to compile error if we remove FirstMW from definition - // App<IntSettingMiddleware, SecondMW> app; - // or change the order of FirstMW and SecondMW - // App<IntSettingMiddleware, SecondMW, FirstMW> app; +TEST(Crow, middlewareContext) +{ + static char buf[2048]; + // SecondMW depends on FirstMW (it uses all_ctx.get<FirstMW>) + // so it leads to compile error if we remove FirstMW from definition + // App<IntSettingMiddleware, SecondMW> app; + // or change the order of FirstMW and SecondMW + // App<IntSettingMiddleware, SecondMW, FirstMW> app; + + App<IntSettingMiddleware, FirstMW, SecondMW, ThirdMW> app; + + int x{}; + BMCWEB_ROUTE(app, "/") + ([&](const Request& req) { + { + auto& ctx = app.getContext<IntSettingMiddleware>(req); + x = ctx.val; + } + { + auto& ctx = app.getContext<FirstMW>(req); + ctx.v.push_back("handle"); + } + + return ""; + }); + BMCWEB_ROUTE(app, "/break") + ([&](const Request& req) { + { + auto& ctx = app.getContext<FirstMW>(req); + ctx.v.push_back("handle"); + } - App<IntSettingMiddleware, FirstMW, SecondMW, ThirdMW> app; + return ""; + }); - int x{}; - BMCWEB_ROUTE(app, "/") - ([&](const Request& req) { + decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); + auto _ = async(launch::async, [&] { server.run(); }); + std::string sendmsg = "GET /\r\n\r\n"; + asio::io_service is; { - auto& ctx = app.getContext<IntSettingMiddleware>(req); - x = ctx.val; + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + + c.send(asio::buffer(sendmsg)); + + c.receive(asio::buffer(buf, 2048)); + c.close(); } { - auto& ctx = app.getContext<FirstMW>(req); - ctx.v.push_back("handle"); + auto& out = test_middleware_context_vector; + ASSERT_EQUAL(1, x); + ASSERT_EQUAL(7, out.size()); + ASSERT_EQUAL("1 before", out[0]); + ASSERT_EQUAL("2 before", out[1]); + ASSERT_EQUAL("3 before", out[2]); + ASSERT_EQUAL("handle", out[3]); + ASSERT_EQUAL("3 after", out[4]); + ASSERT_EQUAL("2 after", out[5]); + ASSERT_EQUAL("1 after", out[6]); } + std::string sendmsg2 = "GET /break\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + + c.send(asio::buffer(sendmsg2)); - return ""; - }); - BMCWEB_ROUTE(app, "/break") - ([&](const Request& req) { + c.receive(asio::buffer(buf, 2048)); + c.close(); + } { - auto& ctx = app.getContext<FirstMW>(req); - ctx.v.push_back("handle"); + auto& out = test_middleware_context_vector; + ASSERT_EQUAL(4, out.size()); + ASSERT_EQUAL("1 before", out[0]); + ASSERT_EQUAL("2 before", out[1]); + ASSERT_EQUAL("2 after", out[2]); + ASSERT_EQUAL("1 after", out[3]); } + server.stop(); +} - return ""; - }); +TEST(Crow, bug_quick_repeated_request) +{ + static char buf[2048]; - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - std::string sendmsg = "GET /\r\n\r\n"; - asio::io_service is; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + SimpleApp app; - c.send(asio::buffer(sendmsg)); + BMCWEB_ROUTE(app, "/")([&] { return "hello"; }); - c.receive(asio::buffer(buf, 2048)); - c.close(); - } - { - auto& out = test_middleware_context_vector; - ASSERT_EQUAL(1, x); - ASSERT_EQUAL(7, out.size()); - ASSERT_EQUAL("1 before", out[0]); - ASSERT_EQUAL("2 before", out[1]); - ASSERT_EQUAL("3 before", out[2]); - ASSERT_EQUAL("handle", out[3]); - ASSERT_EQUAL("3 after", out[4]); - ASSERT_EQUAL("2 after", out[5]); - ASSERT_EQUAL("1 after", out[6]); - } - std::string sendmsg2 = "GET /break\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - - c.send(asio::buffer(sendmsg2)); - - c.receive(asio::buffer(buf, 2048)); - c.close(); - } - { - auto& out = test_middleware_context_vector; - ASSERT_EQUAL(4, out.size()); - ASSERT_EQUAL("1 before", out[0]); - ASSERT_EQUAL("2 before", out[1]); - ASSERT_EQUAL("2 after", out[2]); - ASSERT_EQUAL("1 after", out[3]); - } - server.stop(); + decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); + auto _ = async(launch::async, [&] { server.run(); }); + std::string sendmsg = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"; + asio::io_service is; + { + std::vector<std::future<void>> v; + for (int i = 0; i < 5; i++) + { + v.push_back(async(launch::async, [&] { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + + for (int j = 0; j < 5; j++) + { + c.send(asio::buffer(sendmsg)); + + size_t received = c.receive(asio::buffer(buf, 2048)); + ASSERT_EQUAL("hello", std::string(buf + received - 5, + buf + received)); + } + c.close(); + })); + } + } + server.stop(); } -TEST(Crow, bug_quick_repeated_request) { - static char buf[2048]; +TEST(Crow, simple_url_params) +{ + static char buf[2048]; + + SimpleApp app; + + QueryString lastUrlParams; + + BMCWEB_ROUTE(app, "/params") + ([&lastUrlParams](const crow::Request& req) { + lastUrlParams = std::move(req.urlParams); + return "OK"; + }); - SimpleApp app; + /// params?h=1&foo=bar&lol&count[]=1&count[]=4&pew=5.2 - BMCWEB_ROUTE(app, "/")([&] { return "hello"; }); + decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); + auto _ = async(launch::async, [&] { server.run(); }); + asio::io_service is; + std::string sendmsg; - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - std::string sendmsg = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"; - asio::io_service is; - { - std::vector<std::future<void>> v; - for (int i = 0; i < 5; i++) { - v.push_back(async(launch::async, [&] { + // check empty params + sendmsg = "GET /params\r\n\r\n"; + { asio::ip::tcp::socket c(is); c.connect(asio::ip::tcp::endpoint( asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); - for (int j = 0; j < 5; j++) { - c.send(asio::buffer(sendmsg)); + stringstream ss; + ss << lastUrlParams; - size_t received = c.receive(asio::buffer(buf, 2048)); - ASSERT_EQUAL("hello", - std::string(buf + received - 5, buf + received)); - } + ASSERT_EQUAL("[ ]", ss.str()); + } + // check single presence + sendmsg = "GET /params?foobar\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); + + ASSERT_TRUE(lastUrlParams.get("missing") == nullptr); + ASSERT_TRUE(lastUrlParams.get("foobar") != nullptr); + ASSERT_TRUE(lastUrlParams.getList("missing").empty()); + } + // check multiple presence + sendmsg = "GET /params?foo&bar&baz\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); c.close(); - })); + + ASSERT_TRUE(lastUrlParams.get("missing") == nullptr); + ASSERT_TRUE(lastUrlParams.get("foo") != nullptr); + ASSERT_TRUE(lastUrlParams.get("bar") != nullptr); + ASSERT_TRUE(lastUrlParams.get("baz") != nullptr); } - } - server.stop(); -} + // check single value + sendmsg = "GET /params?hello=world\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); -TEST(Crow, simple_url_params) { - static char buf[2048]; - - SimpleApp app; - - QueryString lastUrlParams; - - BMCWEB_ROUTE(app, "/params") - ([&lastUrlParams](const crow::Request& req) { - lastUrlParams = std::move(req.urlParams); - return "OK"; - }); - - /// params?h=1&foo=bar&lol&count[]=1&count[]=4&pew=5.2 - - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - asio::io_service is; - std::string sendmsg; - - // check empty params - sendmsg = "GET /params\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - stringstream ss; - ss << lastUrlParams; - - ASSERT_EQUAL("[ ]", ss.str()); - } - // check single presence - sendmsg = "GET /params?foobar\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_TRUE(lastUrlParams.get("missing") == nullptr); - ASSERT_TRUE(lastUrlParams.get("foobar") != nullptr); - ASSERT_TRUE(lastUrlParams.getList("missing").empty()); - } - // check multiple presence - sendmsg = "GET /params?foo&bar&baz\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_TRUE(lastUrlParams.get("missing") == nullptr); - ASSERT_TRUE(lastUrlParams.get("foo") != nullptr); - ASSERT_TRUE(lastUrlParams.get("bar") != nullptr); - ASSERT_TRUE(lastUrlParams.get("baz") != nullptr); - } - // check single value - sendmsg = "GET /params?hello=world\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world"); - } - // check multiple value - sendmsg = "GET /params?hello=world&left=right&up=down\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world"); - ASSERT_EQUAL(string(lastUrlParams.get("left")), "right"); - ASSERT_EQUAL(string(lastUrlParams.get("up")), "down"); - } - // check multiple value, multiple types - sendmsg = "GET /params?int=100&double=123.45&boolean=1\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(boost::lexical_cast<int>(lastUrlParams.get("int")), 100); - ASSERT_EQUAL(boost::lexical_cast<double>(lastUrlParams.get("double")), - 123.45); - ASSERT_EQUAL(boost::lexical_cast<bool>(lastUrlParams.get("boolean")), true); - } - // check single array value - sendmsg = "GET /params?tmnt[]=leonardo\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_TRUE(lastUrlParams.get("tmnt") == nullptr); - ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 1); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo"); - } - // check multiple array value - sendmsg = - "GET /params?tmnt[]=leonardo&tmnt[]=donatello&tmnt[]=raphael\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 3); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo"); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[1]), "donatello"); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[2]), "raphael"); - } - server.stop(); + ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world"); + } + // check multiple value + sendmsg = "GET /params?hello=world&left=right&up=down\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); + + ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world"); + ASSERT_EQUAL(string(lastUrlParams.get("left")), "right"); + ASSERT_EQUAL(string(lastUrlParams.get("up")), "down"); + } + // check multiple value, multiple types + sendmsg = "GET /params?int=100&double=123.45&boolean=1\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); + + ASSERT_EQUAL(boost::lexical_cast<int>(lastUrlParams.get("int")), 100); + ASSERT_EQUAL(boost::lexical_cast<double>(lastUrlParams.get("double")), + 123.45); + ASSERT_EQUAL(boost::lexical_cast<bool>(lastUrlParams.get("boolean")), + true); + } + // check single array value + sendmsg = "GET /params?tmnt[]=leonardo\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); + + ASSERT_TRUE(lastUrlParams.get("tmnt") == nullptr); + ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 1); + ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo"); + } + // check multiple array value + sendmsg = + "GET /params?tmnt[]=leonardo&tmnt[]=donatello&tmnt[]=raphael\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); + + ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 3); + ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo"); + ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[1]), "donatello"); + ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[2]), "raphael"); + } + server.stop(); } -TEST(Crow, routeDynamic) { - SimpleApp app; - int x = 1; - app.routeDynamic("/")([&] { - x = 2; - return ""; - }); - - app.routeDynamic("/set4")([&](const Request&) { - x = 4; - return ""; - }); - app.routeDynamic("/set5")([&](const Request&, Response& res) { - x = 5; - res.end(); - }); - - app.routeDynamic("/set_int/<int>")([&](int y) { - x = y; - return ""; - }); - - try { - app.routeDynamic("/invalid_test/<double>/<path>")([]() { return ""; }); - fail(); - } catch (std::exception&) { - } - - // app is in an invalid state when routeDynamic throws an exception. - try { - app.validate(); - fail(); - } catch (std::exception&) { - } +TEST(Crow, routeDynamic) +{ + SimpleApp app; + int x = 1; + app.routeDynamic("/")([&] { + x = 2; + return ""; + }); + + app.routeDynamic("/set4")([&](const Request&) { + x = 4; + return ""; + }); + app.routeDynamic("/set5")([&](const Request&, Response& res) { + x = 5; + res.end(); + }); + + app.routeDynamic("/set_int/<int>")([&](int y) { + x = y; + return ""; + }); + + try + { + app.routeDynamic("/invalid_test/<double>/<path>")([]() { return ""; }); + fail(); + } + catch (std::exception&) + { + } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; - req.url = "/"; - app.handle(req, res); - ASSERT_EQUAL(x, 2); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; - req.url = "/set_int/42"; - app.handle(req, res); - ASSERT_EQUAL(x, 42); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; - req.url = "/set5"; - app.handle(req, res); - ASSERT_EQUAL(x, 5); - } - { - boost::beast::http::request<boost::beast::http::string_body> r{}; - Request req{r}; - Response res; - req.url = "/set4"; - app.handle(req, res); - ASSERT_EQUAL(x, 4); - } + // app is in an invalid state when routeDynamic throws an exception. + try + { + app.validate(); + fail(); + } + catch (std::exception&) + { + } + + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; + req.url = "/"; + app.handle(req, res); + ASSERT_EQUAL(x, 2); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; + req.url = "/set_int/42"; + app.handle(req, res); + ASSERT_EQUAL(x, 42); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; + req.url = "/set5"; + app.handle(req, res); + ASSERT_EQUAL(x, 5); + } + { + boost::beast::http::request<boost::beast::http::string_body> r{}; + Request req{r}; + Response res; + req.url = "/set4"; + app.handle(req, res); + ASSERT_EQUAL(x, 4); + } } |