Browse code

Check for too long haystack

Fixes #145

John Hawthorn authored on 09/08/2020 02:42:58
Showing 1 changed files
... ...
@@ -131,6 +131,18 @@ TEST score_dot() {
131 131
 	PASS();
132 132
 }
133 133
 
134
+TEST score_long_string() {
135
+	char string[4096];
136
+	memset(string, 'a', sizeof(string) - 1);
137
+	string[sizeof(string) - 1] = '\0';
138
+
139
+	ASSERT_SCORE_EQ(SCORE_MIN, match("aa", string));
140
+	ASSERT_SCORE_EQ(SCORE_MIN, match(string, "aa"));
141
+	ASSERT_SCORE_EQ(SCORE_MIN, match(string, string));
142
+
143
+	PASS();
144
+}
145
+
134 146
 TEST positions_consecutive() {
135 147
 	size_t positions[3];
136 148
 	match_positions("amo", "app/models/foo", positions);
... ...
@@ -210,6 +222,7 @@ SUITE(match_suite) {
210 222
 	RUN_TEST(score_slash);
211 223
 	RUN_TEST(score_capital);
212 224
 	RUN_TEST(score_dot);
225
+	RUN_TEST(score_long_string);
213 226
 
214 227
 	RUN_TEST(positions_consecutive);
215 228
 	RUN_TEST(positions_start_of_word);
Browse code

Fix warnings due to types in test

John Hawthorn authored on 27/04/2017 01:09:45
Showing 1 changed files
... ...
@@ -7,7 +7,7 @@
7 7
 
8 8
 #define SCORE_TOLERANCE 0.000001
9 9
 #define ASSERT_SCORE_EQ(a,b) ASSERT_IN_RANGE((a), (b), SCORE_TOLERANCE)
10
-#define ASSERT_INT_EQ(a,b) ASSERT_EQ_FMT((a), (b), "%d")
10
+#define ASSERT_SIZE_T_EQ(a,b) ASSERT_EQ_FMT((size_t)(a), (b), "%zu")
11 11
 
12 12
 /* has_match(char *needle, char *haystack) */
13 13
 TEST exact_match_should_return_true() {
... ...
@@ -134,9 +134,9 @@ TEST score_dot() {
134 134
 TEST positions_consecutive() {
135 135
 	size_t positions[3];
136 136
 	match_positions("amo", "app/models/foo", positions);
137
-	ASSERT_INT_EQ(0, positions[0]);
138
-	ASSERT_INT_EQ(4, positions[1]);
139
-	ASSERT_INT_EQ(5, positions[2]);
137
+	ASSERT_SIZE_T_EQ(0, positions[0]);
138
+	ASSERT_SIZE_T_EQ(4, positions[1]);
139
+	ASSERT_SIZE_T_EQ(5, positions[2]);
140 140
 
141 141
 	PASS();
142 142
 }
... ...
@@ -148,10 +148,10 @@ TEST positions_start_of_word() {
148 148
 	 */
149 149
 	size_t positions[4];
150 150
 	match_positions("amor", "app/models/order", positions);
151
-	ASSERT_INT_EQ(0, positions[0]);
152
-	ASSERT_INT_EQ(4, positions[1]);
153
-	ASSERT_INT_EQ(11, positions[2]);
154
-	ASSERT_INT_EQ(12, positions[3]);
151
+	ASSERT_SIZE_T_EQ(0, positions[0]);
152
+	ASSERT_SIZE_T_EQ(4, positions[1]);
153
+	ASSERT_SIZE_T_EQ(11, positions[2]);
154
+	ASSERT_SIZE_T_EQ(12, positions[3]);
155 155
 
156 156
 	PASS();
157 157
 }
... ...
@@ -159,12 +159,12 @@ TEST positions_start_of_word() {
159 159
 TEST positions_no_bonuses() {
160 160
 	size_t positions[2];
161 161
 	match_positions("as", "tags", positions);
162
-	ASSERT_INT_EQ(1, positions[0]);
163
-	ASSERT_INT_EQ(3, positions[1]);
162
+	ASSERT_SIZE_T_EQ(1, positions[0]);
163
+	ASSERT_SIZE_T_EQ(3, positions[1]);
164 164
 
165 165
 	match_positions("as", "examples.txt", positions);
166
-	ASSERT_INT_EQ(2, positions[0]);
167
-	ASSERT_INT_EQ(7, positions[1]);
166
+	ASSERT_SIZE_T_EQ(2, positions[0]);
167
+	ASSERT_SIZE_T_EQ(7, positions[1]);
168 168
 
169 169
 	PASS();
170 170
 }
... ...
@@ -172,9 +172,9 @@ TEST positions_no_bonuses() {
172 172
 TEST positions_multiple_candidates_start_of_words() {
173 173
 	size_t positions[3];
174 174
 	match_positions("abc", "a/a/b/c/c", positions);
175
-	ASSERT_INT_EQ(2, positions[0]);
176
-	ASSERT_INT_EQ(4, positions[1]);
177
-	ASSERT_INT_EQ(6, positions[2]);
175
+	ASSERT_SIZE_T_EQ(2, positions[0]);
176
+	ASSERT_SIZE_T_EQ(4, positions[1]);
177
+	ASSERT_SIZE_T_EQ(6, positions[2]);
178 178
 
179 179
 	PASS();
180 180
 }
... ...
@@ -182,9 +182,9 @@ TEST positions_multiple_candidates_start_of_words() {
182 182
 TEST positions_exact_match() {
183 183
 	size_t positions[3];
184 184
 	match_positions("foo", "foo", positions);
185
-	ASSERT_INT_EQ(0, positions[0]);
186
-	ASSERT_INT_EQ(1, positions[1]);
187
-	ASSERT_INT_EQ(2, positions[2]);
185
+	ASSERT_SIZE_T_EQ(0, positions[0]);
186
+	ASSERT_SIZE_T_EQ(1, positions[1]);
187
+	ASSERT_SIZE_T_EQ(2, positions[2]);
188 188
 
189 189
 	PASS();
190 190
 }
Browse code

Use a tolerance for assertions on exact score

This caused the test suite to fail on i386 (and possibly other archs),
because the value was off my a minute amount due to floating point
representation.

John Hawthorn authored on 17/04/2017 06:35:38
Showing 1 changed files
... ...
@@ -5,7 +5,8 @@
5 5
 
6 6
 #include "greatest/greatest.h"
7 7
 
8
-#define ASSERT_SCORE_EQ(a,b) ASSERT_EQ_FMT((a), (b), "%f")
8
+#define SCORE_TOLERANCE 0.000001
9
+#define ASSERT_SCORE_EQ(a,b) ASSERT_IN_RANGE((a), (b), SCORE_TOLERANCE)
9 10
 #define ASSERT_INT_EQ(a,b) ASSERT_EQ_FMT((a), (b), "%d")
10 11
 
11 12
 /* has_match(char *needle, char *haystack) */
Browse code

Format values in errored tests

John Hawthorn authored on 17/04/2017 06:12:21
Showing 1 changed files
... ...
@@ -5,6 +5,9 @@
5 5
 
6 6
 #include "greatest/greatest.h"
7 7
 
8
+#define ASSERT_SCORE_EQ(a,b) ASSERT_EQ_FMT((a), (b), "%f")
9
+#define ASSERT_INT_EQ(a,b) ASSERT_EQ_FMT((a), (b), "%d")
10
+
8 11
 /* has_match(char *needle, char *haystack) */
9 12
 TEST exact_match_should_return_true() {
10 13
 	ASSERT(has_match("a", "a"));
... ...
@@ -76,63 +79,63 @@ TEST should_prefer_start_of_candidate() {
76 79
 
77 80
 TEST score_exact_match() {
78 81
 	/* Exact match is SCORE_MAX */
79
-	ASSERT_EQ(SCORE_MAX, match("abc", "abc"));
80
-	ASSERT_EQ(SCORE_MAX, match("aBc", "abC"));
82
+	ASSERT_SCORE_EQ(SCORE_MAX, match("abc", "abc"));
83
+	ASSERT_SCORE_EQ(SCORE_MAX, match("aBc", "abC"));
81 84
 	PASS();
82 85
 }
83 86
 
84 87
 TEST score_empty_query() {
85 88
 	/* Empty query always results in SCORE_MIN */
86
-	ASSERT_EQ(SCORE_MIN, match("", ""));
87
-	ASSERT_EQ(SCORE_MIN, match("", "a"));
88
-	ASSERT_EQ(SCORE_MIN, match("", "bb"));
89
+	ASSERT_SCORE_EQ(SCORE_MIN, match("", ""));
90
+	ASSERT_SCORE_EQ(SCORE_MIN, match("", "a"));
91
+	ASSERT_SCORE_EQ(SCORE_MIN, match("", "bb"));
89 92
 	PASS();
90 93
 }
91 94
 
92 95
 TEST score_gaps() {
93
-	ASSERT_EQ(SCORE_GAP_LEADING, match("a", "*a"));
94
-	ASSERT_EQ(SCORE_GAP_LEADING*2, match("a", "*ba"));
95
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING, match("a", "**a*"));
96
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2, match("a", "**a**"));
97
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2, match("aa", "**aa**"));
98
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING, match("aa", "**a*a**"));
96
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING, match("a", "*a"));
97
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2, match("a", "*ba"));
98
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING, match("a", "**a*"));
99
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2, match("a", "**a**"));
100
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2, match("aa", "**aa**"));
101
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING, match("aa", "**a*a**"));
99 102
 	PASS();
100 103
 }
101 104
 
102 105
 TEST score_consecutive() {
103
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE, match("aa", "*aa"));
104
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2, match("aaa", "*aaa"));
105
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE, match("aaa", "*a*aa"));
106
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE, match("aa", "*aa"));
107
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2, match("aaa", "*aaa"));
108
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE, match("aaa", "*a*aa"));
106 109
 	PASS();
107 110
 }
108 111
 
109 112
 TEST score_slash() {
110
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_SLASH, match("a", "/a"));
111
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH, match("a", "*/a"));
112
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE, match("aa", "a/aa"));
113
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_MATCH_SLASH, match("a", "/a"));
114
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH, match("a", "*/a"));
115
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE, match("aa", "a/aa"));
113 116
 	PASS();
114 117
 }
115 118
 
116 119
 TEST score_capital() {
117
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL, match("a", "bA"));
118
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL, match("a", "baA"));
119
-	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE, match("aa", "baAa"));
120
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL, match("a", "bA"));
121
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL, match("a", "baA"));
122
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE, match("aa", "baAa"));
120 123
 	PASS();
121 124
 }
122 125
 
123 126
 TEST score_dot() {
124
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_DOT, match("a", ".a"));
125
-	ASSERT_EQ(SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT, match("a", "*a.a"));
126
-	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT, match("a", "*a.a"));
127
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_MATCH_DOT, match("a", ".a"));
128
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT, match("a", "*a.a"));
129
+	ASSERT_SCORE_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT, match("a", "*a.a"));
127 130
 	PASS();
128 131
 }
129 132
 
130 133
 TEST positions_consecutive() {
131 134
 	size_t positions[3];
132 135
 	match_positions("amo", "app/models/foo", positions);
133
-	ASSERT_EQ(0, positions[0]);
134
-	ASSERT_EQ(4, positions[1]);
135
-	ASSERT_EQ(5, positions[2]);
136
+	ASSERT_INT_EQ(0, positions[0]);
137
+	ASSERT_INT_EQ(4, positions[1]);
138
+	ASSERT_INT_EQ(5, positions[2]);
136 139
 
137 140
 	PASS();
138 141
 }
... ...
@@ -144,10 +147,10 @@ TEST positions_start_of_word() {
144 147
 	 */
145 148
 	size_t positions[4];
146 149
 	match_positions("amor", "app/models/order", positions);
147
-	ASSERT_EQ(0, positions[0]);
148
-	ASSERT_EQ(4, positions[1]);
149
-	ASSERT_EQ(11, positions[2]);
150
-	ASSERT_EQ(12, positions[3]);
150
+	ASSERT_INT_EQ(0, positions[0]);
151
+	ASSERT_INT_EQ(4, positions[1]);
152
+	ASSERT_INT_EQ(11, positions[2]);
153
+	ASSERT_INT_EQ(12, positions[3]);
151 154
 
152 155
 	PASS();
153 156
 }
... ...
@@ -155,12 +158,12 @@ TEST positions_start_of_word() {
155 158
 TEST positions_no_bonuses() {
156 159
 	size_t positions[2];
157 160
 	match_positions("as", "tags", positions);
158
-	ASSERT_EQ(1, positions[0]);
159
-	ASSERT_EQ(3, positions[1]);
161
+	ASSERT_INT_EQ(1, positions[0]);
162
+	ASSERT_INT_EQ(3, positions[1]);
160 163
 
161 164
 	match_positions("as", "examples.txt", positions);
162
-	ASSERT_EQ(2, positions[0]);
163
-	ASSERT_EQ(7, positions[1]);
165
+	ASSERT_INT_EQ(2, positions[0]);
166
+	ASSERT_INT_EQ(7, positions[1]);
164 167
 
165 168
 	PASS();
166 169
 }
... ...
@@ -168,9 +171,9 @@ TEST positions_no_bonuses() {
168 171
 TEST positions_multiple_candidates_start_of_words() {
169 172
 	size_t positions[3];
170 173
 	match_positions("abc", "a/a/b/c/c", positions);
171
-	ASSERT_EQ(2, positions[0]);
172
-	ASSERT_EQ(4, positions[1]);
173
-	ASSERT_EQ(6, positions[2]);
174
+	ASSERT_INT_EQ(2, positions[0]);
175
+	ASSERT_INT_EQ(4, positions[1]);
176
+	ASSERT_INT_EQ(6, positions[2]);
174 177
 
175 178
 	PASS();
176 179
 }
... ...
@@ -178,9 +181,9 @@ TEST positions_multiple_candidates_start_of_words() {
178 181
 TEST positions_exact_match() {
179 182
 	size_t positions[3];
180 183
 	match_positions("foo", "foo", positions);
181
-	ASSERT_EQ(0, positions[0]);
182
-	ASSERT_EQ(1, positions[1]);
183
-	ASSERT_EQ(2, positions[2]);
184
+	ASSERT_INT_EQ(0, positions[0]);
185
+	ASSERT_INT_EQ(1, positions[1]);
186
+	ASSERT_INT_EQ(2, positions[2]);
184 187
 
185 188
 	PASS();
186 189
 }
Browse code

Split up tests, improve naming

John Hawthorn authored on 05/04/2017 06:29:46
Showing 1 changed files
... ...
@@ -5,95 +5,129 @@
5 5
 
6 6
 #include "greatest/greatest.h"
7 7
 
8
-TEST test_match() {
8
+/* has_match(char *needle, char *haystack) */
9
+TEST exact_match_should_return_true() {
9 10
 	ASSERT(has_match("a", "a"));
11
+	PASS();
12
+}
13
+
14
+TEST partial_match_should_return_true() {
10 15
 	ASSERT(has_match("a", "ab"));
11 16
 	ASSERT(has_match("a", "ba"));
17
+	PASS();
18
+}
19
+
20
+TEST match_with_delimiters_in_between() {
12 21
 	ASSERT(has_match("abc", "a|b|c"));
22
+	PASS();
23
+}
13 24
 
14
-	/* non-match */
25
+TEST non_match_should_return_false() {
15 26
 	ASSERT(!has_match("a", ""));
16 27
 	ASSERT(!has_match("a", "b"));
17 28
 	ASSERT(!has_match("ass", "tags"));
29
+	PASS();
30
+}
18 31
 
32
+TEST empty_query_should_always_match() {
19 33
 	/* match when query is empty */
20 34
 	ASSERT(has_match("", ""));
21 35
 	ASSERT(has_match("", "a"));
22
-
23 36
 	PASS();
24 37
 }
25 38
 
26
-TEST test_relative_scores() {
39
+/* match(char *needle, char *haystack) */
40
+
41
+TEST should_prefer_starts_of_words() {
27 42
 	/* App/Models/Order is better than App/MOdels/zRder  */
28 43
 	ASSERT(match("amor", "app/models/order") > match("amor", "app/models/zrder"));
44
+	PASS();
45
+}
29 46
 
47
+TEST should_prefer_consecutive_letters() {
30 48
 	/* App/MOdels/foo is better than App/M/fOo  */
31 49
 	ASSERT(match("amo", "app/m/foo") < match("amo", "app/models/foo"));
50
+	PASS();
51
+}
32 52
 
53
+TEST should_prefer_contiguous_over_letter_following_period() {
33 54
 	/* GEMFIle.Lock < GEMFILe  */
34 55
 	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
56
+	PASS();
57
+}
35 58
 
36
-	/* GEMFIle.Lock < GEMFILe  */
37
-	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
38
-
39
-	/* Prefer shorter matches */
59
+TEST should_prefer_shorter_matches() {
40 60
 	ASSERT(match("abce", "abcdef") > match("abce", "abc de"));
61
+	ASSERT(match("abc", "    a b c ") > match("abc", " a  b  c "));
62
+	ASSERT(match("abc", " a b c    ") > match("abc", " a  b  c "));
63
+	PASS();
64
+}
41 65
 
42
-	/* Prefer shorter candidates */
66
+TEST should_prefer_shorter_candidates() {
43 67
 	ASSERT(match("test", "tests") > match("test", "testing"));
68
+	PASS();
69
+}
44 70
 
71
+TEST should_prefer_start_of_candidate() {
45 72
 	/* Scores first letter highly */
46 73
 	ASSERT(match("test", "testing") > match("test", "/testing"));
47
-
48
-	/* Prefer shorter matches */
49
-	ASSERT(match("abc", "    a b c ") > match("abc", " a  b  c "));
50
-	ASSERT(match("abc", " a b c    ") > match("abc", " a  b  c "));
51
-
52 74
 	PASS();
53 75
 }
54 76
 
55
-TEST test_exact_scores() {
77
+TEST score_exact_match() {
56 78
 	/* Exact match is SCORE_MAX */
57 79
 	ASSERT_EQ(SCORE_MAX, match("abc", "abc"));
58 80
 	ASSERT_EQ(SCORE_MAX, match("aBc", "abC"));
81
+	PASS();
82
+}
59 83
 
84
+TEST score_empty_query() {
60 85
 	/* Empty query always results in SCORE_MIN */
61 86
 	ASSERT_EQ(SCORE_MIN, match("", ""));
62 87
 	ASSERT_EQ(SCORE_MIN, match("", "a"));
63 88
 	ASSERT_EQ(SCORE_MIN, match("", "bb"));
89
+	PASS();
90
+}
64 91
 
65
-	/* Gaps */
92
+TEST score_gaps() {
66 93
 	ASSERT_EQ(SCORE_GAP_LEADING, match("a", "*a"));
67 94
 	ASSERT_EQ(SCORE_GAP_LEADING*2, match("a", "*ba"));
68 95
 	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING, match("a", "**a*"));
69 96
 	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2, match("a", "**a**"));
70 97
 	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2, match("aa", "**aa**"));
71 98
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING, match("aa", "**a*a**"));
99
+	PASS();
100
+}
72 101
 
73
-	/* Consecutive */
102
+TEST score_consecutive() {
74 103
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE, match("aa", "*aa"));
75 104
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2, match("aaa", "*aaa"));
76 105
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE, match("aaa", "*a*aa"));
106
+	PASS();
107
+}
77 108
 
78
-	/* Slash */
109
+TEST score_slash() {
79 110
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_SLASH, match("a", "/a"));
80 111
 	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH, match("a", "*/a"));
81 112
 	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE, match("aa", "a/aa"));
113
+	PASS();
114
+}
82 115
 
83
-	/* Capital */
116
+TEST score_capital() {
84 117
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL, match("a", "bA"));
85 118
 	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL, match("a", "baA"));
86 119
 	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE, match("aa", "baAa"));
120
+	PASS();
121
+}
87 122
 
88
-	/* Dot */
123
+TEST score_dot() {
89 124
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_DOT, match("a", ".a"));
90 125
 	ASSERT_EQ(SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT, match("a", "*a.a"));
91 126
 	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT, match("a", "*a.a"));
92
-
93 127
 	PASS();
94 128
 }
95 129
 
96
-TEST test_positions_1() {
130
+TEST positions_consecutive() {
97 131
 	size_t positions[3];
98 132
 	match_positions("amo", "app/models/foo", positions);
99 133
 	ASSERT_EQ(0, positions[0]);
... ...
@@ -103,7 +137,7 @@ TEST test_positions_1() {
103 137
 	PASS();
104 138
 }
105 139
 
106
-TEST test_positions_2() {
140
+TEST positions_start_of_word() {
107 141
 	/*
108 142
 	 * We should prefer matching the 'o' in order, since it's the beginning
109 143
 	 * of a word.
... ...
@@ -113,21 +147,17 @@ TEST test_positions_2() {
113 147
 	ASSERT_EQ(0, positions[0]);
114 148
 	ASSERT_EQ(4, positions[1]);
115 149
 	ASSERT_EQ(11, positions[2]);
150
+	ASSERT_EQ(12, positions[3]);
116 151
 
117 152
 	PASS();
118 153
 }
119 154
 
120
-TEST test_positions_3() {
155
+TEST positions_no_bonuses() {
121 156
 	size_t positions[2];
122 157
 	match_positions("as", "tags", positions);
123 158
 	ASSERT_EQ(1, positions[0]);
124 159
 	ASSERT_EQ(3, positions[1]);
125 160
 
126
-	PASS();
127
-}
128
-
129
-TEST test_positions_4() {
130
-	size_t positions[2];
131 161
 	match_positions("as", "examples.txt", positions);
132 162
 	ASSERT_EQ(2, positions[0]);
133 163
 	ASSERT_EQ(7, positions[1]);
... ...
@@ -135,7 +165,7 @@ TEST test_positions_4() {
135 165
 	PASS();
136 166
 }
137 167
 
138
-TEST test_positions_5() {
168
+TEST positions_multiple_candidates_start_of_words() {
139 169
 	size_t positions[3];
140 170
 	match_positions("abc", "a/a/b/c/c", positions);
141 171
 	ASSERT_EQ(2, positions[0]);
... ...
@@ -145,7 +175,7 @@ TEST test_positions_5() {
145 175
 	PASS();
146 176
 }
147 177
 
148
-TEST test_positions_exact() {
178
+TEST positions_exact_match() {
149 179
 	size_t positions[3];
150 180
 	match_positions("foo", "foo", positions);
151 181
 	ASSERT_EQ(0, positions[0]);
... ...
@@ -156,13 +186,30 @@ TEST test_positions_exact() {
156 186
 }
157 187
 
158 188
 SUITE(match_suite) {
159
-	RUN_TEST(test_match);
160
-	RUN_TEST(test_relative_scores);
161
-	RUN_TEST(test_exact_scores);
162
-	RUN_TEST(test_positions_1);
163
-	RUN_TEST(test_positions_2);
164
-	RUN_TEST(test_positions_3);
165
-	RUN_TEST(test_positions_4);
166
-	RUN_TEST(test_positions_5);
167
-	RUN_TEST(test_positions_exact);
189
+	RUN_TEST(exact_match_should_return_true);
190
+	RUN_TEST(partial_match_should_return_true);
191
+	RUN_TEST(empty_query_should_always_match);
192
+	RUN_TEST(non_match_should_return_false);
193
+	RUN_TEST(match_with_delimiters_in_between);
194
+
195
+	RUN_TEST(should_prefer_starts_of_words);
196
+	RUN_TEST(should_prefer_consecutive_letters);
197
+	RUN_TEST(should_prefer_contiguous_over_letter_following_period);
198
+	RUN_TEST(should_prefer_shorter_matches);
199
+	RUN_TEST(should_prefer_shorter_candidates);
200
+	RUN_TEST(should_prefer_start_of_candidate);
201
+
202
+	RUN_TEST(score_exact_match);
203
+	RUN_TEST(score_empty_query);
204
+	RUN_TEST(score_gaps);
205
+	RUN_TEST(score_consecutive);
206
+	RUN_TEST(score_slash);
207
+	RUN_TEST(score_capital);
208
+	RUN_TEST(score_dot);
209
+
210
+	RUN_TEST(positions_consecutive);
211
+	RUN_TEST(positions_start_of_word);
212
+	RUN_TEST(positions_no_bonuses);
213
+	RUN_TEST(positions_multiple_candidates_start_of_words);
214
+	RUN_TEST(positions_exact_match);
168 215
 }
Browse code

Move test suites into separate files

John Hawthorn authored on 05/04/2017 05:52:53
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,168 @@
1
+#include <stdlib.h>
2
+
3
+#include "../config.h"
4
+#include "match.h"
5
+
6
+#include "greatest/greatest.h"
7
+
8
+TEST test_match() {
9
+	ASSERT(has_match("a", "a"));
10
+	ASSERT(has_match("a", "ab"));
11
+	ASSERT(has_match("a", "ba"));
12
+	ASSERT(has_match("abc", "a|b|c"));
13
+
14
+	/* non-match */
15
+	ASSERT(!has_match("a", ""));
16
+	ASSERT(!has_match("a", "b"));
17
+	ASSERT(!has_match("ass", "tags"));
18
+
19
+	/* match when query is empty */
20
+	ASSERT(has_match("", ""));
21
+	ASSERT(has_match("", "a"));
22
+
23
+	PASS();
24
+}
25
+
26
+TEST test_relative_scores() {
27
+	/* App/Models/Order is better than App/MOdels/zRder  */
28
+	ASSERT(match("amor", "app/models/order") > match("amor", "app/models/zrder"));
29
+
30
+	/* App/MOdels/foo is better than App/M/fOo  */
31
+	ASSERT(match("amo", "app/m/foo") < match("amo", "app/models/foo"));
32
+
33
+	/* GEMFIle.Lock < GEMFILe  */
34
+	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
35
+
36
+	/* GEMFIle.Lock < GEMFILe  */
37
+	ASSERT(match("gemfil", "Gemfile.lock") < match("gemfil", "Gemfile"));
38
+
39
+	/* Prefer shorter matches */
40
+	ASSERT(match("abce", "abcdef") > match("abce", "abc de"));
41
+
42
+	/* Prefer shorter candidates */
43
+	ASSERT(match("test", "tests") > match("test", "testing"));
44
+
45
+	/* Scores first letter highly */
46
+	ASSERT(match("test", "testing") > match("test", "/testing"));
47
+
48
+	/* Prefer shorter matches */
49
+	ASSERT(match("abc", "    a b c ") > match("abc", " a  b  c "));
50
+	ASSERT(match("abc", " a b c    ") > match("abc", " a  b  c "));
51
+
52
+	PASS();
53
+}
54
+
55
+TEST test_exact_scores() {
56
+	/* Exact match is SCORE_MAX */
57
+	ASSERT_EQ(SCORE_MAX, match("abc", "abc"));
58
+	ASSERT_EQ(SCORE_MAX, match("aBc", "abC"));
59
+
60
+	/* Empty query always results in SCORE_MIN */
61
+	ASSERT_EQ(SCORE_MIN, match("", ""));
62
+	ASSERT_EQ(SCORE_MIN, match("", "a"));
63
+	ASSERT_EQ(SCORE_MIN, match("", "bb"));
64
+
65
+	/* Gaps */
66
+	ASSERT_EQ(SCORE_GAP_LEADING, match("a", "*a"));
67
+	ASSERT_EQ(SCORE_GAP_LEADING*2, match("a", "*ba"));
68
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING, match("a", "**a*"));
69
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_GAP_TRAILING*2, match("a", "**a**"));
70
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CONSECUTIVE + SCORE_GAP_TRAILING*2, match("aa", "**aa**"));
71
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_GAP_TRAILING + SCORE_GAP_TRAILING, match("aa", "**a*a**"));
72
+
73
+	/* Consecutive */
74
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE, match("aa", "*aa"));
75
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CONSECUTIVE*2, match("aaa", "*aaa"));
76
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_CONSECUTIVE, match("aaa", "*a*aa"));
77
+
78
+	/* Slash */
79
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_SLASH, match("a", "/a"));
80
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH, match("a", "*/a"));
81
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_SLASH + SCORE_MATCH_CONSECUTIVE, match("aa", "a/aa"));
82
+
83
+	/* Capital */
84
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_CAPITAL, match("a", "bA"));
85
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL, match("a", "baA"));
86
+	ASSERT_EQ(SCORE_GAP_LEADING*2 + SCORE_MATCH_CAPITAL + SCORE_MATCH_CONSECUTIVE, match("aa", "baAa"));
87
+
88
+	/* Dot */
89
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_MATCH_DOT, match("a", ".a"));
90
+	ASSERT_EQ(SCORE_GAP_LEADING*3 + SCORE_MATCH_DOT, match("a", "*a.a"));
91
+	ASSERT_EQ(SCORE_GAP_LEADING + SCORE_GAP_INNER + SCORE_MATCH_DOT, match("a", "*a.a"));
92
+
93
+	PASS();
94
+}
95
+
96
+TEST test_positions_1() {
97
+	size_t positions[3];
98
+	match_positions("amo", "app/models/foo", positions);
99
+	ASSERT_EQ(0, positions[0]);
100
+	ASSERT_EQ(4, positions[1]);
101
+	ASSERT_EQ(5, positions[2]);
102
+
103
+	PASS();
104
+}
105
+
106
+TEST test_positions_2() {
107
+	/*
108
+	 * We should prefer matching the 'o' in order, since it's the beginning
109
+	 * of a word.
110
+	 */
111
+	size_t positions[4];
112
+	match_positions("amor", "app/models/order", positions);
113
+	ASSERT_EQ(0, positions[0]);
114
+	ASSERT_EQ(4, positions[1]);
115
+	ASSERT_EQ(11, positions[2]);
116
+
117
+	PASS();
118
+}
119
+
120
+TEST test_positions_3() {
121
+	size_t positions[2];
122
+	match_positions("as", "tags", positions);
123
+	ASSERT_EQ(1, positions[0]);
124
+	ASSERT_EQ(3, positions[1]);
125
+
126
+	PASS();
127
+}
128
+
129
+TEST test_positions_4() {
130
+	size_t positions[2];
131
+	match_positions("as", "examples.txt", positions);
132
+	ASSERT_EQ(2, positions[0]);
133
+	ASSERT_EQ(7, positions[1]);
134
+
135
+	PASS();
136
+}
137
+
138
+TEST test_positions_5() {
139
+	size_t positions[3];
140
+	match_positions("abc", "a/a/b/c/c", positions);
141
+	ASSERT_EQ(2, positions[0]);
142
+	ASSERT_EQ(4, positions[1]);
143
+	ASSERT_EQ(6, positions[2]);
144
+
145
+	PASS();
146
+}
147
+
148
+TEST test_positions_exact() {
149
+	size_t positions[3];
150
+	match_positions("foo", "foo", positions);
151
+	ASSERT_EQ(0, positions[0]);
152
+	ASSERT_EQ(1, positions[1]);
153
+	ASSERT_EQ(2, positions[2]);
154
+
155
+	PASS();
156
+}
157
+
158
+SUITE(match_suite) {
159
+	RUN_TEST(test_match);
160
+	RUN_TEST(test_relative_scores);
161
+	RUN_TEST(test_exact_scores);
162
+	RUN_TEST(test_positions_1);
163
+	RUN_TEST(test_positions_2);
164
+	RUN_TEST(test_positions_3);
165
+	RUN_TEST(test_positions_4);
166
+	RUN_TEST(test_positions_5);
167
+	RUN_TEST(test_positions_exact);
168
+}