From 92fcd32e0aa53508cbf0417fec4e6e1315211d68 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Sat, 28 Dec 2019 22:12:49 +0100 Subject: [PATCH] Add router unit tests --- tests/HttpRouter.cpp | 247 +++++++++++++++++++++++++++++++++++++++++++ tests/Makefile | 3 + 2 files changed, 250 insertions(+) create mode 100644 tests/HttpRouter.cpp create mode 100644 tests/Makefile diff --git a/tests/HttpRouter.cpp b/tests/HttpRouter.cpp new file mode 100644 index 0000000..629a0f7 --- /dev/null +++ b/tests/HttpRouter.cpp @@ -0,0 +1,247 @@ +#include "../src/HttpRouter.h" + +#include +#include + +void testMethodPriority() { + std::cout << "TestMethodPriority" << std::endl; + uWS::HttpRouter r; + std::string result; + + r.add(r.methods, "/static/route", [&result](auto *) { + std::cout << "ANY static route" << std::endl; + result += "AS"; + return true; + }, r.LOW_PRIORITY); + + r.add({"patch"}, "/static/route", [&result](auto *) { + std::cout << "PATCH static route" << std::endl; + result += "PS"; + return false; + }); + + r.add({"get"}, "/static/route", [&result](auto *) { + std::cout << "GET static route" << std::endl; + result += "GS"; + return true; + }); + + assert(r.route("nonsense", "/static/route") == false); + assert(r.route("get", "/static") == false); + assert(result == ""); + + /* Should end up directly in ANY handler */ + result.clear(); + assert(r.route("post", "/static/route")); + assert(result == "AS"); + + /* Should up directly in GET handler */ + result.clear(); + assert(r.route("get", "/static/route")); + assert(result == "GS"); + + /* Should end up in PATCH then in ANY handler */ + result.clear(); + assert(r.route("patch", "/static/route")); + assert(result == "PSAS"); +} + +void testPatternPriority() { + std::cout << "TestPatternPriority" << std::endl; + uWS::HttpRouter r; + std::string result; + + r.add(r.methods, "/a/b/c", [&result](auto *) { + std::cout << "ANY static route" << std::endl; + result += "AS"; + return false; + }, r.LOW_PRIORITY); + + r.add({"get"}, "/a/:b/c", [&result](auto *) { + std::cout << "GET parameter route" << std::endl; + result += "GP"; + return false; + }); + + r.add({"get"}, "/a/*", [&result](auto *) { + std::cout << "GET wildcard route" << std::endl; + result += "GW"; + return false; + }); + + r.add({"get"}, "/a/b/c", [&result](auto *) { + std::cout << "GET static route" << std::endl; + result += "GS"; + return false; + }); + + r.add({"post"}, "/a/:b/c", [&result](auto *) { + std::cout << "POST parameter route" << std::endl; + result += "PP"; + return false; + }); + + r.add(r.methods, "/a/:b/c", [&result](auto *) { + std::cout << "ANY parameter route" << std::endl; + result += "AP"; + return false; + }, r.LOW_PRIORITY); + + assert(r.route("post", "/a/b/c") == false); + assert(result == "ASPPAP"); + + result.clear(); + assert(r.route("get", "/a/b/c") == false); + assert(result == "GSASGPAPGW"); +} + +void testUpgrade() { + std::cout << "TestUpgrade" << std::endl; + uWS::HttpRouter r; + std::string result; + + /* HTTP on / */ + r.add({"get"}, "/something", [&result](auto *) { + result += "GS"; + return true; + }, r.MEDIUM_PRIORITY); + + /* HTTP on /* */ + r.add({"get"}, "/*", [&result](auto *) { + result += "GW"; + return false; + }, r.MEDIUM_PRIORITY); + + /* WebSockets on /* */ + r.add({"get"}, "/*", [&result](auto *) { + result += "WW"; + return false; + }, r.HIGH_PRIORITY); + + assert(r.route("get", "/something")); + assert(result == "GS"); + result.clear(); + + assert(r.route("get", "/") == false); + assert(result == "WWGW"); +} + +void testBugReports() { + std::cout << "TestBugReports" << std::endl; + { + uWS::HttpRouter r; + std::string result; + + /* WS on /* */ + r.add({"get"}, "/*", [&result](auto *) { + result += "WW"; + return false; + }, r.HIGH_PRIORITY); + + /* HTTP on /ok */ + r.add({"get"}, "/ok", [&result](auto *) { + result += "GS"; + return false; + }, r.MEDIUM_PRIORITY); + + r.add({"get"}, "/*", [&result](auto *) { + result += "GW"; + return false; + }, r.MEDIUM_PRIORITY); + + r.route("get", "/ok"); + assert(result == "GSWWGW"); + } + + { + uWS::HttpRouter r; + std::string result; + + /* WS on / */ + r.add({"get"}, "/", [&result](auto *) { + result += "WS"; + return false; + }, r.HIGH_PRIORITY); + + /* HTTP on / */ + r.add({"get"}, "/", [&result](auto *) { + result += "GS"; + return false; + }, r.MEDIUM_PRIORITY); + + r.route("get", "/"); + assert(result == "WSGS"); + } +} + +void testParameters() { + std::cout << "TestParameters" << std::endl; + uWS::HttpRouter r; + std::string result; + + r.add({"get"}, "/candy/:kind/*", [&result](auto *h) { + auto [paramsTop, params] = h->getParameters(); + + assert(paramsTop == 0); + assert(params[0] == "lollipop"); + + result += "GPW"; + return false; + }); + + r.add({"get"}, "/candy/lollipop/*", [&result](auto *h) { + auto [paramsTop, params] = h->getParameters(); + + assert(paramsTop == -1); + + result += "GLW"; + return false; + }); + + r.add({"get"}, "/candy/:kind/:action", [&result](auto *h) { + auto [paramsTop, params] = h->getParameters(); + + assert(paramsTop == 1); + assert(params[0] == "lollipop"); + assert(params[1] == "eat"); + + result += "GPP"; + return false; + }); + + r.add({"get"}, "/candy/lollipop/:action", [&result](auto *h) { + auto [paramsTop, params] = h->getParameters(); + + assert(params[0] == "eat"); + assert(paramsTop == 0); + + result += "GLP"; + return false; + }); + + r.add({"get"}, "/candy/lollipop/eat", [&result](auto *h) { + auto [paramsTop, params] = h->getParameters(); + + assert(paramsTop == -1); + + result += "GLS"; + return false; + }); + + r.route("get", "/candy/lollipop/eat"); + assert(result == "GLSGLPGLWGPPGPW"); + result.clear(); + + r.route("get", "/candy/lollipop/"); + r.route("get", "/candy/lollipop"); + r.route("get", "/candy/"); + assert(result == ""); +} + +int main() { + testPatternPriority(); + testMethodPriority(); + testUpgrade(); + testBugReports(); + testParameters(); +} \ No newline at end of file diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..100e8cf --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,3 @@ +default: + $(CXX) -std=c++17 HttpRouter.cpp -o HttpRouter + ./HttpRouter \ No newline at end of file