1#include <string.h>
2
3#include <marisa.h>
4
5#include "assert.h"
6
7void TestHandle(void) {
8  marisa_trie *trie = NULL;
9
10  TEST_START();
11
12  ASSERT(marisa_init(&trie) == MARISA_OK);
13  ASSERT(marisa_init(&trie) == MARISA_HANDLE_ERROR);
14  ASSERT(marisa_end(trie) == MARISA_OK);
15  ASSERT(marisa_end(NULL) == MARISA_HANDLE_ERROR);
16
17  ASSERT(marisa_build(NULL, NULL, 0, NULL, NULL, NULL, 0) ==
18      MARISA_HANDLE_ERROR);
19
20  ASSERT(marisa_mmap(NULL, NULL, 0, 0) == MARISA_HANDLE_ERROR);
21  ASSERT(marisa_map(NULL, NULL, 0) == MARISA_HANDLE_ERROR);
22
23  ASSERT(marisa_load(NULL, NULL, 0, 0) == MARISA_HANDLE_ERROR);
24  ASSERT(marisa_fread(NULL, NULL) == MARISA_HANDLE_ERROR);
25  ASSERT(marisa_read(NULL, 0) == MARISA_HANDLE_ERROR);
26
27  ASSERT(marisa_save(NULL, NULL, 0, 0, 0) == MARISA_HANDLE_ERROR);
28  ASSERT(marisa_fwrite(NULL, NULL) == MARISA_HANDLE_ERROR);
29  ASSERT(marisa_write(NULL, 0) == MARISA_HANDLE_ERROR);
30
31  ASSERT(marisa_restore(NULL, 0, NULL, 0, NULL) == MARISA_HANDLE_ERROR);
32
33  ASSERT(marisa_lookup(NULL, NULL, 0, NULL) == MARISA_HANDLE_ERROR);
34
35  ASSERT(marisa_find(NULL, NULL, 0, NULL, NULL, 0, NULL) ==
36      MARISA_HANDLE_ERROR);
37  ASSERT(marisa_find_first(NULL, NULL, 0, NULL, NULL) == MARISA_HANDLE_ERROR);
38  ASSERT(marisa_find_last(NULL, NULL, 0, NULL, NULL) == MARISA_HANDLE_ERROR);
39  ASSERT(marisa_find_callback(NULL, NULL, 0, NULL, NULL) ==
40      MARISA_HANDLE_ERROR);
41
42  ASSERT(marisa_predict(NULL, NULL, 0, NULL, 0, NULL) == MARISA_HANDLE_ERROR);
43  ASSERT(marisa_predict_breadth_first(NULL, NULL, 0, NULL, 0, NULL) ==
44      MARISA_HANDLE_ERROR);
45  ASSERT(marisa_predict_depth_first(NULL, NULL, 0, NULL, 0, NULL) ==
46      MARISA_HANDLE_ERROR);
47  ASSERT(marisa_predict_callback(NULL, NULL, 0, NULL, NULL) ==
48      MARISA_HANDLE_ERROR);
49
50  ASSERT(marisa_get_num_tries(NULL) == 0);
51  ASSERT(marisa_get_num_keys(NULL) == 0);
52  ASSERT(marisa_get_num_nodes(NULL) == 0);
53  ASSERT(marisa_get_total_size(NULL) == 0);
54
55  ASSERT(marisa_clear(NULL) == MARISA_HANDLE_ERROR);
56
57  TEST_END();
58}
59
60int callback_for_find(void *num_keys,
61    marisa_uint32 key_id, size_t key_length) {
62  ASSERT(*(size_t *)num_keys == 0);
63  ASSERT(key_id == 1);
64  ASSERT(key_length == 3);
65  ++*(size_t *)num_keys;
66  return 1;
67}
68
69int callback_for_predict(void *num_keys,
70    marisa_uint32 key_id, const char *key, size_t key_length) {
71  ASSERT(*(size_t *)num_keys < 2);
72  switch (*(size_t *)num_keys) {
73    case 0: {
74      ASSERT(key_id == 0);
75      ASSERT(key_length == 3);
76      ASSERT(strcmp(key, "app") == 0);
77      break;
78    }
79    case 1: {
80      ASSERT(key_id == 3);
81      ASSERT(key_length == 5);
82      ASSERT(strcmp(key, "apple") == 0);
83      break;
84    }
85  }
86  ++*(size_t *)num_keys;
87  return 1;
88}
89
90void TestTrie() {
91  marisa_trie *trie = NULL;
92  const char *keys[8];
93  marisa_uint32 key_ids[8];
94  size_t i;
95  char key_buf[16];
96  size_t key_length;
97  marisa_uint32 key_id;
98  marisa_uint32 found_key_ids[8];
99  size_t found_key_lengths[8];
100  size_t num_found_keys;
101
102  TEST_START();
103
104  ASSERT(marisa_init(&trie) == MARISA_OK);
105
106  ASSERT(marisa_get_num_tries(trie) == 0);
107  ASSERT(marisa_get_num_keys(trie) == 0);
108  ASSERT(marisa_get_num_nodes(trie) == 0);
109  ASSERT(marisa_get_total_size(trie) == (sizeof(marisa_uint32) * 23));
110
111  ASSERT(marisa_build(trie, NULL, 0, NULL, NULL, NULL, 0) == MARISA_OK);
112
113  ASSERT(marisa_get_num_tries(trie) == 1);
114  ASSERT(marisa_get_num_keys(trie) == 0);
115  ASSERT(marisa_get_num_nodes(trie) == 1);
116
117  keys[0] = "apple";
118  keys[1] = "and";
119  keys[2] = "Bad";
120  keys[3] = "apple";
121  keys[4] = "app";
122
123  ASSERT(marisa_build(trie, keys, 5, NULL, NULL, key_ids,
124      1 | MARISA_WITHOUT_TAIL | MARISA_LABEL_ORDER) == MARISA_OK);
125
126  ASSERT(marisa_get_num_tries(trie) == 1);
127  ASSERT(marisa_get_num_keys(trie) == 4);
128  ASSERT(marisa_get_num_nodes(trie) == 11);
129
130  ASSERT(key_ids[0] == 3);
131  ASSERT(key_ids[1] == 1);
132  ASSERT(key_ids[2] == 0);
133  ASSERT(key_ids[3] == 3);
134  ASSERT(key_ids[4] == 2);
135
136  for (i = 0; i < marisa_get_num_tries(trie); ++i) {
137    ASSERT(marisa_restore(trie,
138        key_ids[i], key_buf, sizeof(key_buf), &key_length) == MARISA_OK);
139    ASSERT(key_length == strlen(keys[i]));
140    ASSERT(strcmp(key_buf, keys[i]) == 0);
141
142    ASSERT(marisa_lookup(trie,
143        keys[i], MARISA_ZERO_TERMINATED, &key_id) == MARISA_OK);
144    ASSERT(key_id == key_ids[i]);
145
146    ASSERT(marisa_lookup(trie,
147        keys[i], strlen(keys[i]), &key_id) == MARISA_OK);
148    ASSERT(key_id == key_ids[i]);
149  }
150
151  ASSERT(marisa_clear(trie) == MARISA_OK);
152
153  ASSERT(marisa_get_num_tries(trie) == 0);
154  ASSERT(marisa_get_num_keys(trie) == 0);
155  ASSERT(marisa_get_num_nodes(trie) == 0);
156  ASSERT(marisa_get_total_size(trie) == (sizeof(marisa_uint32) * 23));
157
158  ASSERT(marisa_build(trie, keys, 5, NULL, NULL, key_ids,
159      1 | MARISA_WITHOUT_TAIL | MARISA_WEIGHT_ORDER) == MARISA_OK);
160
161  ASSERT(marisa_get_num_tries(trie) == 1);
162  ASSERT(marisa_get_num_keys(trie) == 4);
163  ASSERT(marisa_get_num_nodes(trie) == 11);
164
165  ASSERT(key_ids[0] == 3);
166  ASSERT(key_ids[1] == 1);
167  ASSERT(key_ids[2] == 2);
168  ASSERT(key_ids[3] == 3);
169  ASSERT(key_ids[4] == 0);
170
171  ASSERT(marisa_find(trie, "ap", MARISA_ZERO_TERMINATED,
172      found_key_ids, found_key_lengths, 8, &num_found_keys) == MARISA_OK);
173  ASSERT(num_found_keys == 0);
174
175  ASSERT(marisa_find(trie, "applex", MARISA_ZERO_TERMINATED,
176      found_key_ids, found_key_lengths, 8, &num_found_keys) == MARISA_OK);
177  ASSERT(num_found_keys == 2);
178  ASSERT(found_key_ids[0] == key_ids[4]);
179  ASSERT(found_key_lengths[0] == 3);
180  ASSERT(found_key_ids[1] == key_ids[0]);
181  ASSERT(found_key_lengths[1] == 5);
182
183  num_found_keys = 0;
184  ASSERT(marisa_find_callback(trie, "anderson", MARISA_ZERO_TERMINATED,
185      callback_for_find, &num_found_keys) == MARISA_OK);
186  ASSERT(num_found_keys == 1);
187
188  ASSERT(marisa_predict(trie, "a", MARISA_ZERO_TERMINATED,
189      found_key_ids, 8, &num_found_keys) == MARISA_OK);
190  ASSERT(num_found_keys == 3);
191  ASSERT(found_key_ids[0] == key_ids[4]);
192  ASSERT(found_key_ids[1] == key_ids[1]);
193  ASSERT(found_key_ids[2] == key_ids[0]);
194
195  num_found_keys = 0;
196  ASSERT(marisa_predict_callback(trie, "app", MARISA_ZERO_TERMINATED,
197      callback_for_predict, &num_found_keys) == MARISA_OK);
198
199  ASSERT(marisa_end(trie) == MARISA_OK);
200
201  TEST_END();
202}
203
204int main(void) {
205  TestHandle();
206  TestTrie();
207
208  return 0;
209}
210