summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/json.c97
-rw-r--r--test/linked_list.c162
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);
+}
+