1
+#include "test-lib.h"
2
+#include "lib-oid.h"
3
+#include "oidtree.h"
4
+#include "hash.h"
5
+#include "hex.h"
6
+#include "strvec.h"
7
+
8
+#define FILL_TREE(tree, ...) \
9
+ do { \
10
+ const char *hexes[] = { __VA_ARGS__ }; \
11
+ if (fill_tree_loc(tree, hexes, ARRAY_SIZE(hexes))) \
12
+ return; \
13
+ } while (0)
14
+
15
+static int fill_tree_loc(struct oidtree *ot, const char *hexes[], size_t n)
16
+{
17
+ for (size_t i = 0; i < n; i++) {
18
+ struct object_id oid;
19
+ if (!check_int(get_oid_arbitrary_hex(hexes[i], &oid), ==, 0))
20
+ return -1;
21
+ oidtree_insert(ot, &oid);
22
+ }
23
+ return 0;
24
+}
25
+
26
+static void check_contains(struct oidtree *ot, const char *hex, int expected)
27
+{
28
+ struct object_id oid;
29
+
30
+ if (!check_int(get_oid_arbitrary_hex(hex, &oid), ==, 0))
31
+ return;
32
+ if (!check_int(oidtree_contains(ot, &oid), ==, expected))
33
+ test_msg("oid: %s", oid_to_hex(&oid));
34
+}
35
+
36
+struct expected_hex_iter {
37
+ size_t i;
38
+ struct strvec expected_hexes;
39
+ const char *query;
40
+};
41
+
42
+static enum cb_next check_each_cb(const struct object_id *oid, void *data)
43
+{
44
+ struct expected_hex_iter *hex_iter = data;
45
+ struct object_id expected;
46
+
47
+ if (!check_int(hex_iter->i, <, hex_iter->expected_hexes.nr)) {
48
+ test_msg("error: extraneous callback for query: ('%s'), object_id: ('%s')",
49
+ hex_iter->query, oid_to_hex(oid));
50
+ return CB_BREAK;
51
+ }
52
+
53
+ if (!check_int(get_oid_arbitrary_hex(hex_iter->expected_hexes.v[hex_iter->i],
54
+ &expected), ==, 0))
55
+ ; /* the data is bogus and cannot be used */
56
+ else if (!check(oideq(oid, &expected)))
57
+ test_msg("expected: %s\n got: %s\n query: %s",
58
+ oid_to_hex(&expected), oid_to_hex(oid), hex_iter->query);
59
+
60
+ hex_iter->i += 1;
61
+ return CB_CONTINUE;
62
+}
63
+
64
+LAST_ARG_MUST_BE_NULL
65
+static void check_each(struct oidtree *ot, const char *query, ...)
66
+{
67
+ struct object_id oid;
68
+ struct expected_hex_iter hex_iter = { .expected_hexes = STRVEC_INIT,
69
+ .query = query };
70
+ const char *arg;
71
+ va_list hex_args;
72
+
73
+ va_start(hex_args, query);
74
+ while ((arg = va_arg(hex_args, const char *)))
75
+ strvec_push(&hex_iter.expected_hexes, arg);
76
+ va_end(hex_args);
77
+
78
+ if (!check_int(get_oid_arbitrary_hex(query, &oid), ==, 0))
79
+ return;
80
+ oidtree_each(ot, &oid, strlen(query), check_each_cb, &hex_iter);
81
+
82
+ if (!check_int(hex_iter.i, ==, hex_iter.expected_hexes.nr))
83
+ test_msg("error: could not find some 'object_id's for query ('%s')", query);
84
+ strvec_clear(&hex_iter.expected_hexes);
85
+}
86
+
87
+static void setup(void (*f)(struct oidtree *ot))
88
+{
89
+ struct oidtree ot;
90
+
91
+ oidtree_init(&ot);
92
+ f(&ot);
93
+ oidtree_clear(&ot);
94
+}
95
+
96
+static void t_contains(struct oidtree *ot)
97
+{
98
+ FILL_TREE(ot, "444", "1", "2", "3", "4", "5", "a", "b", "c", "d", "e");
99
+ check_contains(ot, "44", 0);
100
+ check_contains(ot, "441", 0);
101
+ check_contains(ot, "440", 0);
102
+ check_contains(ot, "444", 1);
103
+ check_contains(ot, "4440", 1);
104
+ check_contains(ot, "4444", 0);
105
+}
106
+
107
+static void t_each(struct oidtree *ot)
108
+{
109
+ FILL_TREE(ot, "f", "9", "8", "123", "321", "320", "a", "b", "c", "d", "e");
110
+ check_each(ot, "12300", "123", NULL);
111
+ check_each(ot, "3211", NULL); /* should not reach callback */
112
+ check_each(ot, "3210", "321", NULL);
113
+ check_each(ot, "32100", "321", NULL);
114
+ check_each(ot, "32", "320", "321", NULL);
115
+}
116
+
117
+int cmd_main(int argc UNUSED, const char **argv UNUSED)
118
+{
119
+ TEST(setup(t_contains), "oidtree insert and contains works");
120
+ TEST(setup(t_each), "oidtree each works");
121
+ return test_done();
122
+}