vessel/tests/path-dynamic.c
2025-06-13 17:58:13 +03:00

122 lines
4 KiB
C

#include <stdio.h>
#include <string.h>
#include <vessel/path.h>
#include <vessel/main.h>
#define Err(...) \
{ \
fprintf(stderr, __VA_ARGS__); \
return 1; \
}
int main(void) {
uint64_t idx = 0;
HMap p = { 0 };
const char *expected[][4] = {
{ "/path/%s:name/", "/path/hello/", "name", "hello" },
{ "/%i:s", "/1244790962", "s", "1244790962" },
{ "/this/is/%f:test/floating", "/this/is/182.9481/floating", "test", "182.9481" },
{ "/this/is/%f:test/floating", "/this/is/182/floating", "test", "182" },
{ "/this/is/%d:test", "/this/is/999.81291", "test", "999.81291" },
{ "/hello/%p:ath", "/hello/world/this/is/a/test", "ath", "world/this/is/a/test" },
/* Additional test cases */
{ "/user/%s:name/", "/user/john_doe/", "name", "john_doe" },
{ "/item/%i:id/", "/item/42/", "id", "42" },
{ "/data/%f:value/", "/data/3.14/", "value", "3.14" },
{ "/measure/%d:value/", "/measure/123.456/", "value", "123.456" },
{ "/search/%p:query", "/search/some/query/here/", "query", "some/query/here/" },
/* Edge cases */
{ "/path/%s:name/", "/path//", "name", "" },
{ "/path/%i:id/", "/path/0/", "id", "0" },
/* Invalid cases */
{ "path/%i:id/", "/path/notanumber/", NULL, NULL },
{ "path/%i:id/", "/path/1-11-1/", NULL, NULL },
{ "path/%d:double/", "/path/123./", NULL, NULL },
{ "path/%f:double/", "/path/1-23/", NULL, NULL },
/* Testing minimum and maximum values (it's a string but still) */
{ "/max/%i:value/", "/max/2147483647/", "value", "2147483647" }, /* Max int */
{ "/min/%i:value/", "/min/-2147483648/", "value", "-2147483648" }, /* Min int */
/* Testing floating point edge cases */
{ "/float/%f:value/", "/float/0.0/", "value", "0.0" }, /* Zero float */
{ "/float/%f:value/", "/float/-1.2345/", "value", "-1.2345" }, /* Negative float */
/* Testing paths with special characters */
{ "/api/v1/users/%p:data",
"/api/v1/users/john.doe@example.com",
"data",
"john.doe@example.com" },
/* End of test cases */
{ 0 },
};
if (!Path_parse_init(&p)) {
perror("Failed to initialise the dynamic path parser");
return 1;
}
while (expected[idx][0]) {
HMapBucket *b;
printf("Testing: %35s | %35s =[%8s]=> %20s\n",
expected[idx][0],
expected[idx][1],
expected[idx][2] ? expected[idx][2] : "",
expected[idx][3] ? expected[idx][3] : "(intended failure)");
if (!HMap_clear(&p)) {
perror("Failed to clear HMap");
goto error;
}
if (expected[idx][2] == NULL) {
if (Path_parse_pattern(&p, expected[idx][0], expected[idx][1])) {
fprintf(stderr,
"Test %lu passed when it was not supposed to: %s\n",
idx,
expected[idx][0]);
goto error;
}
++idx;
continue;
}
if (!Path_parse_pattern(&p, expected[idx][0], expected[idx][1])) {
fprintf(stderr, "Failed to parse test %lu: %s\n", idx, expected[idx][0]);
goto error;
}
if ((b = HMap_find(&p, expected[idx][2])) == NULL) {
fprintf(stderr, "Failed to find key for test %lu: %s\n", idx, expected[idx][2]);
goto error;
}
if (strcmp(expected[idx][3], b->value) != 0) {
fprintf(stderr,
"Invalid value for key %s of test %lu: %s\n",
expected[idx][3],
idx,
(char *)b->value);
goto error;
}
++idx;
}
puts("All tests passed successfully :)");
Path_parse_destroy(&p);
return 0;
error:
Path_parse_destroy(&p);
return 1;
}