|
1 |
|
2 #include <stdlib.h> |
|
3 #include <stdio.h> |
|
4 #include <string.h> |
|
5 |
|
6 #include "lib/url.h" |
|
7 |
|
8 #define FAIL(...) do { printf("FAIL: "); printf(__VA_ARGS__); return -1; } while (0) |
|
9 |
|
10 |
|
11 struct url_test { |
|
12 const char *url; |
|
13 const struct url expected; |
|
14 } url_tests[] = { |
|
15 { "localhost:http", { |
|
16 NULL, NULL, NULL, "localhost", "http", NULL, NULL |
|
17 } }, |
|
18 |
|
19 /* { "http://example.com/path", { |
|
20 { 1, { "http" } }, NULL, NULL, "example.com", NULL, "path", NULL |
|
21 } }, */ |
|
22 |
|
23 { NULL, { } }, |
|
24 }; |
|
25 |
|
26 int cmp_url_str (const char *field, const char *test, const char *real) { |
|
27 if (!test) { |
|
28 if (real) |
|
29 FAIL("%s: shouldn't be present", field); |
|
30 |
|
31 } else if (!real) { |
|
32 FAIL("%s: missing", field); |
|
33 |
|
34 } else { |
|
35 if (strcmp(test, real) != 0) |
|
36 FAIL("%s: differs: %s -> %s", field, test, real); |
|
37 } |
|
38 |
|
39 // ok |
|
40 return 0; |
|
41 } |
|
42 |
|
43 int cmp_url (const struct url *test, const struct url *real) { |
|
44 int i; |
|
45 |
|
46 // test schema |
|
47 if (!test->schema) { |
|
48 if (real->schema) |
|
49 FAIL("test has no schema, but real does"); |
|
50 |
|
51 } else if (!real->schema) { |
|
52 FAIL("test has a schema, but real doesn't"); |
|
53 |
|
54 } else { |
|
55 if (test->schema->count != test->schema->count) |
|
56 FAIL("inconsistent scheme count"); |
|
57 |
|
58 for (i = 0; i < test->schema->count; i++) { |
|
59 if (strcmp(test->schema->list[i], real->schema->list[i]) != 0) |
|
60 FAIL("differing scheme #%d", i); |
|
61 } |
|
62 } |
|
63 |
|
64 // test username |
|
65 if (cmp_url_str("username", test->username, real->username)) |
|
66 goto error; |
|
67 |
|
68 // test password |
|
69 if (cmp_url_str("password", test->password, real->password)) |
|
70 goto error; |
|
71 |
|
72 // test hostname |
|
73 if (cmp_url_str("hostname", test->hostname, real->hostname)) |
|
74 goto error; |
|
75 |
|
76 // test service |
|
77 if (cmp_url_str("service", test->service, real->service)) |
|
78 goto error; |
|
79 |
|
80 // test path |
|
81 if (cmp_url_str("path", test->path, real->path)) |
|
82 goto error; |
|
83 |
|
84 // test query |
|
85 if (!test->opts) { |
|
86 if (real->opts) |
|
87 FAIL("test has no opts, but real does"); |
|
88 |
|
89 } else if (!real->opts) { |
|
90 FAIL("test has opts, but real doesn't"); |
|
91 |
|
92 } else { |
|
93 if (test->opts->count != test->opts->count) |
|
94 FAIL("inconsistent opts count"); |
|
95 |
|
96 for (i = 0; i < test->opts->count; i++) { |
|
97 if (strcmp(test->opts->list[i]->key, real->opts->list[i]->key) != 0) |
|
98 FAIL("differing scheme key #%d", i); |
|
99 |
|
100 if (strcmp(test->opts->list[i]->value, real->opts->list[i]->value) != 0) |
|
101 FAIL("differing scheme value #%d", i); |
|
102 } |
|
103 } |
|
104 |
|
105 // ok |
|
106 return 0; |
|
107 |
|
108 error: |
|
109 return -1; |
|
110 } |
|
111 |
|
112 void print_url_part (const char *field, const char *val) { |
|
113 if (val) { |
|
114 printf("%s=%s ", field, val); |
|
115 } |
|
116 } |
|
117 |
|
118 void print_url (const struct url *url) { |
|
119 int i; |
|
120 |
|
121 if (url->schema) { |
|
122 printf("schema="); |
|
123 |
|
124 for (i = 0; i < url->schema->count; i++) { |
|
125 if (i > 0) |
|
126 printf("+"); |
|
127 |
|
128 printf("%s", url->schema->list[i]); |
|
129 } |
|
130 |
|
131 printf(" "); |
|
132 } |
|
133 |
|
134 print_url_part("username", url->username); |
|
135 print_url_part("password", url->password); |
|
136 print_url_part("hostname", url->hostname); |
|
137 print_url_part("service", url->service); |
|
138 print_url_part("path", url->path); |
|
139 |
|
140 if (url->opts) { |
|
141 printf("opts: "); |
|
142 |
|
143 for (i = 0; i < url->opts->count; i++) { |
|
144 printf("%s=%s ", url->opts->list[i]->key, url->opts->list[i]->value); |
|
145 } |
|
146 } |
|
147 |
|
148 printf("\n"); |
|
149 } |
|
150 |
|
151 void usage (const char *exec_name) { |
|
152 printf("Usage: %s\n\n\tNo arguments are accepted\n", exec_name); |
|
153 |
|
154 exit(EXIT_FAILURE); |
|
155 } |
|
156 |
|
157 int main (int argc, char **argv) { |
|
158 const struct url_test *test; |
|
159 struct url url; |
|
160 |
|
161 if (argc > 1) |
|
162 usage(argv[0]); |
|
163 |
|
164 // run the tests |
|
165 for (test = url_tests; test->url; test++) { |
|
166 // first output the URL we are handling... |
|
167 printf("%s... ", test->url); |
|
168 fflush(stdout); |
|
169 |
|
170 // parse the URL |
|
171 memset(&url, 0, sizeof(url)); |
|
172 |
|
173 if (url_parse(&url, test->url)) { |
|
174 printf("FATAL: url_parse failed\n"); |
|
175 return EXIT_FAILURE; |
|
176 } |
|
177 |
|
178 // compare it |
|
179 if (cmp_url(&test->expected, &url)) { |
|
180 printf("\texpected: "); |
|
181 print_url(&test->expected); |
|
182 |
|
183 printf("\tresult: "); |
|
184 print_url(&url); |
|
185 |
|
186 } else { |
|
187 printf("OK\n\t"); |
|
188 print_url(&url); |
|
189 } |
|
190 } |
|
191 } |
|
192 |