diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/json.c | 97 | ||||
-rw-r--r-- | test/linked_list.c | 162 |
2 files changed, 259 insertions, 0 deletions
diff --git a/test/json.c b/test/json.c new file mode 100644 index 0000000000..0a4462bc21 --- /dev/null +++ b/test/json.c @@ -0,0 +1,97 @@ +#include "test_helpers.h" + +#include "common/common.h" +#include "misc/json.h" +#include "misc/node.h" + +struct entry { + const char *src; + const char *out_txt; + struct mpv_node out_data; + bool expect_fail; +}; + +#define TEXT(...) #__VA_ARGS__ + +#define VAL_LIST(...) (struct mpv_node[]){__VA_ARGS__} + +#define L(...) __VA_ARGS__ + +#define NODE_INT64(v) {.format = MPV_FORMAT_INT64, .u = { .int64 = (v) }} +#define NODE_STR(v) {.format = MPV_FORMAT_STRING, .u = { .string = (v) }} +#define NODE_BOOL(v) {.format = MPV_FORMAT_FLAG, .u = { .flag = (bool)(v) }} +#define NODE_FLOAT(v) {.format = MPV_FORMAT_DOUBLE, .u = { .double_ = (v) }} +#define NODE_NONE() {.format = MPV_FORMAT_NONE } +#define NODE_ARRAY(...) {.format = MPV_FORMAT_NODE_ARRAY, .u = { .list = \ + &(struct mpv_node_list) { \ + .num = sizeof(VAL_LIST(__VA_ARGS__)) / sizeof(struct mpv_node), \ + .values = VAL_LIST(__VA_ARGS__)}}} +#define NODE_MAP(k, v) {.format = MPV_FORMAT_NODE_MAP, .u = { .list = \ + &(struct mpv_node_list) { \ + .num = sizeof(VAL_LIST(v)) / sizeof(struct mpv_node), \ + .values = VAL_LIST(v), \ + .keys = (char**)(const char *[]){k}}}} + +static const struct entry entries[] = { + { "null", "null", NODE_NONE()}, + { "true", "true", NODE_BOOL(true)}, + { "false", "false", NODE_BOOL(false)}, + { "", .expect_fail = true}, + { "abc", .expect_fail = true}, + { " 123 ", "123", NODE_INT64(123)}, + { "123.25", "123.250000", NODE_FLOAT(123.25)}, + { TEXT("a\n\\\/\\\""), TEXT("a\n\\/\\\""), NODE_STR("a\n\\/\\\"")}, + { TEXT("a\u2c29"), TEXT("aⰩ"), NODE_STR("a\342\260\251")}, + { "[1,2,3]", "[1,2,3]", + NODE_ARRAY(NODE_INT64(1), NODE_INT64(2), NODE_INT64(3))}, + { "[ ]", "[]", NODE_ARRAY()}, + { "[1,,2]", .expect_fail = true}, + { "[,]", .expect_fail = true}, + { TEXT({"a":1, "b":2}), TEXT({"a":1,"b":2}), + NODE_MAP(L("a", "b"), L(NODE_INT64(1), NODE_INT64(2)))}, + { "{ }", "{}", NODE_MAP(L(), L())}, + { TEXT({"a":b}), .expect_fail = true}, + { TEXT({1a:"b"}), .expect_fail = true}, + + // non-standard extensions + { "[1,2,]", "[1,2]", NODE_ARRAY(NODE_INT64(1), NODE_INT64(2))}, + { TEXT({a:"b"}), TEXT({"a":"b"}), + NODE_MAP(L("a"), L(NODE_STR("b")))}, + { TEXT({a="b"}), TEXT({"a":"b"}), + NODE_MAP(L("a"), L(NODE_STR("b")))}, + { TEXT({a ="b"}), TEXT({"a":"b"}), + NODE_MAP(L("a"), L(NODE_STR("b")))}, + { TEXT({_a12="b"}), TEXT({"_a12":"b"}), + NODE_MAP(L("_a12"), L(NODE_STR("b")))}, +}; + +#define MAX_DEPTH 10 + +static void test_json(void **state) +{ + for (int n = 0; n < MP_ARRAY_SIZE(entries); n++) { + const struct entry *e = &entries[n]; + print_message("%d: %s\n", n, e->src); + void *tmp = talloc_new(NULL); + char *s = talloc_strdup(tmp, e->src); + json_skip_whitespace(&s); + struct mpv_node res; + bool ok = json_parse(tmp, &res, &s, MAX_DEPTH) >= 0; + assert_true(ok != e->expect_fail); + if (!ok) + continue; + char *d = talloc_strdup(tmp, ""); + assert_true(json_write(&d, &res) >= 0); + assert_string_equal(e->out_txt, d); + assert_true(equal_mpv_node(&e->out_data, &res)); + talloc_free(tmp); + } +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_json), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} + diff --git a/test/linked_list.c b/test/linked_list.c new file mode 100644 index 0000000000..6ad61f36ec --- /dev/null +++ b/test/linked_list.c @@ -0,0 +1,162 @@ +#include "test_helpers.h" + +#include "common/common.h" +#include "misc/linked_list.h" + +struct list_item { + int v; + struct { + struct list_item *prev, *next; + } list_node; +}; + +struct the_list { + struct list_item *head, *tail; +}; + +static bool do_check_list(struct the_list *lst, int *c, int num_c) +{ + if (!lst->head) + assert_true(!lst->tail); + if (!lst->tail) + assert_true(!lst->head); + + for (struct list_item *cur = lst->head; cur; cur = cur->list_node.next) { + if (cur->list_node.prev) { + assert_true(cur->list_node.prev->list_node.next == cur); + assert_true(lst->head != cur); + } else { + assert_true(lst->head == cur); + } + if (cur->list_node.next) { + assert_true(cur->list_node.next->list_node.prev == cur); + assert_true(lst->tail != cur); + } else { + assert_true(lst->tail == cur); + } + + if (num_c < 1) + return false; + if (c[0] != cur->v) + return false; + + num_c--; + c++; + } + + if (num_c) + return false; + + return true; +} + +static void test_linked_list(void **state) +{ + struct the_list lst = {0}; + struct list_item e1 = {1}; + struct list_item e2 = {2}; + struct list_item e3 = {3}; + struct list_item e4 = {4}; + struct list_item e5 = {5}; + struct list_item e6 = {6}; + +#define check_list(...) \ + assert_true(do_check_list(&lst, (int[]){__VA_ARGS__}, \ + sizeof((int[]){__VA_ARGS__}) / sizeof(int))); +#define check_list_empty() \ + assert_true(do_check_list(&lst, NULL, 0)); + + check_list_empty(); + LL_APPEND(list_node, &lst, &e1); + + check_list(1); + LL_APPEND(list_node, &lst, &e2); + + check_list(1, 2); + LL_APPEND(list_node, &lst, &e4); + + check_list(1, 2, 4); + LL_CLEAR(list_node, &lst); + + check_list_empty(); + LL_PREPEND(list_node, &lst, &e4); + + check_list(4); + LL_PREPEND(list_node, &lst, &e2); + + check_list(2, 4); + LL_PREPEND(list_node, &lst, &e1); + + check_list(1, 2, 4); + LL_CLEAR(list_node, &lst); + + check_list_empty(); + LL_INSERT_BEFORE(list_node, &lst, (struct list_item *)NULL, &e6); + + check_list(6); + LL_INSERT_BEFORE(list_node, &lst, (struct list_item *)NULL, &e1); + + check_list(6, 1); + LL_INSERT_BEFORE(list_node, &lst, (struct list_item *)NULL, &e2); + + check_list(6, 1, 2); + LL_INSERT_BEFORE(list_node, &lst, &e6, &e3); + + check_list(3, 6, 1, 2); + LL_INSERT_BEFORE(list_node, &lst, &e6, &e5); + + check_list(3, 5, 6, 1, 2); + LL_INSERT_BEFORE(list_node, &lst, &e2, &e4); + + check_list(3, 5, 6, 1, 4, 2); + LL_REMOVE(list_node, &lst, &e6); + + check_list(3, 5, 1, 4, 2); + LL_REMOVE(list_node, &lst, &e3); + + check_list(5, 1, 4, 2); + LL_REMOVE(list_node, &lst, &e2); + + check_list(5, 1, 4); + LL_REMOVE(list_node, &lst, &e4); + + check_list(5, 1); + LL_REMOVE(list_node, &lst, &e5); + + check_list(1); + LL_REMOVE(list_node, &lst, &e1); + + check_list_empty(); + LL_APPEND(list_node, &lst, &e2); + + check_list(2); + LL_REMOVE(list_node, &lst, &e2); + + check_list_empty(); + LL_INSERT_AFTER(list_node, &lst, (struct list_item *)NULL, &e1); + + check_list(1); + LL_INSERT_AFTER(list_node, &lst, (struct list_item *)NULL, &e2); + + check_list(2, 1); + LL_INSERT_AFTER(list_node, &lst, (struct list_item *)NULL, &e3); + + check_list(3, 2, 1); + LL_INSERT_AFTER(list_node, &lst, &e3, &e4); + + check_list(3, 4, 2, 1); + LL_INSERT_AFTER(list_node, &lst, &e4, &e5); + + check_list(3, 4, 5, 2, 1); + LL_INSERT_AFTER(list_node, &lst, &e1, &e6); + + check_list(3, 4, 5, 2, 1, 6); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_linked_list), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} + |