Mercurial > paster
comparison tests/test-database.c @ 34:030efbd7340f
tests: create unit tests, closes #1696 @2h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 12 Feb 2020 12:50:00 +0100 |
parents | |
children | 48834441dc86 |
comparison
equal
deleted
inserted
replaced
33:511e2e865e15 | 34:030efbd7340f |
---|---|
1 /* | |
2 * test-database.c -- test database functions | |
3 * | |
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #include <stdio.h> | |
20 #include <unistd.h> | |
21 | |
22 #define GREATEST_USE_ABBREVS 0 | |
23 #include <greatest.h> | |
24 | |
25 #include "database.h" | |
26 #include "paste.h" | |
27 #include "util.h" | |
28 | |
29 #define TEST_DATABASE "test.db" | |
30 | |
31 static void | |
32 setup(void *data) | |
33 { | |
34 remove(TEST_DATABASE); | |
35 | |
36 if (!database_open(TEST_DATABASE)) | |
37 die("abort: could not open database"); | |
38 | |
39 (void)data; | |
40 } | |
41 | |
42 static void | |
43 finish(void *data) | |
44 { | |
45 database_finish(); | |
46 | |
47 (void)data; | |
48 } | |
49 | |
50 GREATEST_TEST | |
51 recents_empty(void) | |
52 { | |
53 struct paste pastes[10]; | |
54 size_t max = 10; | |
55 | |
56 if (!database_recents(pastes, &max)) | |
57 GREATEST_FAIL(); | |
58 | |
59 GREATEST_ASSERT_EQ(max, 0); | |
60 GREATEST_PASS(); | |
61 } | |
62 | |
63 GREATEST_TEST | |
64 recents_one(void) | |
65 { | |
66 struct paste pastes[10]; | |
67 size_t max = 10; | |
68 struct paste one = { | |
69 .title = estrdup("test 1"), | |
70 .author = estrdup("unit test"), | |
71 .language = estrdup("cpp"), | |
72 .code = estrdup("int main() {}"), | |
73 .duration = PASTE_HOUR, | |
74 .visible = true | |
75 }; | |
76 | |
77 if (!database_insert(&one)) | |
78 GREATEST_FAIL(); | |
79 if (!database_recents(pastes, &max)) | |
80 GREATEST_FAIL(); | |
81 | |
82 GREATEST_ASSERT_EQ(max, 1); | |
83 GREATEST_ASSERT(pastes[0].uuid); | |
84 GREATEST_ASSERT_STR_EQ(pastes[0].title, "test 1"); | |
85 GREATEST_ASSERT_STR_EQ(pastes[0].author, "unit test"); | |
86 GREATEST_ASSERT_STR_EQ(pastes[0].language, "cpp"); | |
87 GREATEST_ASSERT_STR_EQ(pastes[0].code, "int main() {}"); | |
88 GREATEST_ASSERT_EQ(pastes[0].duration, PASTE_HOUR); | |
89 GREATEST_ASSERT(pastes[0].visible); | |
90 GREATEST_PASS(); | |
91 } | |
92 | |
93 | |
94 GREATEST_TEST | |
95 recents_hidden(void) | |
96 { | |
97 struct paste pastes[10]; | |
98 size_t max = 10; | |
99 struct paste one = { | |
100 .title = estrdup("test 1"), | |
101 .author = estrdup("unit test"), | |
102 .language = estrdup("cpp"), | |
103 .code = estrdup("int main() {}"), | |
104 .duration = PASTE_HOUR, | |
105 .visible = false | |
106 }; | |
107 | |
108 if (!database_insert(&one)) | |
109 GREATEST_FAIL(); | |
110 if (!database_recents(pastes, &max)) | |
111 GREATEST_FAIL(); | |
112 | |
113 GREATEST_ASSERT_EQ(max, 0); | |
114 GREATEST_PASS(); | |
115 } | |
116 | |
117 GREATEST_TEST | |
118 recents_many(void) | |
119 { | |
120 static const int expected[] = { 2, 1, 0 }; | |
121 struct paste pastes[3]; | |
122 size_t max = 3; | |
123 struct paste pastie = { | |
124 .duration = PASTE_HOUR, | |
125 .visible = true | |
126 }; | |
127 | |
128 for (int i = 0; i < 3; ++i) { | |
129 pastie.title = estrdup(bprintf("test %d", i)); | |
130 pastie.author = estrdup(bprintf("unit test %d", i)); | |
131 pastie.language = estrdup("cpp"); | |
132 pastie.code = estrdup(bprintf("int main() { return %d; }", i)); | |
133 | |
134 if (!database_insert(&pastie)) | |
135 GREATEST_FAIL(); | |
136 | |
137 /* Sleep a little bit to avoid same timestamp. */ | |
138 sleep(2); | |
139 }; | |
140 | |
141 if (!database_recents(pastes, &max)) | |
142 GREATEST_FAIL(); | |
143 | |
144 GREATEST_ASSERT_EQ(max, 3U); | |
145 | |
146 for (int i = 0; i < 3; ++i) { | |
147 /* Selected in most recents first. */ | |
148 GREATEST_ASSERT(pastes[i].uuid); | |
149 GREATEST_ASSERT_STR_EQ(pastes[i].title, | |
150 bprintf("test %d", expected[i])); | |
151 GREATEST_ASSERT_STR_EQ(pastes[i].author, | |
152 bprintf("unit test %d", expected[i])); | |
153 GREATEST_ASSERT_STR_EQ(pastes[i].language, "cpp"); | |
154 GREATEST_ASSERT_STR_EQ(pastes[i].code, | |
155 bprintf("int main() { return %d; }", expected[i])); | |
156 GREATEST_ASSERT_EQ(pastes[i].duration, PASTE_HOUR); | |
157 GREATEST_ASSERT(pastes[i].visible); | |
158 }; | |
159 | |
160 GREATEST_PASS(); | |
161 } | |
162 | |
163 GREATEST_TEST | |
164 recents_limits(void) | |
165 { | |
166 static const int expected[] = { 19, 18, 17 }; | |
167 struct paste pastes[3]; | |
168 size_t max = 3; | |
169 struct paste pastie = { | |
170 .duration = PASTE_HOUR, | |
171 .visible = true | |
172 }; | |
173 | |
174 for (int i = 0; i < 20; ++i) { | |
175 pastie.title = estrdup(bprintf("test %d", i)); | |
176 pastie.author = estrdup(bprintf("unit test %d", i)); | |
177 pastie.language = estrdup("cpp"); | |
178 pastie.code = estrdup(bprintf("int main() { return %d; }", i)); | |
179 | |
180 if (!database_insert(&pastie)) | |
181 GREATEST_FAIL(); | |
182 | |
183 /* Sleep a little bit to avoid same timestamp. */ | |
184 sleep(2); | |
185 }; | |
186 | |
187 if (!database_recents(pastes, &max)) | |
188 GREATEST_FAIL(); | |
189 | |
190 GREATEST_ASSERT_EQ(max, 3U); | |
191 | |
192 for (int i = 0; i < 3; ++i) { | |
193 /* Selected in most recents first. */ | |
194 GREATEST_ASSERT(pastes[i].uuid); | |
195 GREATEST_ASSERT_STR_EQ(pastes[i].title, | |
196 bprintf("test %d", expected[i])); | |
197 GREATEST_ASSERT_STR_EQ(pastes[i].author, | |
198 bprintf("unit test %d", expected[i])); | |
199 GREATEST_ASSERT_STR_EQ(pastes[i].language, "cpp"); | |
200 GREATEST_ASSERT_STR_EQ(pastes[i].code, | |
201 bprintf("int main() { return %d; }", expected[i])); | |
202 GREATEST_ASSERT_EQ(pastes[i].duration, PASTE_HOUR); | |
203 GREATEST_ASSERT(pastes[i].visible); | |
204 }; | |
205 | |
206 GREATEST_PASS(); | |
207 } | |
208 | |
209 GREATEST_SUITE(recents) | |
210 { | |
211 GREATEST_SET_SETUP_CB(setup, NULL); | |
212 GREATEST_SET_TEARDOWN_CB(finish, NULL); | |
213 GREATEST_RUN_TEST(recents_empty); | |
214 GREATEST_RUN_TEST(recents_one); | |
215 GREATEST_RUN_TEST(recents_hidden); | |
216 GREATEST_RUN_TEST(recents_many); | |
217 GREATEST_RUN_TEST(recents_limits); | |
218 } | |
219 | |
220 GREATEST_TEST | |
221 get_basic(void) | |
222 { | |
223 struct paste original = { | |
224 .title = estrdup("test 1"), | |
225 .author = estrdup("unit test"), | |
226 .language = estrdup("cpp"), | |
227 .code = estrdup("int main() {}"), | |
228 .duration = PASTE_HOUR, | |
229 .visible = false | |
230 }; | |
231 struct paste new = { 0 }; | |
232 | |
233 if (!database_insert(&original)) | |
234 GREATEST_FAIL(); | |
235 if (!database_get(&new, original.uuid)) | |
236 GREATEST_FAIL(); | |
237 | |
238 GREATEST_ASSERT_STR_EQ(new.uuid, original.uuid); | |
239 GREATEST_ASSERT_STR_EQ(new.title, original.title); | |
240 GREATEST_ASSERT_STR_EQ(new.author, original.author); | |
241 GREATEST_ASSERT_STR_EQ(new.language, original.language); | |
242 GREATEST_ASSERT_STR_EQ(new.code, original.code); | |
243 GREATEST_ASSERT_EQ(new.visible, original.visible); | |
244 GREATEST_PASS(); | |
245 } | |
246 | |
247 GREATEST_TEST | |
248 get_nonexistent(void) | |
249 { | |
250 struct paste new = { 0 }; | |
251 | |
252 if (!database_get(&new, "unknown")) | |
253 GREATEST_FAIL(); | |
254 | |
255 GREATEST_ASSERT(!new.uuid); | |
256 GREATEST_ASSERT(!new.title); | |
257 GREATEST_ASSERT(!new.author); | |
258 GREATEST_ASSERT(!new.language); | |
259 GREATEST_ASSERT(!new.code); | |
260 GREATEST_PASS(); | |
261 } | |
262 | |
263 GREATEST_SUITE(get) | |
264 { | |
265 GREATEST_SET_SETUP_CB(setup, NULL); | |
266 GREATEST_SET_TEARDOWN_CB(finish, NULL); | |
267 GREATEST_RUN_TEST(get_basic); | |
268 GREATEST_RUN_TEST(get_nonexistent); | |
269 } | |
270 | |
271 GREATEST_TEST | |
272 search_basic(void) | |
273 { | |
274 struct paste searched[3] = { 0 }; | |
275 struct paste originals[] = { | |
276 { | |
277 .title = estrdup("This is in C"), | |
278 .author = estrdup("markand"), | |
279 .language = estrdup("cpp"), | |
280 .code = estrdup("int main(void) {}"), | |
281 .duration = PASTE_HOUR, | |
282 .visible = true | |
283 }, | |
284 { | |
285 .title = estrdup("This is in shell"), | |
286 .author = estrdup("markand"), | |
287 .language = estrdup("shell"), | |
288 .code = estrdup("f() {}"), | |
289 .duration = PASTE_HOUR, | |
290 .visible = true | |
291 }, | |
292 { | |
293 .title = estrdup("This is in python"), | |
294 .author = estrdup("NiReaS"), | |
295 .language = estrdup("python"), | |
296 .code = estrdup("f: pass"), | |
297 .duration = PASTE_HOUR, | |
298 .visible = true | |
299 }, | |
300 }; | |
301 size_t max = 3; | |
302 | |
303 for (int i = 0; i < 3; ++i) | |
304 if (!database_insert(&originals[i])) | |
305 GREATEST_FAIL(); | |
306 | |
307 /* | |
308 * Search: | |
309 * | |
310 * title = <any> | |
311 * author = markand, | |
312 * language = cpp | |
313 */ | |
314 if (!database_search(searched, &max, NULL, "markand", "cpp")) | |
315 GREATEST_FAIL(); | |
316 | |
317 GREATEST_ASSERT_EQ(max, 1); | |
318 GREATEST_ASSERT(searched[0].uuid); | |
319 GREATEST_ASSERT_STR_EQ(searched[0].title, "This is in C"); | |
320 GREATEST_ASSERT_STR_EQ(searched[0].author, "markand"); | |
321 GREATEST_ASSERT_STR_EQ(searched[0].language, "cpp"); | |
322 GREATEST_ASSERT_STR_EQ(searched[0].code, "int main(void) {}"); | |
323 GREATEST_ASSERT_EQ(searched[0].duration, PASTE_HOUR); | |
324 GREATEST_ASSERT(searched[0].visible); | |
325 GREATEST_PASS(); | |
326 } | |
327 | |
328 GREATEST_TEST | |
329 search_notfound(void) | |
330 { | |
331 struct paste searched = { 0 }; | |
332 struct paste original = { | |
333 .title = estrdup("This is in C"), | |
334 .author = estrdup("markand"), | |
335 .language = estrdup("cpp"), | |
336 .code = estrdup("int main(void) {}"), | |
337 .duration = PASTE_HOUR, | |
338 .visible = true | |
339 }; | |
340 size_t max = 1; | |
341 | |
342 if (!database_insert(&original)) | |
343 GREATEST_FAIL(); | |
344 | |
345 /* | |
346 * Search: | |
347 * | |
348 * title = <any> | |
349 * author = jean, | |
350 * language = <any> | |
351 */ | |
352 if (!database_search(&searched, &max, NULL, "jean", NULL)) | |
353 GREATEST_FAIL(); | |
354 | |
355 GREATEST_ASSERT_EQ(max, 0); | |
356 GREATEST_ASSERT(!searched.uuid); | |
357 GREATEST_ASSERT(!searched.title); | |
358 GREATEST_ASSERT(!searched.author); | |
359 GREATEST_ASSERT(!searched.language); | |
360 GREATEST_ASSERT(!searched.code); | |
361 GREATEST_PASS(); | |
362 } | |
363 | |
364 GREATEST_TEST | |
365 search_private(void) | |
366 { | |
367 struct paste searched = { 0 }; | |
368 struct paste original = { | |
369 .title = estrdup("This is secret"), | |
370 .author = estrdup("anonymous"), | |
371 .language = estrdup("nohighlight"), | |
372 .code = estrdup("I love you, honey"), | |
373 .duration = PASTE_HOUR, | |
374 .visible = false | |
375 }; | |
376 size_t max = 1; | |
377 | |
378 if (!database_insert(&original)) | |
379 GREATEST_FAIL(); | |
380 | |
381 /* | |
382 * Search: | |
383 * | |
384 * title = <any> | |
385 * author = <any> | |
386 * language = <any> | |
387 */ | |
388 if (!database_search(&searched, &max, NULL, NULL, NULL)) | |
389 GREATEST_FAIL(); | |
390 | |
391 GREATEST_ASSERT_EQ(max, 0); | |
392 GREATEST_ASSERT(!searched.uuid); | |
393 GREATEST_ASSERT(!searched.title); | |
394 GREATEST_ASSERT(!searched.author); | |
395 GREATEST_ASSERT(!searched.language); | |
396 GREATEST_ASSERT(!searched.code); | |
397 GREATEST_PASS(); | |
398 } | |
399 | |
400 GREATEST_SUITE(search) | |
401 { | |
402 GREATEST_SET_SETUP_CB(setup, NULL); | |
403 GREATEST_SET_TEARDOWN_CB(finish, NULL); | |
404 GREATEST_RUN_TEST(search_basic); | |
405 GREATEST_RUN_TEST(search_notfound); | |
406 GREATEST_RUN_TEST(search_private); | |
407 } | |
408 | |
409 GREATEST_TEST | |
410 clear_run(void) | |
411 { | |
412 struct paste searched = { 0 }; | |
413 struct paste originals[] = { | |
414 /* Will be deleted */ | |
415 { | |
416 .title = estrdup("This is in C"), | |
417 .author = estrdup("markand"), | |
418 .language = estrdup("cpp"), | |
419 .code = estrdup("int main(void) {}"), | |
420 .duration = 1, | |
421 .visible = true | |
422 }, | |
423 /* Will be deleted */ | |
424 { | |
425 .title = estrdup("This is in shell"), | |
426 .author = estrdup("markand"), | |
427 .language = estrdup("shell"), | |
428 .code = estrdup("f() {}"), | |
429 .duration = 1, | |
430 .visible = true | |
431 }, | |
432 /* Will be kept */ | |
433 { | |
434 .title = estrdup("This is in python"), | |
435 .author = estrdup("NiReaS"), | |
436 .language = estrdup("python"), | |
437 .code = estrdup("f: pass"), | |
438 .duration = PASTE_HOUR, | |
439 .visible = true | |
440 }, | |
441 }; | |
442 size_t max = 1; | |
443 | |
444 for (int i = 0; i < 3; ++i) | |
445 if (!database_insert(&originals[i])) | |
446 GREATEST_FAIL(); | |
447 | |
448 /* Sleep 2 seconds to exceed the lifetime of C and shell pastes. */ | |
449 sleep(2); | |
450 database_clear(); | |
451 | |
452 /* | |
453 * Search: | |
454 * | |
455 * title = <any> | |
456 * author = <any> | |
457 * language = <any> | |
458 */ | |
459 if (!database_search(&searched, &max, NULL, NULL, NULL)) | |
460 GREATEST_FAIL(); | |
461 | |
462 GREATEST_ASSERT_EQ(max, 1); | |
463 GREATEST_ASSERT(searched.uuid); | |
464 GREATEST_ASSERT_STR_EQ(searched.title, "This is in python"); | |
465 GREATEST_ASSERT_STR_EQ(searched.author, "NiReaS"); | |
466 GREATEST_ASSERT_STR_EQ(searched.language, "python"); | |
467 GREATEST_ASSERT_STR_EQ(searched.code, "f: pass"); | |
468 GREATEST_ASSERT_EQ(searched.duration, PASTE_HOUR); | |
469 GREATEST_ASSERT(searched.visible); | |
470 GREATEST_PASS(); | |
471 } | |
472 | |
473 GREATEST_SUITE(clear) | |
474 { | |
475 GREATEST_SET_SETUP_CB(setup, NULL); | |
476 GREATEST_SET_TEARDOWN_CB(finish, NULL); | |
477 GREATEST_RUN_TEST(clear_run); | |
478 } | |
479 | |
480 GREATEST_MAIN_DEFS(); | |
481 | |
482 int | |
483 main(int argc, char **argv) | |
484 { | |
485 GREATEST_MAIN_BEGIN(); | |
486 GREATEST_RUN_SUITE(recents); | |
487 GREATEST_RUN_SUITE(get); | |
488 GREATEST_RUN_SUITE(search); | |
489 GREATEST_RUN_SUITE(clear); | |
490 GREATEST_MAIN_END(); | |
491 } |