test_router.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* _
  2. * ___ __ _ __ _ _ _(_)
  3. * / __|/ _` |/ _` | | | | |
  4. * \__ \ (_| | (_| | |_| | |
  5. * |___/\__,_|\__, |\__,_|_|
  6. * |___/
  7. *
  8. * Cross-platform library which helps to develop web servers or frameworks.
  9. *
  10. * Copyright (C) 2016-2019 Silvio Clecio <[email protected]>
  11. *
  12. * Sagui library is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * Sagui library is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Lesser General Public
  23. * License along with Sagui library; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25. */
  26. #include "sg_assert.h"
  27. #include <stdlib.h>
  28. #include <errno.h>
  29. #include <string.h>
  30. #include "sg_router.h"
  31. #include <sagui.h>
  32. static void route_empty_cb(__SG_UNUSED void *cls,
  33. __SG_UNUSED struct sg_route *route) {
  34. }
  35. static void route_cb(void *cls, struct sg_route *route) {
  36. strcat(cls, sg_route_path(route));
  37. strcat(cls, sg_route_rawpattern(route));
  38. strcat(cls, sg_route_user_data(route));
  39. }
  40. static int router_dispatch_empty_cb(__SG_UNUSED void *cls,
  41. __SG_UNUSED const char *path,
  42. __SG_UNUSED struct sg_route *route) {
  43. return 0;
  44. }
  45. static int router_dispatch_123_cb(__SG_UNUSED void *cls,
  46. __SG_UNUSED const char *path,
  47. __SG_UNUSED struct sg_route *route) {
  48. return 123;
  49. }
  50. static int router_dispatch_concat_cb(void *cls, const char *path,
  51. struct sg_route *route) {
  52. strcat(cls, path);
  53. strcat(cls, sg_route_rawpattern(route));
  54. return 0;
  55. }
  56. static int router_match_empty_cb(__SG_UNUSED void *cls,
  57. __SG_UNUSED struct sg_route *route) {
  58. return 0;
  59. }
  60. static int router_match_123_cb(__SG_UNUSED void *cls,
  61. __SG_UNUSED struct sg_route *route) {
  62. return 123;
  63. }
  64. static void test_router_new(void) {
  65. struct sg_router *router;
  66. struct sg_route *routes = NULL;
  67. errno = 0;
  68. ASSERT(!sg_router_new(NULL));
  69. ASSERT(errno == EINVAL);
  70. ASSERT(sg_routes_add(&routes, "foo", route_empty_cb, "foo"));
  71. ASSERT(sg_routes_add(&routes, "bar", route_empty_cb, "bar"));
  72. router = sg_router_new(routes);
  73. ASSERT(router);
  74. ASSERT(router->routes == routes);
  75. sg_routes_cleanup(&routes);
  76. sg_router_free(router);
  77. }
  78. static void test_router_dispatch2(struct sg_router *router,
  79. struct sg_route **routes) {
  80. struct sg_router dummy_router;
  81. char str[100];
  82. ASSERT(sg_router_dispatch2(NULL, "foo", "bar", router_dispatch_empty_cb,
  83. "foobar", router_match_empty_cb) == EINVAL);
  84. ASSERT(sg_router_dispatch2(router, NULL, "bar", router_dispatch_empty_cb,
  85. "foobar", router_match_empty_cb) == EINVAL);
  86. dummy_router.routes = NULL;
  87. ASSERT(sg_router_dispatch2(&dummy_router, "foo", "bar",
  88. router_dispatch_empty_cb, "foobar",
  89. router_match_empty_cb) == EINVAL);
  90. ASSERT(sg_router_dispatch2(router, "foo", "bar", router_dispatch_123_cb,
  91. "foobar", router_match_empty_cb) == 123);
  92. memset(str, 0, sizeof(str));
  93. ASSERT(sg_router_dispatch2(router, "abc", "bar", router_dispatch_concat_cb,
  94. str, router_match_empty_cb) == ENOENT);
  95. ASSERT(strcmp(str, "abc^foo$abc^bar$") == 0);
  96. ASSERT(sg_router_dispatch2(router, "foo", "bar", router_dispatch_empty_cb,
  97. "foobar", router_match_123_cb) == 123);
  98. memset(str, 0, sizeof(str));
  99. ASSERT(sg_routes_add(routes, "/abc", route_cb, str));
  100. ASSERT(sg_router_dispatch2(router, "/abc", "foo", router_dispatch_empty_cb,
  101. "bar", router_match_empty_cb) == 0);
  102. ASSERT(strcmp(str, "/abc^/abc$foo") == 0);
  103. }
  104. static void test_router_dispatch(struct sg_router *router) {
  105. struct sg_router dummy_router;
  106. ASSERT(sg_router_dispatch(NULL, "foo", "bar") == EINVAL);
  107. ASSERT(sg_router_dispatch(router, NULL, "bar") == EINVAL);
  108. dummy_router.routes = NULL;
  109. ASSERT(sg_router_dispatch(&dummy_router, "foo", "bar") == EINVAL);
  110. ASSERT(sg_router_dispatch(router, "foo", NULL) == 0);
  111. ASSERT(sg_router_dispatch(router, "bar", NULL) == 0);
  112. }
  113. int main(void) {
  114. struct sg_router *router;
  115. struct sg_route *routes = NULL;
  116. test_router_new();
  117. sg_routes_add(&routes, "foo", route_empty_cb, "foo");
  118. sg_routes_add(&routes, "bar", route_empty_cb, "bar");
  119. router = sg_router_new(routes);
  120. test_router_dispatch2(router, &routes);
  121. test_router_dispatch(router);
  122. sg_routes_cleanup(&routes);
  123. sg_router_free(router);
  124. return EXIT_SUCCESS;
  125. }