xref: /freebsd/contrib/pkgconf/tests/api/test-dependency.c (revision 592efe252472a3385acf36b1f49ecf710a7f3d9c)
1 /*
2  * test-dependency.c
3  * Tests for the public libpkgconf dependency API.
4  *
5  * SPDX-License-Identifier: pkgconf
6  *
7  * Copyright (c) 2026 pkgconf authors (see AUTHORS).
8  *
9  * Permission to use, copy, modify, and/or distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * This software is provided 'as is' and without any warranty, express or
14  * implied.  In no event shall the authors be liable for any damages arising
15  * from the use of this software.
16  */
17 
18 #include "test-api.h"
19 
20 static size_t
dependency_count(const pkgconf_list_t * list)21 dependency_count(const pkgconf_list_t *list)
22 {
23 	size_t n = 0;
24 	const pkgconf_node_t *iter;
25 
26 	PKGCONF_FOREACH_LIST_ENTRY(list->head, iter)
27 	{
28 		n++;
29 	}
30 
31 	return n;
32 }
33 
34 static const pkgconf_dependency_t *
dependency_at(const pkgconf_list_t * list,size_t index)35 dependency_at(const pkgconf_list_t *list, size_t index)
36 {
37 	const pkgconf_node_t *iter;
38 	size_t i = 0;
39 
40 	PKGCONF_FOREACH_LIST_ENTRY(list->head, iter)
41 	{
42 		if (i++ == index)
43 			return iter->data;
44 	}
45 
46 	return NULL;
47 }
48 
49 static void
test_comparator_lookup_known(void)50 test_comparator_lookup_known(void)
51 {
52 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name("="), PKGCONF_CMP_EQUAL);
53 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name("!="), PKGCONF_CMP_NOT_EQUAL);
54 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name("<"), PKGCONF_CMP_LESS_THAN);
55 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name("<="), PKGCONF_CMP_LESS_THAN_EQUAL);
56 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name(">"), PKGCONF_CMP_GREATER_THAN);
57 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name(">="), PKGCONF_CMP_GREATER_THAN_EQUAL);
58 }
59 
60 static void
test_comparator_lookup_unknown(void)61 test_comparator_lookup_unknown(void)
62 {
63 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name("~~"), PKGCONF_CMP_ANY);
64 	TEST_ASSERT_EQ(pkgconf_pkg_comparator_lookup_by_name(""), PKGCONF_CMP_ANY);
65 }
66 
67 static void
test_comparator_roundtrip(void)68 test_comparator_roundtrip(void)
69 {
70 	pkgconf_pkg_comparator_t values[] =
71 	{
72 		PKGCONF_CMP_NOT_EQUAL,
73 		PKGCONF_CMP_ANY,
74 		PKGCONF_CMP_LESS_THAN,
75 		PKGCONF_CMP_LESS_THAN_EQUAL,
76 		PKGCONF_CMP_EQUAL,
77 		PKGCONF_CMP_GREATER_THAN,
78 		PKGCONF_CMP_GREATER_THAN_EQUAL,
79 	};
80 
81 	for (size_t i = 0; i < PKGCONF_ARRAY_SIZE(values); i++)
82 	{
83 		pkgconf_dependency_t dep = { 0 };
84 		dep.compare = values[i];
85 
86 		const char *str = pkgconf_pkg_get_comparator(&dep);
87 		TEST_ASSERT_NONNULL(str);
88 
89 		// ANY's value does not round-trip so do not check
90 		if (values[i] == PKGCONF_CMP_ANY)
91 			continue;
92 
93 		pkgconf_pkg_comparator_t back = pkgconf_pkg_comparator_lookup_by_name(str);
94 		TEST_ASSERT_EQ(back, values[i]);
95 	}
96 }
97 
98 static void
test_parse_str_single(void)99 test_parse_str_single(void)
100 {
101 	pkgconf_client_t *client = test_client_new();
102 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
103 
104 	pkgconf_dependency_parse_str(client, &deps, "foo", 0);
105 
106 	TEST_ASSERT_EQ(dependency_count(&deps), 1);
107 	const pkgconf_dependency_t *d = dependency_at(&deps, 0);
108 	TEST_ASSERT_NONNULL(d);
109 	TEST_ASSERT_STRCMP_EQ(d->package, "foo");
110 	TEST_ASSERT_EQ(d->compare, PKGCONF_CMP_ANY);
111 	TEST_ASSERT_NULL(d->version);
112 
113 	pkgconf_dependency_free(&deps);
114 	pkgconf_client_free(client);
115 }
116 
117 static void
test_parse_str_versioned(void)118 test_parse_str_versioned(void)
119 {
120 	pkgconf_client_t *client = test_client_new();
121 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
122 
123 	pkgconf_dependency_parse_str(client, &deps, "foo >= 1.2.3", 0);
124 
125 	TEST_ASSERT_EQ(dependency_count(&deps), 1);
126 	const pkgconf_dependency_t *d = dependency_at(&deps, 0);
127 	TEST_ASSERT_NONNULL(d);
128 	TEST_ASSERT_STRCMP_EQ(d->package, "foo");
129 	TEST_ASSERT_EQ(d->compare, PKGCONF_CMP_GREATER_THAN_EQUAL);
130 	TEST_ASSERT_STRCMP_EQ(d->version, "1.2.3");
131 
132 	pkgconf_dependency_free(&deps);
133 	pkgconf_client_free(client);
134 }
135 
136 static void
test_parse_str_multiple_space_separated(void)137 test_parse_str_multiple_space_separated(void)
138 {
139 	pkgconf_client_t *client = test_client_new();
140 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
141 
142 	pkgconf_dependency_parse_str(client, &deps, "foo bar baz", 0);
143 
144 	TEST_ASSERT_EQ(dependency_count(&deps), 3);
145 
146 	const pkgconf_dependency_t *d0 = dependency_at(&deps, 0);
147 	const pkgconf_dependency_t *d1 = dependency_at(&deps, 1);
148 	const pkgconf_dependency_t *d2 = dependency_at(&deps, 2);
149 	TEST_ASSERT_NONNULL(d0);
150 	TEST_ASSERT_NONNULL(d1);
151 	TEST_ASSERT_NONNULL(d2);
152 	TEST_ASSERT_STRCMP_EQ(d0->package, "foo");
153 	TEST_ASSERT_STRCMP_EQ(d1->package, "bar");
154 	TEST_ASSERT_STRCMP_EQ(d2->package, "baz");
155 
156 	pkgconf_dependency_free(&deps);
157 	pkgconf_client_free(client);
158 }
159 
160 static void
test_parse_str_multiple_comma_separated(void)161 test_parse_str_multiple_comma_separated(void)
162 {
163 	pkgconf_client_t *client = test_client_new();
164 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
165 
166 	pkgconf_dependency_parse_str(client, &deps, "foo, bar, baz", 0);
167 
168 	TEST_ASSERT_EQ(dependency_count(&deps), 3);
169 
170 	const pkgconf_dependency_t *d0 = dependency_at(&deps, 0);
171 	const pkgconf_dependency_t *d1 = dependency_at(&deps, 1);
172 	const pkgconf_dependency_t *d2 = dependency_at(&deps, 2);
173 	TEST_ASSERT_NONNULL(d0);
174 	TEST_ASSERT_NONNULL(d1);
175 	TEST_ASSERT_NONNULL(d2);
176 	TEST_ASSERT_STRCMP_EQ(d0->package, "foo");
177 	TEST_ASSERT_STRCMP_EQ(d1->package, "bar");
178 	TEST_ASSERT_STRCMP_EQ(d2->package, "baz");
179 
180 	pkgconf_dependency_free(&deps);
181 	pkgconf_client_free(client);
182 }
183 
184 static void
test_parse_str_mixed_versioned_and_bare(void)185 test_parse_str_mixed_versioned_and_bare(void)
186 {
187 	pkgconf_client_t *client = test_client_new();
188 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
189 
190 	pkgconf_dependency_parse_str(client, &deps, "foo >= 1.0, bar, baz < 2.0", 0);
191 
192 	TEST_ASSERT_EQ(dependency_count(&deps), 3);
193 
194 	const pkgconf_dependency_t *d0 = dependency_at(&deps, 0);
195 	const pkgconf_dependency_t *d1 = dependency_at(&deps, 1);
196 	const pkgconf_dependency_t *d2 = dependency_at(&deps, 2);
197 
198 	TEST_ASSERT_NONNULL(d0);
199 	TEST_ASSERT_NONNULL(d1);
200 	TEST_ASSERT_NONNULL(d2);
201 
202 	TEST_ASSERT_STRCMP_EQ(d0->package, "foo");
203 	TEST_ASSERT_EQ(d0->compare, PKGCONF_CMP_GREATER_THAN_EQUAL);
204 	TEST_ASSERT_STRCMP_EQ(d0->version, "1.0");
205 
206 	TEST_ASSERT_STRCMP_EQ(d1->package, "bar");
207 	TEST_ASSERT_EQ(d1->compare, PKGCONF_CMP_ANY);
208 
209 	TEST_ASSERT_STRCMP_EQ(d2->package, "baz");
210 	TEST_ASSERT_EQ(d2->compare, PKGCONF_CMP_LESS_THAN);
211 	TEST_ASSERT_STRCMP_EQ(d2->version, "2.0");
212 
213 	pkgconf_dependency_free(&deps);
214 	pkgconf_client_free(client);
215 }
216 
217 static void
test_parse_str_empty(void)218 test_parse_str_empty(void)
219 {
220 	pkgconf_client_t *client = test_client_new();
221 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
222 
223 	pkgconf_dependency_parse_str(client, &deps, "", 0);
224 	TEST_ASSERT_EQ(dependency_count(&deps), 0);
225 
226 	pkgconf_dependency_free(&deps);
227 	pkgconf_client_free(client);
228 }
229 
230 static void
test_parse_str_all_comparators(void)231 test_parse_str_all_comparators(void)
232 {
233 	pkgconf_client_t *client = test_client_new();
234 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
235 
236 	pkgconf_dependency_parse_str(client, &deps, "a = 1, b != 2, c < 3, d <= 4, e > 5, f >= 6", 0);
237 
238 	TEST_ASSERT_EQ(dependency_count(&deps), 6);
239 
240 	const pkgconf_dependency_t *d0 = dependency_at(&deps, 0);
241 	const pkgconf_dependency_t *d1 = dependency_at(&deps, 1);
242 	const pkgconf_dependency_t *d2 = dependency_at(&deps, 2);
243 	const pkgconf_dependency_t *d3 = dependency_at(&deps, 3);
244 	const pkgconf_dependency_t *d4 = dependency_at(&deps, 4);
245 	const pkgconf_dependency_t *d5 = dependency_at(&deps, 5);
246 
247 	TEST_ASSERT_NONNULL(d0);
248 	TEST_ASSERT_NONNULL(d1);
249 	TEST_ASSERT_NONNULL(d2);
250 	TEST_ASSERT_NONNULL(d3);
251 	TEST_ASSERT_NONNULL(d4);
252 	TEST_ASSERT_NONNULL(d5);
253 
254 	TEST_ASSERT_EQ(d0->compare, PKGCONF_CMP_EQUAL);
255 	TEST_ASSERT_EQ(d1->compare, PKGCONF_CMP_NOT_EQUAL);
256 	TEST_ASSERT_EQ(d2->compare, PKGCONF_CMP_LESS_THAN);
257 	TEST_ASSERT_EQ(d3->compare, PKGCONF_CMP_LESS_THAN_EQUAL);
258 	TEST_ASSERT_EQ(d4->compare, PKGCONF_CMP_GREATER_THAN);
259 	TEST_ASSERT_EQ(d5->compare, PKGCONF_CMP_GREATER_THAN_EQUAL);
260 
261 	pkgconf_dependency_free(&deps);
262 	pkgconf_client_free(client);
263 }
264 
265 static void
test_dependency_add(void)266 test_dependency_add(void)
267 {
268 	pkgconf_client_t *client = test_client_new();
269 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
270 
271 	pkgconf_dependency_t *d = pkgconf_dependency_add(client, &deps, "foo", "1.0", PKGCONF_CMP_GREATER_THAN_EQUAL, 0);
272 	TEST_ASSERT_NONNULL(d);
273 	TEST_ASSERT_STRCMP_EQ(d->package, "foo");
274 	TEST_ASSERT_STRCMP_EQ(d->version, "1.0");
275 	TEST_ASSERT_EQ(d->compare, PKGCONF_CMP_GREATER_THAN_EQUAL);
276 
277 	TEST_ASSERT_EQ(dependency_count(&deps), 1);
278 
279 	pkgconf_dependency_unref(client, d);
280 	pkgconf_dependency_free(&deps);
281 	pkgconf_client_free(client);
282 }
283 
284 static void
test_dependency_add_no_version(void)285 test_dependency_add_no_version(void)
286 {
287 	pkgconf_client_t *client = test_client_new();
288 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
289 
290 	pkgconf_dependency_t *d = pkgconf_dependency_add(client, &deps, "foo", NULL, PKGCONF_CMP_ANY, 0);
291 	TEST_ASSERT_NONNULL(d);
292 	TEST_ASSERT_STRCMP_EQ(d->package, "foo");
293 	TEST_ASSERT_EQ(d->compare, PKGCONF_CMP_ANY);
294 
295 	pkgconf_dependency_unref(client, d);
296 	pkgconf_dependency_free(&deps);
297 	pkgconf_client_free(client);
298 }
299 
300 static void
test_dependency_add_multiple(void)301 test_dependency_add_multiple(void)
302 {
303 	pkgconf_client_t *client = test_client_new();
304 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
305 
306 	pkgconf_dependency_t *d0 = pkgconf_dependency_add(client, &deps, "foo", NULL, PKGCONF_CMP_ANY, 0);
307 	pkgconf_dependency_t *d1 = pkgconf_dependency_add(client, &deps, "bar", "2.0", PKGCONF_CMP_EQUAL, 0);
308 	pkgconf_dependency_t *d2 = pkgconf_dependency_add(client, &deps, "baz", "3.0", PKGCONF_CMP_LESS_THAN, 0);
309 
310 	TEST_ASSERT_NONNULL(d0);
311 	TEST_ASSERT_NONNULL(d1);
312 	TEST_ASSERT_NONNULL(d2);
313 
314 	TEST_ASSERT_EQ(dependency_count(&deps), 3);
315 
316 	pkgconf_dependency_unref(client, d0);
317 	pkgconf_dependency_unref(client, d1);
318 	pkgconf_dependency_unref(client, d2);
319 	pkgconf_dependency_free(&deps);
320 	pkgconf_client_free(client);
321 }
322 
323 static void
test_dependency_collision_drops_flagged_newcomer(void)324 test_dependency_collision_drops_flagged_newcomer(void)
325 {
326 	pkgconf_client_t *client = test_client_new();
327 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
328 
329 	pkgconf_dependency_t *first = pkgconf_dependency_add(client, &deps, "foo", "1.0", PKGCONF_CMP_EQUAL, 0);
330 	TEST_ASSERT_NONNULL(first);
331 	TEST_ASSERT_EQ(dependency_count(&deps), 1);
332 
333 	/* Adding the same dep WITH flags collides; the flagged newcomer
334 	 * is dropped in favour of the existing unflagged node, so _add
335 	 * returns NULL and the count stays at 1 */
336 	pkgconf_dependency_t *second = pkgconf_dependency_add(client, &deps, "foo", "1.0", PKGCONF_CMP_EQUAL, PKGCONF_PKG_DEPF_INTERNAL);
337 	TEST_ASSERT_NULL(second);
338 	TEST_ASSERT_EQ(dependency_count(&deps), 1);
339 
340 	pkgconf_dependency_unref(client, first);
341 	pkgconf_dependency_free(&deps);
342 	pkgconf_client_free(client);
343 }
344 
345 static void
test_dependency_collision_drops_flagged_existing(void)346 test_dependency_collision_drops_flagged_existing(void)
347 {
348 	pkgconf_client_t *client = test_client_new();
349 	pkgconf_list_t deps = PKGCONF_LIST_INITIALIZER;
350 
351 	pkgconf_dependency_t *first = pkgconf_dependency_add(client, &deps, "foo", "1.0", PKGCONF_CMP_EQUAL, PKGCONF_PKG_DEPF_INTERNAL);
352 	TEST_ASSERT_NONNULL(first);
353 	TEST_ASSERT_EQ(dependency_count(&deps), 1);
354 
355 	/* Adding the same dep UNFLAGGED collides; the existing flagged
356 	 * node is deleted and unref'd, the unflagged newcomer takes its
357 	 * place; count stays at 1, but the node is now the new one */
358 	pkgconf_dependency_t *second = pkgconf_dependency_add(client, &deps, "foo", "1.0", PKGCONF_CMP_EQUAL, 0);
359 	TEST_ASSERT_NONNULL(second);
360 	TEST_ASSERT_EQ(dependency_count(&deps), 1);
361 	TEST_ASSERT_EQ(second->flags, 0);
362 
363 	pkgconf_dependency_unref(client, first);
364 	pkgconf_dependency_unref(client, second);
365 	pkgconf_dependency_free(&deps);
366 	pkgconf_client_free(client);
367 }
368 
369 static void
test_version_equal(void)370 test_version_equal(void)
371 {
372 	TEST_ASSERT_EQ(pkgconf_compare_version("1.0", "1.0"), 0);
373 	TEST_ASSERT_EQ(pkgconf_compare_version("1.2.3", "1.2.3"), 0);
374 	TEST_ASSERT_EQ(pkgconf_compare_version("", ""), 0);
375 }
376 
377 static void
test_version_simple_numeric(void)378 test_version_simple_numeric(void)
379 {
380 	TEST_ASSERT_LT(pkgconf_compare_version("1.0", "1.1"), 0);
381 	TEST_ASSERT_GT(pkgconf_compare_version("1.1", "1.0"), 0);
382 
383 	TEST_ASSERT_LT(pkgconf_compare_version("1.0", "2.0"), 0);
384 	TEST_ASSERT_GT(pkgconf_compare_version("2.0", "1.0"), 0);
385 
386 	TEST_ASSERT_LT(pkgconf_compare_version("1.2.3", "1.2.4"), 0);
387 	TEST_ASSERT_LT(pkgconf_compare_version("1.2.3", "1.3.0"), 0);
388 	TEST_ASSERT_LT(pkgconf_compare_version("1.2.3", "2.0.0"), 0);
389 }
390 
391 static void
test_version_numeric_segments_not_lexical(void)392 test_version_numeric_segments_not_lexical(void)
393 {
394 	TEST_ASSERT_GT(pkgconf_compare_version("1.10", "1.9"), 0);
395 	TEST_ASSERT_GT(pkgconf_compare_version("1.100", "1.99"), 0);
396 }
397 
398 static void
test_version_different_lengths(void)399 test_version_different_lengths(void)
400 {
401 	TEST_ASSERT_LT(pkgconf_compare_version("1.0", "1.0.1"), 0);
402 	TEST_ASSERT_GT(pkgconf_compare_version("1.0.1", "1.0"), 0);
403 }
404 
405 static void
test_version_alpha_suffix(void)406 test_version_alpha_suffix(void)
407 {
408 	TEST_ASSERT_GT(pkgconf_compare_version("1.0a", "1.0"), 0);
409 	TEST_ASSERT_GT(pkgconf_compare_version("1.0alpha", "1.0"), 0);
410 	TEST_ASSERT_GT(pkgconf_compare_version("1.0rc1", "1.0"), 0);
411 
412 	TEST_ASSERT_LT(pkgconf_compare_version("1.0alpha", "1.0beta"), 0);
413 	TEST_ASSERT_LT(pkgconf_compare_version("1.0beta", "1.0rc"), 0);
414 }
415 
416 static void
test_version_tilde_prerelease(void)417 test_version_tilde_prerelease(void)
418 {
419 	TEST_ASSERT_LT(pkgconf_compare_version("1.0~rc1", "1.0"), 0);
420 	TEST_ASSERT_LT(pkgconf_compare_version("1.0~alpha", "1.0"), 0);
421 	TEST_ASSERT_LT(pkgconf_compare_version("1.0~beta", "1.0~rc"), 0);
422 
423 	TEST_ASSERT_LT(pkgconf_compare_version("1.0~rc1", "1.0rc1"), 0);
424 }
425 
426 static void
test_version_numeric_beats_alpha(void)427 test_version_numeric_beats_alpha(void)
428 {
429 	TEST_ASSERT_GT(pkgconf_compare_version("1.0.1", "1.0a"), 0);
430 	TEST_ASSERT_LT(pkgconf_compare_version("1.0a", "1.0.1"), 0);
431 }
432 
433 static void
test_version_alpha_ordering(void)434 test_version_alpha_ordering(void)
435 {
436 	TEST_ASSERT_LT(pkgconf_compare_version("1.0a", "1.0b"), 0);
437 	TEST_ASSERT_GT(pkgconf_compare_version("1.0b", "1.0a"), 0);
438 }
439 
440 static void
test_version_dotted_vs_hyphenated(void)441 test_version_dotted_vs_hyphenated(void)
442 {
443 	TEST_ASSERT_EQ(pkgconf_compare_version("1.0-1", "1.0.1"), 0);
444 }
445 
446 static void
test_version_leading_zeros(void)447 test_version_leading_zeros(void)
448 {
449 	TEST_ASSERT_EQ(pkgconf_compare_version("1.01", "1.1"), 0);
450 	TEST_ASSERT_EQ(pkgconf_compare_version("01.0", "1.0"), 0);
451 }
452 
453 static void
test_version_trailing_zero_segments(void)454 test_version_trailing_zero_segments(void)
455 {
456 	/* Pkgconf does NOT treat "1.0" and "1.0.0" as equivalent.
457 	 * Even a zero trailing numeric segment is additional content that makes the version greater.
458 	 */
459 	TEST_ASSERT_LT(pkgconf_compare_version("1.0", "1.0.0"), 0);
460 	TEST_ASSERT_GT(pkgconf_compare_version("1.0.0", "1.0"), 0);
461 	TEST_ASSERT_LT(pkgconf_compare_version("1", "1.0"), 0);
462 	TEST_ASSERT_LT(pkgconf_compare_version("1", "1.0.0.0"), 0);
463 }
464 
465 static void
test_version_null_handling(void)466 test_version_null_handling(void)
467 {
468 	TEST_ASSERT_LT(pkgconf_compare_version(NULL, "1.0"), 0);
469 	TEST_ASSERT_GT(pkgconf_compare_version("1.0", NULL), 0);
470 	TEST_ASSERT_LT(pkgconf_compare_version(NULL, NULL), 0);
471 }
472 
473 static void
test_version_tilde_both_sides(void)474 test_version_tilde_both_sides(void)
475 {
476 	TEST_ASSERT_LT(pkgconf_compare_version("1.0~", "1.0a"), 0);
477 	TEST_ASSERT_GT(pkgconf_compare_version("1.0a", "1.0~"), 0);
478 
479 	TEST_ASSERT_EQ(pkgconf_compare_version("1.0~rc", "1.0~rc"), 0);
480 	TEST_ASSERT_LT(pkgconf_compare_version("1.0~a", "1.0~b"), 0);
481 	TEST_ASSERT_LT(pkgconf_compare_version("1.0~1", "1.0~2"), 0);
482 }
483 
484 static void
test_version_separator_equivalence(void)485 test_version_separator_equivalence(void)
486 {
487 	TEST_ASSERT_EQ(pkgconf_compare_version("1.0", "1-0"), 0);
488 	TEST_ASSERT_EQ(pkgconf_compare_version("1.2.3", "1_2_3"), 0);
489 	TEST_ASSERT_EQ(pkgconf_compare_version("1..2", "1.2"), 0);
490 }
491 
492 static void
test_version_case_insensitive(void)493 test_version_case_insensitive(void)
494 {
495 	TEST_ASSERT_EQ(pkgconf_compare_version("1.0RC1", "1.0rc1"), 0);
496 	TEST_ASSERT_EQ(pkgconf_compare_version("1.0A", "1.0a"), 0);
497 }
498 
499 static void
test_version_alpha_prefix(void)500 test_version_alpha_prefix(void)
501 {
502 	TEST_ASSERT_LT(pkgconf_compare_version("1.0alpha", "1.0alphabeta"), 0);
503 	TEST_ASSERT_GT(pkgconf_compare_version("1.0alphabeta", "1.0alpha"), 0);
504 
505 	TEST_ASSERT_LT(pkgconf_compare_version("1.0a", "1.0ab"), 0);
506 	TEST_ASSERT_GT(pkgconf_compare_version("1.0ab", "1.0a"), 0);
507 }
508 
509 int
main(int argc,char * argv[])510 main(int argc, char *argv[])
511 {
512 	(void) argc;
513 	const char *basename = pkgconf_path_find_basename(argv[0]);
514 
515 	TEST_RUN(basename, test_comparator_lookup_known);
516 	TEST_RUN(basename, test_comparator_lookup_unknown);
517 	TEST_RUN(basename, test_comparator_roundtrip);
518 
519 	TEST_RUN(basename, test_parse_str_empty);
520 	TEST_RUN(basename, test_parse_str_single);
521 	TEST_RUN(basename, test_parse_str_versioned);
522 	TEST_RUN(basename, test_parse_str_multiple_space_separated);
523 	TEST_RUN(basename, test_parse_str_multiple_comma_separated);
524 	TEST_RUN(basename, test_parse_str_mixed_versioned_and_bare);
525 	TEST_RUN(basename, test_parse_str_all_comparators);
526 
527 	TEST_RUN(basename, test_dependency_add);
528 	TEST_RUN(basename, test_dependency_add_no_version);
529 	TEST_RUN(basename, test_dependency_add_multiple);
530 	TEST_RUN(basename, test_dependency_collision_drops_flagged_newcomer);
531 	TEST_RUN(basename, test_dependency_collision_drops_flagged_existing);
532 
533 	TEST_RUN(basename, test_version_equal);
534 	TEST_RUN(basename, test_version_simple_numeric);
535 	TEST_RUN(basename, test_version_numeric_segments_not_lexical);
536 	TEST_RUN(basename, test_version_different_lengths);
537 	TEST_RUN(basename, test_version_alpha_suffix);
538 	TEST_RUN(basename, test_version_tilde_prerelease);
539 	TEST_RUN(basename, test_version_numeric_beats_alpha);
540 	TEST_RUN(basename, test_version_alpha_ordering);
541 	TEST_RUN(basename, test_version_dotted_vs_hyphenated);
542 	TEST_RUN(basename, test_version_leading_zeros);
543 	TEST_RUN(basename, test_version_trailing_zero_segments);
544 	TEST_RUN(basename, test_version_null_handling);
545 	TEST_RUN(basename, test_version_tilde_both_sides);
546 	TEST_RUN(basename, test_version_separator_equivalence);
547 	TEST_RUN(basename, test_version_case_insensitive);
548 	TEST_RUN(basename, test_version_alpha_prefix);
549 
550 	return EXIT_SUCCESS;
551 }
552