unittest_radix_tree.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. Copyright (c) 2018 Contributors as noted in the AUTHORS file
  3. This file is part of 0MQ.
  4. 0MQ is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. 0MQ is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "../tests/testutil.hpp"
  16. #include <radix_tree.hpp>
  17. #include <stdint.hpp>
  18. #include <set>
  19. #include <string>
  20. #include <string.h>
  21. #include <unity.h>
  22. #include <vector>
  23. void setUp ()
  24. {
  25. }
  26. void tearDown ()
  27. {
  28. }
  29. bool tree_add (zmq::radix_tree_t &tree_, const std::string &key_)
  30. {
  31. return tree_.add (reinterpret_cast<const unsigned char *> (key_.data ()),
  32. key_.size ());
  33. }
  34. bool tree_rm (zmq::radix_tree_t &tree_, const std::string &key_)
  35. {
  36. return tree_.rm (reinterpret_cast<const unsigned char *> (key_.data ()),
  37. key_.size ());
  38. }
  39. bool tree_check (zmq::radix_tree_t &tree_, const std::string &key_)
  40. {
  41. return tree_.check (reinterpret_cast<const unsigned char *> (key_.data ()),
  42. key_.size ());
  43. }
  44. void test_empty ()
  45. {
  46. zmq::radix_tree_t tree;
  47. TEST_ASSERT_TRUE (tree.size () == 0);
  48. }
  49. void test_add_single_entry ()
  50. {
  51. zmq::radix_tree_t tree;
  52. TEST_ASSERT_TRUE (tree_add (tree, "foo"));
  53. }
  54. void test_add_same_entry_twice ()
  55. {
  56. zmq::radix_tree_t tree;
  57. TEST_ASSERT_TRUE (tree_add (tree, "test"));
  58. TEST_ASSERT_FALSE (tree_add (tree, "test"));
  59. }
  60. void test_rm_when_empty ()
  61. {
  62. zmq::radix_tree_t tree;
  63. TEST_ASSERT_FALSE (tree_rm (tree, "test"));
  64. }
  65. void test_rm_single_entry ()
  66. {
  67. zmq::radix_tree_t tree;
  68. tree_add (tree, "temporary");
  69. TEST_ASSERT_TRUE (tree_rm (tree, "temporary"));
  70. }
  71. void test_rm_unique_entry_twice ()
  72. {
  73. zmq::radix_tree_t tree;
  74. tree_add (tree, "test");
  75. TEST_ASSERT_TRUE (tree_rm (tree, "test"));
  76. TEST_ASSERT_FALSE (tree_rm (tree, "test"));
  77. }
  78. void test_rm_duplicate_entry ()
  79. {
  80. zmq::radix_tree_t tree;
  81. tree_add (tree, "test");
  82. tree_add (tree, "test");
  83. TEST_ASSERT_FALSE (tree_rm (tree, "test"));
  84. TEST_ASSERT_TRUE (tree_rm (tree, "test"));
  85. }
  86. void test_rm_common_prefix ()
  87. {
  88. zmq::radix_tree_t tree;
  89. tree_add (tree, "checkpoint");
  90. tree_add (tree, "checklist");
  91. TEST_ASSERT_FALSE (tree_rm (tree, "check"));
  92. }
  93. void test_rm_common_prefix_entry ()
  94. {
  95. zmq::radix_tree_t tree;
  96. tree_add (tree, "checkpoint");
  97. tree_add (tree, "checklist");
  98. tree_add (tree, "check");
  99. TEST_ASSERT_TRUE (tree_rm (tree, "check"));
  100. }
  101. void test_rm_null_entry ()
  102. {
  103. zmq::radix_tree_t tree;
  104. tree_add (tree, "");
  105. TEST_ASSERT_TRUE (tree_rm (tree, ""));
  106. }
  107. void test_check_empty ()
  108. {
  109. zmq::radix_tree_t tree;
  110. TEST_ASSERT_FALSE (tree_check (tree, "foo"));
  111. }
  112. void test_check_added_entry ()
  113. {
  114. zmq::radix_tree_t tree;
  115. tree_add (tree, "entry");
  116. TEST_ASSERT_TRUE (tree_check (tree, "entry"));
  117. }
  118. void test_check_common_prefix ()
  119. {
  120. zmq::radix_tree_t tree;
  121. tree_add (tree, "introduce");
  122. tree_add (tree, "introspect");
  123. TEST_ASSERT_FALSE (tree_check (tree, "intro"));
  124. }
  125. void test_check_prefix ()
  126. {
  127. zmq::radix_tree_t tree;
  128. tree_add (tree, "toasted");
  129. TEST_ASSERT_FALSE (tree_check (tree, "toast"));
  130. TEST_ASSERT_FALSE (tree_check (tree, "toaste"));
  131. TEST_ASSERT_FALSE (tree_check (tree, "toaster"));
  132. }
  133. void test_check_nonexistent_entry ()
  134. {
  135. zmq::radix_tree_t tree;
  136. tree_add (tree, "red");
  137. TEST_ASSERT_FALSE (tree_check (tree, "blue"));
  138. }
  139. void test_check_query_longer_than_entry ()
  140. {
  141. zmq::radix_tree_t tree;
  142. tree_add (tree, "foo");
  143. TEST_ASSERT_TRUE (tree_check (tree, "foobar"));
  144. }
  145. void test_check_null_entry_added ()
  146. {
  147. zmq::radix_tree_t tree;
  148. tree_add (tree, "");
  149. TEST_ASSERT_TRUE (tree_check (tree, "all queries return true"));
  150. }
  151. void test_size ()
  152. {
  153. zmq::radix_tree_t tree;
  154. // Adapted from the example on wikipedia.
  155. std::vector<std::string> keys;
  156. keys.push_back ("tester");
  157. keys.push_back ("water");
  158. keys.push_back ("slow");
  159. keys.push_back ("slower");
  160. keys.push_back ("test");
  161. keys.push_back ("team");
  162. keys.push_back ("toast");
  163. for (size_t i = 0; i < keys.size (); ++i)
  164. TEST_ASSERT_TRUE (tree_add (tree, keys[i]));
  165. TEST_ASSERT_TRUE (tree.size () == keys.size ());
  166. for (size_t i = 0; i < keys.size (); ++i)
  167. TEST_ASSERT_FALSE (tree_add (tree, keys[i]));
  168. TEST_ASSERT_TRUE (tree.size () == 2 * keys.size ());
  169. for (size_t i = 0; i < keys.size (); ++i)
  170. TEST_ASSERT_FALSE (tree_rm (tree, keys[i]));
  171. TEST_ASSERT_TRUE (tree.size () == keys.size ());
  172. for (size_t i = 0; i < keys.size (); ++i)
  173. TEST_ASSERT_TRUE (tree_rm (tree, keys[i]));
  174. TEST_ASSERT_TRUE (tree.size () == 0);
  175. }
  176. void return_key (unsigned char *data_, size_t size_, void *arg_)
  177. {
  178. std::vector<std::string> *vec =
  179. reinterpret_cast<std::vector<std::string> *> (arg_);
  180. std::string key;
  181. for (size_t i = 0; i < size_; ++i)
  182. key.push_back (static_cast<char> (data_[i]));
  183. vec->push_back (key);
  184. }
  185. void test_apply ()
  186. {
  187. zmq::radix_tree_t tree;
  188. std::set<std::string> keys;
  189. keys.insert ("tester");
  190. keys.insert ("water");
  191. keys.insert ("slow");
  192. keys.insert ("slower");
  193. keys.insert ("test");
  194. keys.insert ("team");
  195. keys.insert ("toast");
  196. const std::set<std::string>::iterator end = keys.end ();
  197. for (std::set<std::string>::iterator it = keys.begin (); it != end; ++it)
  198. tree_add (tree, *it);
  199. std::vector<std::string> *vec = new std::vector<std::string> ();
  200. tree.apply (return_key, static_cast<void *> (vec));
  201. for (size_t i = 0; i < vec->size (); ++i)
  202. TEST_ASSERT_TRUE (keys.count ((*vec)[i]) > 0);
  203. delete vec;
  204. }
  205. int main (void)
  206. {
  207. setup_test_environment ();
  208. UNITY_BEGIN ();
  209. RUN_TEST (test_empty);
  210. RUN_TEST (test_add_single_entry);
  211. RUN_TEST (test_add_same_entry_twice);
  212. RUN_TEST (test_rm_when_empty);
  213. RUN_TEST (test_rm_single_entry);
  214. RUN_TEST (test_rm_unique_entry_twice);
  215. RUN_TEST (test_rm_duplicate_entry);
  216. RUN_TEST (test_rm_common_prefix);
  217. RUN_TEST (test_rm_common_prefix_entry);
  218. RUN_TEST (test_rm_null_entry);
  219. RUN_TEST (test_check_empty);
  220. RUN_TEST (test_check_added_entry);
  221. RUN_TEST (test_check_common_prefix);
  222. RUN_TEST (test_check_prefix);
  223. RUN_TEST (test_check_nonexistent_entry);
  224. RUN_TEST (test_check_query_longer_than_entry);
  225. RUN_TEST (test_check_null_entry_added);
  226. RUN_TEST (test_size);
  227. RUN_TEST (test_apply);
  228. return UNITY_END ();
  229. }