Browse code

Move test suites into separate files

John Hawthorn authored on 05/04/2017 05:52:53
Showing 1 changed files
... ...
@@ -1,353 +1,17 @@
1
-#define _GNU_SOURCE
2
-#include <stdlib.h>
3
-#include <signal.h>
4
-#include <stdio.h>
5
-#include <string.h>
6
-
7
-#include "../config.h"
8
-#include "match.h"
9
-#include "choices.h"
10
-#include "options.h"
11
-
12 1
 #include "greatest/greatest.h"
13 2
 
14
-static options_t default_options;
15
-
16
-TEST test_match() {
17
-	ASSERT(has_match("a", "a"));
18
-	ASSERT(has_match("a", "ab"));
19
-	ASSERT(has_match("a", "ba"));
20
-	ASSERT(has_match("abc", "a|b|c"));
21
-
22
-	/* non-match */
23
-	ASSERT(!has_match("a", ""));
24
-	ASSERT(!has_match("a", "b"));
25
-	ASSERT(!has_match("ass", "tags"));
26
-
27
-	/* match when query is empty */
28
-	ASSERT(has_match("", ""));
29
-	ASSERT(has_match("", "a"));
30
-
31
-	PASS();
32
-}
33
-
34
-TEST test_relative_scores() {
35
-	/* App/Models/Order is better than App/MOdels/zRder  */
36
-	ASSERT(match("amor", "app/models/order") > match("amor", "app/models/zrder"));
37
-
38
-	/* App/MOdels/foo is better than App/M/fOo  */
39
-	ASSERT(match("amo", "app/m/foo") < match("amo", "app/models/foo"));
40
-
41
-	/* GEMFIle.Lock < GEMFILe  */
42
-	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
43
-
44
-	/* GEMFIle.Lock < GEMFILe  */
45
-	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
46
-
47
-	/* Prefer shorter matches */
48
-	ASSERT(match("abce", "abcdef") > match("abce", "abc de"));
49
-
50
-	/* Prefer shorter candidates */
51
-	ASSERT(match("test", "tests") > match("test", "testing"));
52
-
53
-	/* Scores first letter highly */
54
-	ASSERT(match("test", "testing") > match("test", "/testing"));
55
-
56
-	/* Prefer shorter matches */
57
-	ASSERT(match("abc", "    a b c ") > match("abc", " a  b  c "));
58
-	ASSERT(match("abc", " a b c    ") > match("abc", " a  b  c "));
59
-
60
-	PASS();
61
-}
62
-
63
-TEST test_exact_scores() {
64
-	/* Exact match is SCORE_MAX */
65
-	ASSERT_EQ(SCORE_MAX, match("abc", "abc"));
66
-	ASSERT_EQ(SCORE_MAX, match("aBc", "abC"));
67
-
68
-	/* Empty query always results in SCORE_MIN */
69
-	ASSERT_EQ(SCORE_MIN, match("", ""));
70
-	ASSERT_EQ(SCORE_MIN, match("", "a"));
71
-	ASSERT_EQ(SCORE_MIN, match("", "bb"));
72
-
73
-	/* Gaps */
74
-	ASSERT_EQ(SCORE_GAP_LEADING, match("a", "*a"));
75
-	ASSERT_EQ(SCORE_GAP_LEADING*2, match("a", "*ba"));
76
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING, match("a", "**a*"));
77
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2, match("a", "**a**"));
78
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2, match("aa", "**aa**"));
79
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING, match("aa", "**a*a**"));
80
-
81
-	/* Consecutive */
82
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE, match("aa", "*aa"));
83
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2, match("aaa", "*aaa"));
84
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE, match("aaa", "*a*aa"));
85
-
86
-	/* Slash */
87
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_SLASH, match("a", "/a"));
88
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH, match("a", "*/a"));
89
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE, match("aa", "a/aa"));
90
-
91
-	/* Capital */
92
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL, match("a", "bA"));
93
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL, match("a", "baA"));
94
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE, match("aa", "baAa"));
95
-
96
-	/* Dot */
97
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_DOT, match("a", ".a"));
98
-	ASSERT_EQ(SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT, match("a", "*a.a"));
99
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT, match("a", "*a.a"));
100
-
101
-	PASS();
102
-}
103
-
104
-TEST test_positions_1() {
105
-	size_t positions[3];
106
-	match_positions("amo", "app/models/foo", positions);
107
-	ASSERT_EQ(0, positions[0]);
108
-	ASSERT_EQ(4, positions[1]);
109
-	ASSERT_EQ(5, positions[2]);
110
-
111
-	PASS();
112
-}
113
-
114
-TEST test_positions_2() {
115
-	/*
116
-	 * We should prefer matching the 'o' in order, since it's the beginning
117
-	 * of a word.
118
-	 */
119
-	size_t positions[4];
120
-	match_positions("amor", "app/models/order", positions);
121
-	ASSERT_EQ(0, positions[0]);
122
-	ASSERT_EQ(4, positions[1]);
123
-	ASSERT_EQ(11, positions[2]);
124
-
125
-	PASS();
126
-}
127
-
128
-TEST test_positions_3() {
129
-	size_t positions[2];
130
-	match_positions("as", "tags", positions);
131
-	ASSERT_EQ(1, positions[0]);
132
-	ASSERT_EQ(3, positions[1]);
133
-
134
-	PASS();
135
-}
136
-
137
-TEST test_positions_4() {
138
-	size_t positions[2];
139
-	match_positions("as", "examples.txt", positions);
140
-	ASSERT_EQ(2, positions[0]);
141
-	ASSERT_EQ(7, positions[1]);
142
-
143
-	PASS();
144
-}
145
-
146
-TEST test_positions_5() {
147
-	size_t positions[3];
148
-	match_positions("abc", "a/a/b/c/c", positions);
149
-	ASSERT_EQ(2, positions[0]);
150
-	ASSERT_EQ(4, positions[1]);
151
-	ASSERT_EQ(6, positions[2]);
152
-
153
-	PASS();
154
-}
155
-
156
-TEST test_positions_exact() {
157
-	size_t positions[3];
158
-	match_positions("foo", "foo", positions);
159
-	ASSERT_EQ(0, positions[0]);
160
-	ASSERT_EQ(1, positions[1]);
161
-	ASSERT_EQ(2, positions[2]);
162
-
163
-	PASS();
164
-}
165
-
166
-TEST test_choices_empty() {
167
-	choices_t choices;
168
-	choices_init(&choices, &default_options);
169
-	ASSERT_EQ(0, choices.size);
170
-	ASSERT_EQ(0, choices.available);
171
-	ASSERT_EQ(0, choices.selection);
172
-
173
-	choices_prev(&choices);
174
-	ASSERT_EQ(0, choices.selection);
175
-
176
-	choices_next(&choices);
177
-	ASSERT_EQ(0, choices.selection);
178
-
179
-	choices_destroy(&choices);
180
-
181
-	PASS();
182
-}
183
-
184
-TEST test_choices_1() {
185
-	choices_t choices;
186
-	choices_init(&choices, &default_options);
187
-	choices_add(&choices, "tags");
188
-
189
-	choices_search(&choices, "");
190
-	ASSERT_EQ(1, choices.available);
191
-	ASSERT_EQ(0, choices.selection);
192
-
193
-	choices_search(&choices, "t");
194
-	ASSERT_EQ(1, choices.available);
195
-	ASSERT_EQ(0, choices.selection);
196
-
197
-	choices_prev(&choices);
198
-	ASSERT_EQ(0, choices.selection);
199
-
200
-	choices_next(&choices);
201
-	ASSERT_EQ(0, choices.selection);
202
-
203
-	ASSERT(!strcmp(choices_get(&choices, 0), "tags"));
204
-	ASSERT_EQ(NULL, choices_get(&choices, 1));
205
-
206
-	choices_destroy(&choices);
207
-
208
-	PASS();
209
-}
210
-
211
-TEST test_choices_2() {
212
-	choices_t choices;
213
-	choices_init(&choices, &default_options);
214
-	choices_add(&choices, "tags");
215
-	choices_add(&choices, "test");
216
-
217
-	/* Empty search */
218
-	choices_search(&choices, "");
219
-	ASSERT_EQ(0, choices.selection);
220
-	ASSERT_EQ(2, choices.available);
221
-
222
-	choices_next(&choices);
223
-	ASSERT_EQ(1, choices.selection);
224
-	choices_next(&choices);
225
-	ASSERT_EQ(0, choices.selection);
226
-
227
-	choices_prev(&choices);
228
-	ASSERT_EQ(1, choices.selection);
229
-	choices_prev(&choices);
230
-	ASSERT_EQ(0, choices.selection);
231
-
232
-	/* Filtered search */
233
-	choices_search(&choices, "te");
234
-	ASSERT_EQ(1, choices.available);
235
-	ASSERT_EQ(0, choices.selection);
236
-	ASSERT_STR_EQ("test", choices_get(&choices, 0));
237
-
238
-	choices_next(&choices);
239
-	ASSERT_EQ(0, choices.selection);
240
-
241
-	choices_prev(&choices);
242
-	ASSERT_EQ(0, choices.selection);
243
-
244
-	/* No results */
245
-	choices_search(&choices, "foobar");
246
-	ASSERT_EQ(0, choices.available);
247
-	ASSERT_EQ(0, choices.selection);
248
-
249
-	/* Different order due to scoring */
250
-	choices_search(&choices, "ts");
251
-	ASSERT_EQ(2, choices.available);
252
-	ASSERT_EQ(0, choices.selection);
253
-	ASSERT_STR_EQ("test", choices_get(&choices, 0));
254
-	ASSERT_STR_EQ("tags", choices_get(&choices, 1));
255
-
256
-	choices_destroy(&choices);
257
-
258
-	PASS();
259
-}
260
-
261
-TEST test_choices_without_search() {
262
-	/* Before a search is run, it should return no results */
263
-
264
-	choices_t choices;
265
-	choices_init(&choices, &default_options);
266
-
267
-	ASSERT_EQ(0, choices.available);
268
-	ASSERT_EQ(0, choices.selection);
269
-	ASSERT_EQ(0, choices.size);
270
-	ASSERT_EQ(NULL, choices_get(&choices, 0));
271
-
272
-	choices_add(&choices, "test");
273
-
274
-	ASSERT_EQ(0, choices.available);
275
-	ASSERT_EQ(0, choices.selection);
276
-	ASSERT_EQ(1, choices.size);
277
-	ASSERT_EQ(NULL, choices_get(&choices, 0));
278
-
279
-	choices_destroy(&choices);
280
-
281
-	PASS();
282
-}
283
-
284
-/* Regression test for segfault */
285
-TEST test_choices_unicode() {
286
-	choices_t choices;
287
-	choices_init(&choices, &default_options);
288
-
289
-	choices_add(&choices, "Edmund Husserl - Méditations cartésiennes - Introduction a la phénoménologie.pdf");
290
-	choices_search(&choices, "e");
291
-
292
-	choices_destroy(&choices);
293
-	PASS();
294
-}
295
-
296
-TEST test_choices_large_input() {
297
-	choices_t choices;
298
-	choices_init(&choices, &default_options);
299
-
300
-	int N = 100000;
301
-	char *strings[N];
302
-
303
-	for(int i = 0; i < N; i++) {
304
-		asprintf(&strings[i], "%i", i);
305
-		choices_add(&choices, strings[i]);
306
-	}
307
-
308
-	choices_search(&choices, "12");
309
-
310
-	/* Must match `seq 0 99999 | grep '.*1.*2.*' | wc -l` */
311
-	ASSERT_EQ(8146, choices.available);
312
-
313
-	ASSERT_STR_EQ("12", choices_get(&choices, 0));
314
-
315
-	for(int i = 0; i < N; i++) {
316
-		free(strings[i]);
317
-	}
318
-
319
-	choices_destroy(&choices);
320
-
321
-	PASS();
322
-}
323
-
324
-SUITE(properties);
3
+SUITE(match_suite);
4
+SUITE(choices_suite);
5
+SUITE(properties_suite);
325 6
 
326 7
 GREATEST_MAIN_DEFS();
327 8
 
328 9
 int main(int argc, char *argv[]) {
329 10
 	GREATEST_MAIN_BEGIN();
330 11
 
331
-	options_init(&default_options);
332
-
333
-	RUN_TEST(test_match);
334
-	RUN_TEST(test_relative_scores);
335
-	RUN_TEST(test_exact_scores);
336
-	RUN_TEST(test_positions_1);
337
-	RUN_TEST(test_positions_2);
338
-	RUN_TEST(test_positions_3);
339
-	RUN_TEST(test_positions_4);
340
-	RUN_TEST(test_positions_5);
341
-	RUN_TEST(test_positions_exact);
342
-
343
-	RUN_TEST(test_choices_empty);
344
-	RUN_TEST(test_choices_1);
345
-	RUN_TEST(test_choices_2);
346
-	RUN_TEST(test_choices_without_search);
347
-	RUN_TEST(test_choices_unicode);
348
-	RUN_TEST(test_choices_large_input);
349
-
350
-	RUN_SUITE(properties);
12
+	RUN_SUITE(match_suite);
13
+	RUN_SUITE(choices_suite);
14
+	RUN_SUITE(properties_suite);
351 15
 
352 16
 	GREATEST_MAIN_END();
353 17
 }
Browse code

Add property based testing using thief

John Hawthorn authored on 04/04/2017 02:03:47
Showing 1 changed files
... ...
@@ -321,6 +321,8 @@ TEST test_choices_large_input() {
321 321
 	PASS();
322 322
 }
323 323
 
324
+SUITE(properties);
325
+
324 326
 GREATEST_MAIN_DEFS();
325 327
 
326 328
 int main(int argc, char *argv[]) {
... ...
@@ -345,5 +347,7 @@ int main(int argc, char *argv[]) {
345 347
 	RUN_TEST(test_choices_unicode);
346 348
 	RUN_TEST(test_choices_large_input);
347 349
 
350
+	RUN_SUITE(properties);
351
+
348 352
 	GREATEST_MAIN_END();
349 353
 }
Browse code

Use ASSERT_EQ where applicable

John Hawthorn authored on 03/04/2017 08:02:09
Showing 1 changed files
... ...
@@ -62,41 +62,41 @@ TEST test_relative_scores() {
62 62
 
63 63
 TEST test_exact_scores() {
64 64
 	/* Exact match is SCORE_MAX */
65
-	ASSERT(match("abc", "abc") == SCORE_MAX);
66
-	ASSERT(match("aBc", "abC") == SCORE_MAX);
65
+	ASSERT_EQ(SCORE_MAX, match("abc", "abc"));
66
+	ASSERT_EQ(SCORE_MAX, match("aBc", "abC"));
67 67
 
68 68
 	/* Empty query always results in SCORE_MIN */
69
-	ASSERT(match("", "") == SCORE_MIN);
70
-	ASSERT(match("", "a") == SCORE_MIN);
71
-	ASSERT(match("", "bb") == SCORE_MIN);
69
+	ASSERT_EQ(SCORE_MIN, match("", ""));
70
+	ASSERT_EQ(SCORE_MIN, match("", "a"));
71
+	ASSERT_EQ(SCORE_MIN, match("", "bb"));
72 72
 
73 73
 	/* Gaps */
74
-	ASSERT(match("a", "*a") == SCORE_GAP_LEADING);
75
-	ASSERT(match("a", "*ba") == SCORE_GAP_LEADING*2);
76
-	ASSERT(match("a", "**a*") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING);
77
-	ASSERT(match("a", "**a**") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2);
78
-	ASSERT(match("aa", "**aa**") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2);
79
-	ASSERT(match("aa", "**a*a**") == SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING);
74
+	ASSERT_EQ(SCORE_GAP_LEADING, match("a", "*a"));
75
+	ASSERT_EQ(SCORE_GAP_LEADING*2, match("a", "*ba"));
76
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING, match("a", "**a*"));
77
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2, match("a", "**a**"));
78
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2, match("aa", "**aa**"));
79
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING, match("aa", "**a*a**"));
80 80
 
81 81
 	/* Consecutive */
82
-	ASSERT(match("aa", "*aa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE);
83
-	ASSERT(match("aaa", "*aaa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2);
84
-	ASSERT(match("aaa", "*a*aa") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE);
82
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE, match("aa", "*aa"));
83
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2, match("aaa", "*aaa"));
84
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE, match("aaa", "*a*aa"));
85 85
 
86 86
 	/* Slash */
87
-	ASSERT(match("a", "/a") == SCORE_GAP_LEADING + SCORE_MATCH_SLASH);
88
-	ASSERT(match("a", "*/a") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH);
89
-	ASSERT(match("aa", "a/aa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE);
87
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_SLASH, match("a", "/a"));
88
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH, match("a", "*/a"));
89
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE, match("aa", "a/aa"));
90 90
 
91 91
 	/* Capital */
92
-	ASSERT(match("a", "bA") == SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL);
93
-	ASSERT(match("a", "baA") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL);
94
-	ASSERT(match("aa", "baAa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE);
92
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL, match("a", "bA"));
93
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL, match("a", "baA"));
94
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE, match("aa", "baAa"));
95 95
 
96 96
 	/* Dot */
97
-	ASSERT(match("a", ".a") == SCORE_GAP_LEADING + SCORE_MATCH_DOT);
98
-	ASSERT(match("a", "*a.a") == SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT);
99
-	ASSERT(match("a", "*a.a") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT);
97
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_DOT, match("a", ".a"));
98
+	ASSERT_EQ(SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT, match("a", "*a.a"));
99
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT, match("a", "*a.a"));
100 100
 
101 101
 	PASS();
102 102
 }
... ...
@@ -104,9 +104,9 @@ TEST test_exact_scores() {
104 104
 TEST test_positions_1() {
105 105
 	size_t positions[3];
106 106
 	match_positions("amo", "app/models/foo", positions);
107
-	ASSERT(positions[0] == 0);
108
-	ASSERT(positions[1] == 4);
109
-	ASSERT(positions[2] == 5);
107
+	ASSERT_EQ(0, positions[0]);
108
+	ASSERT_EQ(4, positions[1]);
109
+	ASSERT_EQ(5, positions[2]);
110 110
 
111 111
 	PASS();
112 112
 }
... ...
@@ -118,9 +118,9 @@ TEST test_positions_2() {
118 118
 	 */
119 119
 	size_t positions[4];
120 120
 	match_positions("amor", "app/models/order", positions);
121
-	ASSERT(positions[0] == 0);
122
-	ASSERT(positions[1] == 4);
123
-	ASSERT(positions[2] == 11);
121
+	ASSERT_EQ(0, positions[0]);
122
+	ASSERT_EQ(4, positions[1]);
123
+	ASSERT_EQ(11, positions[2]);
124 124
 
125 125
 	PASS();
126 126
 }
... ...
@@ -128,8 +128,8 @@ TEST test_positions_2() {
128 128
 TEST test_positions_3() {
129 129
 	size_t positions[2];
130 130
 	match_positions("as", "tags", positions);
131
-	ASSERT(positions[0] == 1);
132
-	ASSERT(positions[1] == 3);
131
+	ASSERT_EQ(1, positions[0]);
132
+	ASSERT_EQ(3, positions[1]);
133 133
 
134 134
 	PASS();
135 135
 }
... ...
@@ -137,8 +137,8 @@ TEST test_positions_3() {
137 137
 TEST test_positions_4() {
138 138
 	size_t positions[2];
139 139
 	match_positions("as", "examples.txt", positions);
140
-	ASSERT(positions[0] == 2);
141
-	ASSERT(positions[1] == 7);
140
+	ASSERT_EQ(2, positions[0]);
141
+	ASSERT_EQ(7, positions[1]);
142 142
 
143 143
 	PASS();
144 144
 }
... ...
@@ -146,9 +146,9 @@ TEST test_positions_4() {
146 146
 TEST test_positions_5() {
147 147
 	size_t positions[3];
148 148
 	match_positions("abc", "a/a/b/c/c", positions);
149
-	ASSERT(positions[0] == 2);
150
-	ASSERT(positions[1] == 4);
151
-	ASSERT(positions[2] == 6);
149
+	ASSERT_EQ(2, positions[0]);
150
+	ASSERT_EQ(4, positions[1]);
151
+	ASSERT_EQ(6, positions[2]);
152 152
 
153 153
 	PASS();
154 154
 }
... ...
@@ -156,9 +156,9 @@ TEST test_positions_5() {
156 156
 TEST test_positions_exact() {
157 157
 	size_t positions[3];
158 158
 	match_positions("foo", "foo", positions);
159
-	ASSERT(positions[0] == 0);
160
-	ASSERT(positions[1] == 1);
161
-	ASSERT(positions[2] == 2);
159
+	ASSERT_EQ(0, positions[0]);
160
+	ASSERT_EQ(1, positions[1]);
161
+	ASSERT_EQ(2, positions[2]);
162 162
 
163 163
 	PASS();
164 164
 }
... ...
@@ -166,15 +166,15 @@ TEST test_positions_exact() {
166 166
 TEST test_choices_empty() {
167 167
 	choices_t choices;
168 168
 	choices_init(&choices, &default_options);
169
-	ASSERT(choices.size == 0);
170
-	ASSERT(choices.available == 0);
171
-	ASSERT(choices.selection == 0);
169
+	ASSERT_EQ(0, choices.size);
170
+	ASSERT_EQ(0, choices.available);
171
+	ASSERT_EQ(0, choices.selection);
172 172
 
173 173
 	choices_prev(&choices);
174
-	ASSERT(choices.selection == 0);
174
+	ASSERT_EQ(0, choices.selection);
175 175
 
176 176
 	choices_next(&choices);
177
-	ASSERT(choices.selection == 0);
177
+	ASSERT_EQ(0, choices.selection);
178 178
 
179 179
 	choices_destroy(&choices);
180 180
 
... ...
@@ -187,21 +187,21 @@ TEST test_choices_1() {
187 187
 	choices_add(&choices, "tags");
188 188
 
189 189
 	choices_search(&choices, "");
190
-	ASSERT(choices.available == 1);
191
-	ASSERT(choices.selection == 0);
190
+	ASSERT_EQ(1, choices.available);
191
+	ASSERT_EQ(0, choices.selection);
192 192
 
193 193
 	choices_search(&choices, "t");
194
-	ASSERT(choices.available == 1);
195
-	ASSERT(choices.selection == 0);
194
+	ASSERT_EQ(1, choices.available);
195
+	ASSERT_EQ(0, choices.selection);
196 196
 
197 197
 	choices_prev(&choices);
198
-	ASSERT(choices.selection == 0);
198
+	ASSERT_EQ(0, choices.selection);
199 199
 
200 200
 	choices_next(&choices);
201
-	ASSERT(choices.selection == 0);
201
+	ASSERT_EQ(0, choices.selection);
202 202
 
203 203
 	ASSERT(!strcmp(choices_get(&choices, 0), "tags"));
204
-	ASSERT(choices_get(&choices, 1) == NULL);
204
+	ASSERT_EQ(NULL, choices_get(&choices, 1));
205 205
 
206 206
 	choices_destroy(&choices);
207 207
 
... ...
@@ -216,40 +216,40 @@ TEST test_choices_2() {
216 216
 
217 217
 	/* Empty search */
218 218
 	choices_search(&choices, "");
219
-	ASSERT(choices.selection == 0);
220
-	ASSERT(choices.available == 2);
219
+	ASSERT_EQ(0, choices.selection);
220
+	ASSERT_EQ(2, choices.available);
221 221
 
222 222
 	choices_next(&choices);
223
-	ASSERT(choices.selection == 1);
223
+	ASSERT_EQ(1, choices.selection);
224 224
 	choices_next(&choices);
225
-	ASSERT(choices.selection == 0);
225
+	ASSERT_EQ(0, choices.selection);
226 226
 
227 227
 	choices_prev(&choices);
228
-	ASSERT(choices.selection == 1);
228
+	ASSERT_EQ(1, choices.selection);
229 229
 	choices_prev(&choices);
230
-	ASSERT(choices.selection == 0);
230
+	ASSERT_EQ(0, choices.selection);
231 231
 
232 232
 	/* Filtered search */
233 233
 	choices_search(&choices, "te");
234
-	ASSERT(choices.available == 1);
235
-	ASSERT(choices.selection == 0);
234
+	ASSERT_EQ(1, choices.available);
235
+	ASSERT_EQ(0, choices.selection);
236 236
 	ASSERT_STR_EQ("test", choices_get(&choices, 0));
237 237
 
238 238
 	choices_next(&choices);
239
-	ASSERT(choices.selection == 0);
239
+	ASSERT_EQ(0, choices.selection);
240 240
 
241 241
 	choices_prev(&choices);
242
-	ASSERT(choices.selection == 0);
242
+	ASSERT_EQ(0, choices.selection);
243 243
 
244 244
 	/* No results */
245 245
 	choices_search(&choices, "foobar");
246
-	ASSERT(choices.available == 0);
247
-	ASSERT(choices.selection == 0);
246
+	ASSERT_EQ(0, choices.available);
247
+	ASSERT_EQ(0, choices.selection);
248 248
 
249 249
 	/* Different order due to scoring */
250 250
 	choices_search(&choices, "ts");
251
-	ASSERT(choices.available == 2);
252
-	ASSERT(choices.selection == 0);
251
+	ASSERT_EQ(2, choices.available);
252
+	ASSERT_EQ(0, choices.selection);
253 253
 	ASSERT_STR_EQ("test", choices_get(&choices, 0));
254 254
 	ASSERT_STR_EQ("tags", choices_get(&choices, 1));
255 255
 
... ...
@@ -264,17 +264,17 @@ TEST test_choices_without_search() {
264 264
 	choices_t choices;
265 265
 	choices_init(&choices, &default_options);
266 266
 
267
-	ASSERT(choices.available == 0);
268
-	ASSERT(choices.selection == 0);
269
-	ASSERT(choices.size == 0);
270
-	ASSERT(choices_get(&choices, 0) == NULL);
267
+	ASSERT_EQ(0, choices.available);
268
+	ASSERT_EQ(0, choices.selection);
269
+	ASSERT_EQ(0, choices.size);
270
+	ASSERT_EQ(NULL, choices_get(&choices, 0));
271 271
 
272 272
 	choices_add(&choices, "test");
273 273
 
274
-	ASSERT(choices.available == 0);
275
-	ASSERT(choices.selection == 0);
276
-	ASSERT(choices.size == 1);
277
-	ASSERT(choices_get(&choices, 0) == NULL);
274
+	ASSERT_EQ(0, choices.available);
275
+	ASSERT_EQ(0, choices.selection);
276
+	ASSERT_EQ(1, choices.size);
277
+	ASSERT_EQ(NULL, choices_get(&choices, 0));
278 278
 
279 279
 	choices_destroy(&choices);
280 280
 
... ...
@@ -308,7 +308,7 @@ TEST test_choices_large_input() {
308 308
 	choices_search(&choices, "12");
309 309
 
310 310
 	/* Must match `seq 0 99999 | grep '.*1.*2.*' | wc -l` */
311
-	ASSERT(choices.available == 8146);
311
+	ASSERT_EQ(8146, choices.available);
312 312
 
313 313
 	ASSERT_STR_EQ("12", choices_get(&choices, 0));
314 314
 
Browse code

Correct argument order for ASSERT_STR_EQ

John Hawthorn authored on 03/04/2017 07:57:40
Showing 1 changed files
... ...
@@ -233,7 +233,7 @@ TEST test_choices_2() {
233 233
 	choices_search(&choices, "te");
234 234
 	ASSERT(choices.available == 1);
235 235
 	ASSERT(choices.selection == 0);
236
-	ASSERT_STR_EQ(choices_get(&choices, 0), "test");
236
+	ASSERT_STR_EQ("test", choices_get(&choices, 0));
237 237
 
238 238
 	choices_next(&choices);
239 239
 	ASSERT(choices.selection == 0);
... ...
@@ -250,8 +250,8 @@ TEST test_choices_2() {
250 250
 	choices_search(&choices, "ts");
251 251
 	ASSERT(choices.available == 2);
252 252
 	ASSERT(choices.selection == 0);
253
-	ASSERT_STR_EQ(choices_get(&choices, 0), "test");
254
-	ASSERT_STR_EQ(choices_get(&choices, 1), "tags");
253
+	ASSERT_STR_EQ("test", choices_get(&choices, 0));
254
+	ASSERT_STR_EQ("tags", choices_get(&choices, 1));
255 255
 
256 256
 	choices_destroy(&choices);
257 257
 
... ...
@@ -310,7 +310,7 @@ TEST test_choices_large_input() {
310 310
 	/* Must match `seq 0 99999 | grep '.*1.*2.*' | wc -l` */
311 311
 	ASSERT(choices.available == 8146);
312 312
 
313
-	ASSERT_STR_EQ(choices_get(&choices, 0), "12");
313
+	ASSERT_STR_EQ("12", choices_get(&choices, 0));
314 314
 
315 315
 	for(int i = 0; i < N; i++) {
316 316
 		free(strings[i]);
Browse code

Switch test framework to greatest

John Hawthorn authored on 03/04/2017 05:32:33
Showing 1 changed files
... ...
@@ -9,200 +9,206 @@
9 9
 #include "choices.h"
10 10
 #include "options.h"
11 11
 
12
-int testsrun = 0, testsfailed = 0, assertionsrun = 0;
13
-
14
-#define assert(x)                                                                                  \
15
-	if (++assertionsrun && !(x)) {                                                             \
16
-		fprintf(stderr, "test \"%s\" failed\n   assert(%s) was false\n   at %s:%i\n\n",    \
17
-			__func__, #x, __FILE__, __LINE__);                                         \
18
-		raise(SIGTRAP);                                                                    \
19
-		testsfailed++;                                                                     \
20
-		return;                                                                            \
21
-	}
22
-
23
-#define assert_streq(a, b) assert(!strcmp(a, b))
12
+#include "greatest/greatest.h"
24 13
 
25 14
 static options_t default_options;
26 15
 
27
-void runtest(void (*test)()) {
28
-	testsrun++;
29
-	test();
30
-}
31
-
32
-void test_match() {
33
-	assert(has_match("a", "a"));
34
-	assert(has_match("a", "ab"));
35
-	assert(has_match("a", "ba"));
36
-	assert(has_match("abc", "a|b|c"));
16
+TEST test_match() {
17
+	ASSERT(has_match("a", "a"));
18
+	ASSERT(has_match("a", "ab"));
19
+	ASSERT(has_match("a", "ba"));
20
+	ASSERT(has_match("abc", "a|b|c"));
37 21
 
38 22
 	/* non-match */
39
-	assert(!has_match("a", ""));
40
-	assert(!has_match("a", "b"));
41
-	assert(!has_match("ass", "tags"));
23
+	ASSERT(!has_match("a", ""));
24
+	ASSERT(!has_match("a", "b"));
25
+	ASSERT(!has_match("ass", "tags"));
42 26
 
43 27
 	/* match when query is empty */
44
-	assert(has_match("", ""));
45
-	assert(has_match("", "a"));
28
+	ASSERT(has_match("", ""));
29
+	ASSERT(has_match("", "a"));
30
+
31
+	PASS();
46 32
 }
47 33
 
48
-void test_relative_scores() {
34
+TEST test_relative_scores() {
49 35
 	/* App/Models/Order is better than App/MOdels/zRder  */
50
-	assert(match("amor", "app/models/order") > match("amor", "app/models/zrder"));
36
+	ASSERT(match("amor", "app/models/order") > match("amor", "app/models/zrder"));
51 37
 
52 38
 	/* App/MOdels/foo is better than App/M/fOo  */
53
-	assert(match("amo", "app/m/foo") < match("amo", "app/models/foo"));
39
+	ASSERT(match("amo", "app/m/foo") < match("amo", "app/models/foo"));
54 40
 
55 41
 	/* GEMFIle.Lock < GEMFILe  */
56
-	assert(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
42
+	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
57 43
 
58 44
 	/* GEMFIle.Lock < GEMFILe  */
59
-	assert(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
45
+	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
60 46
 
61 47
 	/* Prefer shorter matches */
62
-	assert(match("abce", "abcdef") > match("abce", "abc de"));
48
+	ASSERT(match("abce", "abcdef") > match("abce", "abc de"));
63 49
 
64 50
 	/* Prefer shorter candidates */
65
-	assert(match("test", "tests") > match("test", "testing"));
51
+	ASSERT(match("test", "tests") > match("test", "testing"));
66 52
 
67 53
 	/* Scores first letter highly */
68
-	assert(match("test", "testing") > match("test", "/testing"));
54
+	ASSERT(match("test", "testing") > match("test", "/testing"));
69 55
 
70 56
 	/* Prefer shorter matches */
71
-	assert(match("abc", "    a b c ") > match("abc", " a  b  c "));
72
-	assert(match("abc", " a b c    ") > match("abc", " a  b  c "));
57
+	ASSERT(match("abc", "    a b c ") > match("abc", " a  b  c "));
58
+	ASSERT(match("abc", " a b c    ") > match("abc", " a  b  c "));
59
+
60
+	PASS();
73 61
 }
74 62
 
75
-void test_exact_scores() {
63
+TEST test_exact_scores() {
76 64
 	/* Exact match is SCORE_MAX */
77
-	assert(match("abc", "abc") == SCORE_MAX);
78
-	assert(match("aBc", "abC") == SCORE_MAX);
65
+	ASSERT(match("abc", "abc") == SCORE_MAX);
66
+	ASSERT(match("aBc", "abC") == SCORE_MAX);
79 67
 
80 68
 	/* Empty query always results in SCORE_MIN */
81
-	assert(match("", "") == SCORE_MIN);
82
-	assert(match("", "a") == SCORE_MIN);
83
-	assert(match("", "bb") == SCORE_MIN);
69
+	ASSERT(match("", "") == SCORE_MIN);
70
+	ASSERT(match("", "a") == SCORE_MIN);
71
+	ASSERT(match("", "bb") == SCORE_MIN);
84 72
 
85 73
 	/* Gaps */
86
-	assert(match("a", "*a") == SCORE_GAP_LEADING);
87
-	assert(match("a", "*ba") == SCORE_GAP_LEADING*2);
88
-	assert(match("a", "**a*") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING);
89
-	assert(match("a", "**a**") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2);
90
-	assert(match("aa", "**aa**") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2);
91
-	assert(match("aa", "**a*a**") == SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING);
74
+	ASSERT(match("a", "*a") == SCORE_GAP_LEADING);
75
+	ASSERT(match("a", "*ba") == SCORE_GAP_LEADING*2);
76
+	ASSERT(match("a", "**a*") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING);
77
+	ASSERT(match("a", "**a**") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2);
78
+	ASSERT(match("aa", "**aa**") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2);
79
+	ASSERT(match("aa", "**a*a**") == SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING);
92 80
 
93 81
 	/* Consecutive */
94
-	assert(match("aa", "*aa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE);
95
-	assert(match("aaa", "*aaa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2);
96
-	assert(match("aaa", "*a*aa") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE);
82
+	ASSERT(match("aa", "*aa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE);
83
+	ASSERT(match("aaa", "*aaa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2);
84
+	ASSERT(match("aaa", "*a*aa") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE);
97 85
 
98 86
 	/* Slash */
99
-	assert(match("a", "/a") == SCORE_GAP_LEADING + SCORE_MATCH_SLASH);
100
-	assert(match("a", "*/a") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH);
101
-	assert(match("aa", "a/aa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE);
87
+	ASSERT(match("a", "/a") == SCORE_GAP_LEADING + SCORE_MATCH_SLASH);
88
+	ASSERT(match("a", "*/a") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH);
89
+	ASSERT(match("aa", "a/aa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE);
102 90
 
103 91
 	/* Capital */
104
-	assert(match("a", "bA") == SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL);
105
-	assert(match("a", "baA") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL);
106
-	assert(match("aa", "baAa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE);
92
+	ASSERT(match("a", "bA") == SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL);
93
+	ASSERT(match("a", "baA") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL);
94
+	ASSERT(match("aa", "baAa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE);
107 95
 
108 96
 	/* Dot */
109
-	assert(match("a", ".a") == SCORE_GAP_LEADING + SCORE_MATCH_DOT);
110
-	assert(match("a", "*a.a") == SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT);
111
-	assert(match("a", "*a.a") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT);
97
+	ASSERT(match("a", ".a") == SCORE_GAP_LEADING + SCORE_MATCH_DOT);
98
+	ASSERT(match("a", "*a.a") == SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT);
99
+	ASSERT(match("a", "*a.a") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT);
100
+
101
+	PASS();
112 102
 }
113 103
 
114
-void test_positions_1() {
104
+TEST test_positions_1() {
115 105
 	size_t positions[3];
116 106
 	match_positions("amo", "app/models/foo", positions);
117
-	assert(positions[0] == 0);
118
-	assert(positions[1] == 4);
119
-	assert(positions[2] == 5);
107
+	ASSERT(positions[0] == 0);
108
+	ASSERT(positions[1] == 4);
109
+	ASSERT(positions[2] == 5);
110
+
111
+	PASS();
120 112
 }
121 113
 
122
-void test_positions_2() {
114
+TEST test_positions_2() {
123 115
 	/*
124 116
 	 * We should prefer matching the 'o' in order, since it's the beginning
125 117
 	 * of a word.
126 118
 	 */
127 119
 	size_t positions[4];
128 120
 	match_positions("amor", "app/models/order", positions);
129
-	assert(positions[0] == 0);
130
-	assert(positions[1] == 4);
131
-	assert(positions[2] == 11);
121
+	ASSERT(positions[0] == 0);
122
+	ASSERT(positions[1] == 4);
123
+	ASSERT(positions[2] == 11);
124
+
125
+	PASS();
132 126
 }
133 127
 
134
-void test_positions_3() {
128
+TEST test_positions_3() {
135 129
 	size_t positions[2];
136 130
 	match_positions("as", "tags", positions);
137
-	assert(positions[0] == 1);
138
-	assert(positions[1] == 3);
131
+	ASSERT(positions[0] == 1);
132
+	ASSERT(positions[1] == 3);
133
+
134
+	PASS();
139 135
 }
140 136
 
141
-void test_positions_4() {
137
+TEST test_positions_4() {
142 138
 	size_t positions[2];
143 139
 	match_positions("as", "examples.txt", positions);
144
-	assert(positions[0] == 2);
145
-	assert(positions[1] == 7);
140
+	ASSERT(positions[0] == 2);
141
+	ASSERT(positions[1] == 7);
142
+
143
+	PASS();
146 144
 }
147 145
 
148
-void test_positions_5() {
146
+TEST test_positions_5() {
149 147
 	size_t positions[3];
150 148
 	match_positions("abc", "a/a/b/c/c", positions);
151
-	assert(positions[0] == 2);
152
-	assert(positions[1] == 4);
153
-	assert(positions[2] == 6);
149
+	ASSERT(positions[0] == 2);
150
+	ASSERT(positions[1] == 4);
151
+	ASSERT(positions[2] == 6);
152
+
153
+	PASS();
154 154
 }
155 155
 
156
-void test_positions_exact() {
156
+TEST test_positions_exact() {
157 157
 	size_t positions[3];
158 158
 	match_positions("foo", "foo", positions);
159
-	assert(positions[0] == 0);
160
-	assert(positions[1] == 1);
161
-	assert(positions[2] == 2);
159
+	ASSERT(positions[0] == 0);
160
+	ASSERT(positions[1] == 1);
161
+	ASSERT(positions[2] == 2);
162
+
163
+	PASS();
162 164
 }
163 165
 
164
-void test_choices_empty() {
166
+TEST test_choices_empty() {
165 167
 	choices_t choices;
166 168
 	choices_init(&choices, &default_options);
167
-	assert(choices.size == 0);
168
-	assert(choices.available == 0);
169
-	assert(choices.selection == 0);
169
+	ASSERT(choices.size == 0);
170
+	ASSERT(choices.available == 0);
171
+	ASSERT(choices.selection == 0);
170 172
 
171 173
 	choices_prev(&choices);
172
-	assert(choices.selection == 0);
174
+	ASSERT(choices.selection == 0);
173 175
 
174 176
 	choices_next(&choices);
175
-	assert(choices.selection == 0);
177
+	ASSERT(choices.selection == 0);
176 178
 
177 179
 	choices_destroy(&choices);
180
+
181
+	PASS();
178 182
 }
179 183
 
180
-void test_choices_1() {
184
+TEST test_choices_1() {
181 185
 	choices_t choices;
182 186
 	choices_init(&choices, &default_options);
183 187
 	choices_add(&choices, "tags");
184 188
 
185 189
 	choices_search(&choices, "");
186
-	assert(choices.available == 1);
187
-	assert(choices.selection == 0);
190
+	ASSERT(choices.available == 1);
191
+	ASSERT(choices.selection == 0);
188 192
 
189 193
 	choices_search(&choices, "t");
190
-	assert(choices.available == 1);
191
-	assert(choices.selection == 0);
194
+	ASSERT(choices.available == 1);
195
+	ASSERT(choices.selection == 0);
192 196
 
193 197
 	choices_prev(&choices);
194
-	assert(choices.selection == 0);
198
+	ASSERT(choices.selection == 0);
195 199
 
196 200
 	choices_next(&choices);
197
-	assert(choices.selection == 0);
201
+	ASSERT(choices.selection == 0);
198 202
 
199
-	assert(!strcmp(choices_get(&choices, 0), "tags"));
200
-	assert(choices_get(&choices, 1) == NULL);
203
+	ASSERT(!strcmp(choices_get(&choices, 0), "tags"));
204
+	ASSERT(choices_get(&choices, 1) == NULL);
201 205
 
202 206
 	choices_destroy(&choices);
207
+
208
+	PASS();
203 209
 }
204 210
 
205
-void test_choices_2() {
211
+TEST test_choices_2() {
206 212
 	choices_t choices;
207 213
 	choices_init(&choices, &default_options);
208 214
 	choices_add(&choices, "tags");
... ...
@@ -210,71 +216,73 @@ void test_choices_2() {
210 216
 
211 217
 	/* Empty search */
212 218
 	choices_search(&choices, "");
213
-	assert(choices.selection == 0);
214
-	assert(choices.available == 2);
215
-	assert_streq(choices_get(&choices, 0), "tags");
216
-	assert_streq(choices_get(&choices, 1), "test");
219
+	ASSERT(choices.selection == 0);
220
+	ASSERT(choices.available == 2);
217 221
 
218 222
 	choices_next(&choices);
219
-	assert(choices.selection == 1);
223
+	ASSERT(choices.selection == 1);
220 224
 	choices_next(&choices);
221
-	assert(choices.selection == 0);
225
+	ASSERT(choices.selection == 0);
222 226
 
223 227
 	choices_prev(&choices);
224
-	assert(choices.selection == 1);
228
+	ASSERT(choices.selection == 1);
225 229
 	choices_prev(&choices);
226
-	assert(choices.selection == 0);
230
+	ASSERT(choices.selection == 0);
227 231
 
228 232
 	/* Filtered search */
229 233
 	choices_search(&choices, "te");
230
-	assert(choices.available == 1);
231
-	assert(choices.selection == 0);
232
-	assert_streq(choices_get(&choices, 0), "test");
234
+	ASSERT(choices.available == 1);
235
+	ASSERT(choices.selection == 0);
236
+	ASSERT_STR_EQ(choices_get(&choices, 0), "test");
233 237
 
234 238
 	choices_next(&choices);
235
-	assert(choices.selection == 0);
239
+	ASSERT(choices.selection == 0);
236 240
 
237 241
 	choices_prev(&choices);
238
-	assert(choices.selection == 0);
242
+	ASSERT(choices.selection == 0);
239 243
 
240 244
 	/* No results */
241 245
 	choices_search(&choices, "foobar");
242
-	assert(choices.available == 0);
243
-	assert(choices.selection == 0);
246
+	ASSERT(choices.available == 0);
247
+	ASSERT(choices.selection == 0);
244 248
 
245 249
 	/* Different order due to scoring */
246 250
 	choices_search(&choices, "ts");
247
-	assert(choices.available == 2);
248
-	assert(choices.selection == 0);
249
-	assert_streq(choices_get(&choices, 0), "test");
250
-	assert_streq(choices_get(&choices, 1), "tags");
251
+	ASSERT(choices.available == 2);
252
+	ASSERT(choices.selection == 0);
253
+	ASSERT_STR_EQ(choices_get(&choices, 0), "test");
254
+	ASSERT_STR_EQ(choices_get(&choices, 1), "tags");
251 255
 
252 256
 	choices_destroy(&choices);
257
+
258
+	PASS();
253 259
 }
254 260
 
255
-void test_choices_without_search() {
261
+TEST test_choices_without_search() {
256 262
 	/* Before a search is run, it should return no results */
257 263
 
258 264
 	choices_t choices;
259 265
 	choices_init(&choices, &default_options);
260 266
 
261
-	assert(choices.available == 0);
262
-	assert(choices.selection == 0);
263
-	assert(choices.size == 0);
264
-	assert(choices_get(&choices, 0) == NULL);
267
+	ASSERT(choices.available == 0);
268
+	ASSERT(choices.selection == 0);
269
+	ASSERT(choices.size == 0);
270
+	ASSERT(choices_get(&choices, 0) == NULL);
265 271
 
266 272
 	choices_add(&choices, "test");
267 273
 
268
-	assert(choices.available == 0);
269
-	assert(choices.selection == 0);
270
-	assert(choices.size == 1);
271
-	assert(choices_get(&choices, 0) == NULL);
274
+	ASSERT(choices.available == 0);
275
+	ASSERT(choices.selection == 0);
276
+	ASSERT(choices.size == 1);
277
+	ASSERT(choices_get(&choices, 0) == NULL);
272 278
 
273 279
 	choices_destroy(&choices);
280
+
281
+	PASS();
274 282
 }
275 283
 
276 284
 /* Regression test for segfault */
277
-void test_choices_unicode() {
285
+TEST test_choices_unicode() {
278 286
 	choices_t choices;
279 287
 	choices_init(&choices, &default_options);
280 288
 
... ...
@@ -282,9 +290,10 @@ void test_choices_unicode() {
282 290
 	choices_search(&choices, "e");
283 291
 
284 292
 	choices_destroy(&choices);
293
+	PASS();
285 294
 }
286 295
 
287
-void test_choices_large_input() {
296
+TEST test_choices_large_input() {
288 297
 	choices_t choices;
289 298
 	choices_init(&choices, &default_options);
290 299
 
... ...
@@ -299,54 +308,42 @@ void test_choices_large_input() {
299 308
 	choices_search(&choices, "12");
300 309
 
301 310
 	/* Must match `seq 0 99999 | grep '.*1.*2.*' | wc -l` */
302
-	assert(choices.available == 8146);
311
+	ASSERT(choices.available == 8146);
303 312
 
304
-	assert_streq(choices_get(&choices, 0), "12")
313
+	ASSERT_STR_EQ(choices_get(&choices, 0), "12");
305 314
 
306 315
 	for(int i = 0; i < N; i++) {
307 316
 		free(strings[i]);
308 317
 	}
309 318
 
310 319
 	choices_destroy(&choices);
311
-}
312 320
 
313
-void summary() {
314
-	printf("%i tests, %i assertions, %i failures\n", testsrun, assertionsrun, testsfailed);
321
+	PASS();
315 322
 }
316 323
 
317
-static void ignore_signal(int signum) {
318
-	(void)signum;
319
-}
324
+GREATEST_MAIN_DEFS();
320 325
 
321 326
 int main(int argc, char *argv[]) {
322
-	(void)argc;
323
-	(void)argv;
324
-
325
-	/* We raise sigtrap on all assertion failures.
326
-	 * If we have no debugger running, we should ignore it */
327
-	signal(SIGTRAP, ignore_signal);
327
+	GREATEST_MAIN_BEGIN();
328 328
 
329 329
 	options_init(&default_options);
330 330
 
331
-	runtest(test_match);
332
-	runtest(test_relative_scores);
333
-	runtest(test_exact_scores);
334
-	runtest(test_positions_1);
335
-	runtest(test_positions_2);
336
-	runtest(test_positions_3);
337
-	runtest(test_positions_4);
338
-	runtest(test_positions_5);
339
-	runtest(test_positions_exact);
340
-
341
-	runtest(test_choices_empty);
342
-	runtest(test_choices_1);
343
-	runtest(test_choices_2);
344
-	runtest(test_choices_without_search);
345
-	runtest(test_choices_unicode);
346
-	runtest(test_choices_large_input);
347
-
348
-	summary();
349
-
350
-	/* exit 0 if all tests pass */
351
-	return !!testsfailed;
331
+	RUN_TEST(test_match);
332
+	RUN_TEST(test_relative_scores);
333
+	RUN_TEST(test_exact_scores);
334
+	RUN_TEST(test_positions_1);
335
+	RUN_TEST(test_positions_2);
336
+	RUN_TEST(test_positions_3);
337
+	RUN_TEST(test_positions_4);
338
+	RUN_TEST(test_positions_5);
339
+	RUN_TEST(test_positions_exact);
340
+
341
+	RUN_TEST(test_choices_empty);
342
+	RUN_TEST(test_choices_1);
343
+	RUN_TEST(test_choices_2);
344
+	RUN_TEST(test_choices_without_search);
345
+	RUN_TEST(test_choices_unicode);
346
+	RUN_TEST(test_choices_large_input);
347
+
348
+	GREATEST_MAIN_END();
352 349
 }
Browse code

Pass options to choices_init

John Hawthorn authored on 01/02/2017 02:06:42
Showing 1 changed files
... ...
@@ -7,6 +7,7 @@
7 7
 #include "../config.h"
8 8
 #include "match.h"
9 9
 #include "choices.h"
10
+#include "options.h"
10 11
 
11 12
 int testsrun = 0, testsfailed = 0, assertionsrun = 0;
12 13
 
... ...
@@ -21,6 +22,8 @@ int testsrun = 0, testsfailed = 0, assertionsrun = 0;
21 22
 
22 23
 #define assert_streq(a, b) assert(!strcmp(a, b))
23 24
 
25
+static options_t default_options;
26
+
24 27
 void runtest(void (*test)()) {
25 28
 	testsrun++;
26 29
 	test();
... ...
@@ -160,7 +163,7 @@ void test_positions_exact() {
160 163
 
161 164
 void test_choices_empty() {
162 165
 	choices_t choices;
163
-	choices_init(&choices);
166
+	choices_init(&choices, &default_options);
164 167
 	assert(choices.size == 0);
165 168
 	assert(choices.available == 0);
166 169
 	assert(choices.selection == 0);
... ...
@@ -176,7 +179,7 @@ void test_choices_empty() {
176 179
 
177 180
 void test_choices_1() {
178 181
 	choices_t choices;
179
-	choices_init(&choices);
182
+	choices_init(&choices, &default_options);
180 183
 	choices_add(&choices, "tags");
181 184
 
182 185
 	choices_search(&choices, "");
... ...
@@ -201,7 +204,7 @@ void test_choices_1() {
201 204
 
202 205
 void test_choices_2() {
203 206
 	choices_t choices;
204
-	choices_init(&choices);
207
+	choices_init(&choices, &default_options);
205 208
 	choices_add(&choices, "tags");
206 209
 	choices_add(&choices, "test");
207 210
 
... ...
@@ -253,7 +256,7 @@ void test_choices_without_search() {
253 256
 	/* Before a search is run, it should return no results */
254 257
 
255 258
 	choices_t choices;
256
-	choices_init(&choices);
259
+	choices_init(&choices, &default_options);
257 260
 
258 261
 	assert(choices.available == 0);
259 262
 	assert(choices.selection == 0);
... ...
@@ -273,7 +276,7 @@ void test_choices_without_search() {
273 276
 /* Regression test for segfault */
274 277
 void test_choices_unicode() {
275 278
 	choices_t choices;
276
-	choices_init(&choices);
279
+	choices_init(&choices, &default_options);
277 280
 
278 281
 	choices_add(&choices, "Edmund Husserl - Méditations cartésiennes - Introduction a la phénoménologie.pdf");
279 282
 	choices_search(&choices, "e");
... ...
@@ -283,7 +286,7 @@ void test_choices_unicode() {
283 286
 
284 287
 void test_choices_large_input() {
285 288
 	choices_t choices;
286
-	choices_init(&choices);
289
+	choices_init(&choices, &default_options);
287 290
 
288 291
 	int N = 100000;
289 292
 	char *strings[N];
... ...
@@ -323,6 +326,8 @@ int main(int argc, char *argv[]) {
323 326
 	 * If we have no debugger running, we should ignore it */
324 327
 	signal(SIGTRAP, ignore_signal);
325 328
 
329
+	options_init(&default_options);
330
+
326 331
 	runtest(test_match);
327 332
 	runtest(test_relative_scores);
328 333
 	runtest(test_exact_scores);
Browse code

Fix tests on OS X

John Hawthorn authored on 27/01/2017 08:34:07
Showing 1 changed files
... ...
@@ -1,5 +1,5 @@
1 1
 #define _GNU_SOURCE
2
-#include <malloc.h>
2
+#include <stdlib.h>
3 3
 #include <signal.h>
4 4
 #include <stdio.h>
5 5
 #include <string.h>
Browse code

Add test for large input

John Hawthorn authored on 18/01/2017 02:15:47
Showing 1 changed files
... ...
@@ -1,6 +1,8 @@
1
+#define _GNU_SOURCE
2
+#include <malloc.h>
3
+#include <signal.h>
1 4
 #include <stdio.h>
2 5
 #include <string.h>
3
-#include <signal.h>
4 6
 
5 7
 #include "../config.h"
6 8
 #include "match.h"
... ...
@@ -279,6 +281,32 @@ void test_choices_unicode() {
279 281
 	choices_destroy(&choices);
280 282
 }
281 283
 
284
+void test_choices_large_input() {
285
+	choices_t choices;
286
+	choices_init(&choices);
287
+
288
+	int N = 100000;
289
+	char *strings[N];
290
+
291
+	for(int i = 0; i < N; i++) {
292
+		asprintf(&strings[i], "%i", i);
293
+		choices_add(&choices, strings[i]);
294
+	}
295
+
296
+	choices_search(&choices, "12");
297
+
298
+	/* Must match `seq 0 99999 | grep '.*1.*2.*' | wc -l` */
299
+	assert(choices.available == 8146);
300
+
301
+	assert_streq(choices_get(&choices, 0), "12")
302
+
303
+	for(int i = 0; i < N; i++) {
304
+		free(strings[i]);
305
+	}
306
+
307
+	choices_destroy(&choices);
308
+}
309
+
282 310
 void summary() {
283 311
 	printf("%i tests, %i assertions, %i failures\n", testsrun, assertionsrun, testsfailed);
284 312
 }
... ...
@@ -310,6 +338,7 @@ int main(int argc, char *argv[]) {
310 338
 	runtest(test_choices_2);
311 339
 	runtest(test_choices_without_search);
312 340
 	runtest(test_choices_unicode);
341
+	runtest(test_choices_large_input);
313 342
 
314 343
 	summary();
315 344
 
Browse code

Fix segfault when encountering utf-8 characters

John Hawthorn authored on 04/08/2016 06:43:36
Showing 1 changed files
... ...
@@ -268,6 +268,17 @@ void test_choices_without_search() {
268 268
 	choices_destroy(&choices);
269 269
 }
270 270
 
271
+/* Regression test for segfault */
272
+void test_choices_unicode() {
273
+	choices_t choices;
274
+	choices_init(&choices);
275
+
276
+	choices_add(&choices, "Edmund Husserl - Méditations cartésiennes - Introduction a la phénoménologie.pdf");
277
+	choices_search(&choices, "e");
278
+
279
+	choices_destroy(&choices);
280
+}
281
+
271 282
 void summary() {
272 283
 	printf("%i tests, %i assertions, %i failures\n", testsrun, assertionsrun, testsfailed);
273 284
 }
... ...
@@ -298,6 +309,7 @@ int main(int argc, char *argv[]) {
298 309
 	runtest(test_choices_1);
299 310
 	runtest(test_choices_2);
300 311
 	runtest(test_choices_without_search);
312
+	runtest(test_choices_unicode);
301 313
 
302 314
 	summary();
303 315
 
Browse code

Add tests for exact scores

Preparing for some changes to the match method

John Hawthorn authored on 14/06/2016 06:36:51
Showing 1 changed files
... ...
@@ -2,6 +2,7 @@
2 2
 #include <string.h>
3 3
 #include <signal.h>
4 4
 
5
+#include "../config.h"
5 6
 #include "match.h"
6 7
 #include "choices.h"
7 8
 
... ...
@@ -39,7 +40,7 @@ void test_match() {
39 40
 	assert(has_match("", "a"));
40 41
 }
41 42
 
42
-void test_scoring() {
43
+void test_relative_scores() {
43 44
 	/* App/Models/Order is better than App/MOdels/zRder  */
44 45
 	assert(match("amor", "app/models/order") > match("amor", "app/models/zrder"));
45 46
 
... ...
@@ -66,6 +67,45 @@ void test_scoring() {
66 67
 	assert(match("abc", " a b c    ") > match("abc", " a  b  c "));
67 68
 }
68 69
 
70
+void test_exact_scores() {
71
+	/* Exact match is SCORE_MAX */
72
+	assert(match("abc", "abc") == SCORE_MAX);
73
+	assert(match("aBc", "abC") == SCORE_MAX);
74
+
75
+	/* Empty query always results in SCORE_MIN */
76
+	assert(match("", "") == SCORE_MIN);
77
+	assert(match("", "a") == SCORE_MIN);
78
+	assert(match("", "bb") == SCORE_MIN);
79
+
80
+	/* Gaps */
81
+	assert(match("a", "*a") == SCORE_GAP_LEADING);
82
+	assert(match("a", "*ba") == SCORE_GAP_LEADING*2);
83
+	assert(match("a", "**a*") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING);
84
+	assert(match("a", "**a**") == SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2);
85
+	assert(match("aa", "**aa**") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2);
86
+	assert(match("aa", "**a*a**") == SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING);
87
+
88
+	/* Consecutive */
89
+	assert(match("aa", "*aa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE);
90
+	assert(match("aaa", "*aaa") == SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2);
91
+	assert(match("aaa", "*a*aa") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE);
92
+
93
+	/* Slash */
94
+	assert(match("a", "/a") == SCORE_GAP_LEADING + SCORE_MATCH_SLASH);
95
+	assert(match("a", "*/a") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH);
96
+	assert(match("aa", "a/aa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE);
97
+
98
+	/* Capital */
99
+	assert(match("a", "bA") == SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL);
100
+	assert(match("a", "baA") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL);
101
+	assert(match("aa", "baAa") == SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE);
102
+
103
+	/* Dot */
104
+	assert(match("a", ".a") == SCORE_GAP_LEADING + SCORE_MATCH_DOT);
105
+	assert(match("a", "*a.a") == SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT);
106
+	assert(match("a", "*a.a") == SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT);
107
+}
108
+
69 109
 void test_positions_1() {
70 110
 	size_t positions[3];
71 111
 	match_positions("amo", "app/models/foo", positions);
... ...
@@ -245,7 +285,8 @@ int main(int argc, char *argv[]) {
245 285
 	signal(SIGTRAP, ignore_signal);
246 286
 
247 287
 	runtest(test_match);
248
-	runtest(test_scoring);
288
+	runtest(test_relative_scores);
289
+	runtest(test_exact_scores);
249 290
 	runtest(test_positions_1);
250 291
 	runtest(test_positions_2);
251 292
 	runtest(test_positions_3);
Browse code

Move fzytest into test/ directory

John Hawthorn authored on 21/05/2016 22:00:39
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,265 @@
1
+#include <stdio.h>
2
+#include <string.h>
3
+#include <signal.h>
4
+
5
+#include "match.h"
6
+#include "choices.h"
7
+
8
+int testsrun = 0, testsfailed = 0, assertionsrun = 0;
9
+
10
+#define assert(x)                                                                                  \
11
+	if (++assertionsrun && !(x)) {                                                             \
12
+		fprintf(stderr, "test \"%s\" failed\n   assert(%s) was false\n   at %s:%i\n\n",    \
13
+			__func__, #x, __FILE__, __LINE__);                                         \
14
+		raise(SIGTRAP);                                                                    \
15
+		testsfailed++;                                                                     \
16
+		return;                                                                            \
17
+	}
18
+
19
+#define assert_streq(a, b) assert(!strcmp(a, b))
20
+
21
+void runtest(void (*test)()) {
22
+	testsrun++;
23
+	test();
24
+}
25
+
26
+void test_match() {
27
+	assert(has_match("a", "a"));
28
+	assert(has_match("a", "ab"));
29
+	assert(has_match("a", "ba"));
30
+	assert(has_match("abc", "a|b|c"));
31
+
32
+	/* non-match */
33
+	assert(!has_match("a", ""));
34
+	assert(!has_match("a", "b"));
35
+	assert(!has_match("ass", "tags"));
36
+
37
+	/* match when query is empty */
38
+	assert(has_match("", ""));
39
+	assert(has_match("", "a"));
40
+}
41
+
42
+void test_scoring() {
43
+	/* App/Models/Order is better than App/MOdels/zRder  */
44
+	assert(match("amor", "app/models/order") > match("amor", "app/models/zrder"));
45
+
46
+	/* App/MOdels/foo is better than App/M/fOo  */
47
+	assert(match("amo", "app/m/foo") < match("amo", "app/models/foo"));
48
+
49
+	/* GEMFIle.Lock < GEMFILe  */
50
+	assert(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
51
+
52
+	/* GEMFIle.Lock < GEMFILe  */
53
+	assert(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
54
+
55
+	/* Prefer shorter matches */
56
+	assert(match("abce", "abcdef") > match("abce", "abc de"));
57
+
58
+	/* Prefer shorter candidates */
59
+	assert(match("test", "tests") > match("test", "testing"));
60
+
61
+	/* Scores first letter highly */
62
+	assert(match("test", "testing") > match("test", "/testing"));
63
+
64
+	/* Prefer shorter matches */
65
+	assert(match("abc", "    a b c ") > match("abc", " a  b  c "));
66
+	assert(match("abc", " a b c    ") > match("abc", " a  b  c "));
67
+}
68
+
69
+void test_positions_1() {
70
+	size_t positions[3];
71
+	match_positions("amo", "app/models/foo", positions);
72
+	assert(positions[0] == 0);
73
+	assert(positions[1] == 4);
74
+	assert(positions[2] == 5);
75
+}
76
+
77
+void test_positions_2() {
78
+	/*
79
+	 * We should prefer matching the 'o' in order, since it's the beginning
80
+	 * of a word.
81
+	 */
82
+	size_t positions[4];
83
+	match_positions("amor", "app/models/order", positions);
84
+	assert(positions[0] == 0);
85
+	assert(positions[1] == 4);
86
+	assert(positions[2] == 11);
87
+}
88
+
89
+void test_positions_3() {
90
+	size_t positions[2];
91
+	match_positions("as", "tags", positions);
92
+	assert(positions[0] == 1);
93
+	assert(positions[1] == 3);
94
+}
95
+
96
+void test_positions_4() {
97
+	size_t positions[2];
98
+	match_positions("as", "examples.txt", positions);
99
+	assert(positions[0] == 2);
100
+	assert(positions[1] == 7);
101
+}
102
+
103
+void test_positions_5() {
104
+	size_t positions[3];
105
+	match_positions("abc", "a/a/b/c/c", positions);
106
+	assert(positions[0] == 2);
107
+	assert(positions[1] == 4);
108
+	assert(positions[2] == 6);
109
+}
110
+
111
+void test_positions_exact() {
112
+	size_t positions[3];
113
+	match_positions("foo", "foo", positions);
114
+	assert(positions[0] == 0);
115
+	assert(positions[1] == 1);
116
+	assert(positions[2] == 2);
117
+}
118
+
119
+void test_choices_empty() {
120
+	choices_t choices;
121
+	choices_init(&choices);
122
+	assert(choices.size == 0);
123
+	assert(choices.available == 0);
124
+	assert(choices.selection == 0);
125
+
126
+	choices_prev(&choices);
127
+	assert(choices.selection == 0);
128
+
129
+	choices_next(&choices);
130
+	assert(choices.selection == 0);
131
+
132
+	choices_destroy(&choices);
133
+}
134
+
135
+void test_choices_1() {
136
+	choices_t choices;
137
+	choices_init(&choices);
138
+	choices_add(&choices, "tags");
139
+
140
+	choices_search(&choices, "");
141
+	assert(choices.available == 1);
142
+	assert(choices.selection == 0);
143
+
144
+	choices_search(&choices, "t");
145
+	assert(choices.available == 1);
146
+	assert(choices.selection == 0);
147
+
148
+	choices_prev(&choices);
149
+	assert(choices.selection == 0);
150
+
151
+	choices_next(&choices);
152
+	assert(choices.selection == 0);
153
+
154
+	assert(!strcmp(choices_get(&choices, 0), "tags"));
155
+	assert(choices_get(&choices, 1) == NULL);
156
+
157
+	choices_destroy(&choices);
158
+}
159
+
160
+void test_choices_2() {
161
+	choices_t choices;
162
+	choices_init(&choices);
163
+	choices_add(&choices, "tags");
164
+	choices_add(&choices, "test");
165
+
166
+	/* Empty search */
167
+	choices_search(&choices, "");
168
+	assert(choices.selection == 0);
169
+	assert(choices.available == 2);
170
+	assert_streq(choices_get(&choices, 0), "tags");
171
+	assert_streq(choices_get(&choices, 1), "test");
172
+
173
+	choices_next(&choices);
174
+	assert(choices.selection == 1);
175
+	choices_next(&choices);
176
+	assert(choices.selection == 0);
177
+
178
+	choices_prev(&choices);
179
+	assert(choices.selection == 1);
180
+	choices_prev(&choices);
181
+	assert(choices.selection == 0);
182
+
183
+	/* Filtered search */
184
+	choices_search(&choices, "te");
185
+	assert(choices.available == 1);
186
+	assert(choices.selection == 0);
187
+	assert_streq(choices_get(&choices, 0), "test");
188
+
189
+	choices_next(&choices);
190
+	assert(choices.selection == 0);
191
+
192
+	choices_prev(&choices);
193
+	assert(choices.selection == 0);
194
+
195
+	/* No results */
196
+	choices_search(&choices, "foobar");
197
+	assert(choices.available == 0);
198
+	assert(choices.selection == 0);
199
+
200
+	/* Different order due to scoring */
201
+	choices_search(&choices, "ts");
202
+	assert(choices.available == 2);
203
+	assert(choices.selection == 0);
204
+	assert_streq(choices_get(&choices, 0), "test");
205
+	assert_streq(choices_get(&choices, 1), "tags");
206
+
207
+	choices_destroy(&choices);
208
+}
209
+
210
+void test_choices_without_search() {
211
+	/* Before a search is run, it should return no results */
212
+
213
+	choices_t choices;
214
+	choices_init(&choices);
215
+
216
+	assert(choices.available == 0);
217
+	assert(choices.selection == 0);
218
+	assert(choices.size == 0);
219
+	assert(choices_get(&choices, 0) == NULL);
220
+
221
+	choices_add(&choices, "test");
222
+
223
+	assert(choices.available == 0);
224
+	assert(choices.selection == 0);
225
+	assert(choices.size == 1);
226
+	assert(choices_get(&choices, 0) == NULL);
227
+
228
+	choices_destroy(&choices);
229
+}
230
+
231
+void summary() {
232
+	printf("%i tests, %i assertions, %i failures\n", testsrun, assertionsrun, testsfailed);
233
+}
234
+
235
+static void ignore_signal(int signum) {
236
+	(void)signum;
237
+}
238
+
239
+int main(int argc, char *argv[]) {
240
+	(void)argc;
241
+	(void)argv;
242
+
243
+	/* We raise sigtrap on all assertion failures.
244
+	 * If we have no debugger running, we should ignore it */
245
+	signal(SIGTRAP, ignore_signal);
246
+
247
+	runtest(test_match);
248
+	runtest(test_scoring);
249
+	runtest(test_positions_1);
250
+	runtest(test_positions_2);
251
+	runtest(test_positions_3);
252
+	runtest(test_positions_4);
253
+	runtest(test_positions_5);
254
+	runtest(test_positions_exact);
255
+
256
+	runtest(test_choices_empty);
257
+	runtest(test_choices_1);
258
+	runtest(test_choices_2);
259
+	runtest(test_choices_without_search);
260
+
261
+	summary();
262
+
263
+	/* exit 0 if all tests pass */
264
+	return !!testsfailed;
265
+}