]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-json.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / test / test-json.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <math.h>
23
24 #include "json.h"
25 #include "string-util.h"
26 #include "util.h"
27
28 static void test_one(const char *data, ...) {
29 void *state = NULL;
30 va_list ap;
31
32 va_start(ap, data);
33
34 for (;;) {
35 _cleanup_free_ char *str = NULL;
36 union json_value v = {};
37 int t, tt;
38
39 t = json_tokenize(&data, &str, &v, &state, NULL);
40 tt = va_arg(ap, int);
41
42 assert_se(t == tt);
43
44 if (t == JSON_END || t < 0)
45 break;
46
47 else if (t == JSON_STRING) {
48 const char *nn;
49
50 nn = va_arg(ap, const char *);
51 assert_se(streq_ptr(nn, str));
52
53 } else if (t == JSON_REAL) {
54 double d;
55
56 d = va_arg(ap, double);
57 assert_se(fabs(d - v.real) < 0.001);
58
59 } else if (t == JSON_INTEGER) {
60 intmax_t i;
61
62 i = va_arg(ap, intmax_t);
63 assert_se(i == v.integer);
64
65 } else if (t == JSON_BOOLEAN) {
66 bool b;
67
68 b = va_arg(ap, int);
69 assert_se(b == v.boolean);
70 }
71 }
72
73 va_end(ap);
74 }
75
76 typedef void (*Test)(JsonVariant *);
77
78 static void test_file(const char *data, Test test) {
79 _cleanup_json_variant_unref_ JsonVariant *v = NULL;
80 int r;
81
82 r = json_parse(data, &v);
83 assert_se(r == 0);
84 assert_se(v != NULL);
85 assert_se(v->type == JSON_VARIANT_OBJECT);
86
87 if (test)
88 test(v);
89 }
90
91 static void test_1(JsonVariant *v) {
92 JsonVariant *p, *q;
93 unsigned i;
94
95 /* 3 keys + 3 values */
96 assert_se(v->size == 6);
97
98 /* has k */
99 p = json_variant_value(v, "k");
100 assert_se(p && p->type == JSON_VARIANT_STRING);
101
102 /* k equals v */
103 assert_se(streq(json_variant_string(p), "v"));
104
105 /* has foo */
106 p = json_variant_value(v, "foo");
107 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 3);
108
109 /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */
110 for (i = 0; i < 3; ++i) {
111 q = json_variant_element(p, i);
112 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == (i+1));
113 }
114
115 /* has bar */
116 p = json_variant_value(v, "bar");
117 assert_se(p && p->type == JSON_VARIANT_OBJECT && p->size == 2);
118
119 /* zap is null */
120 q = json_variant_value(p, "zap");
121 assert_se(q && q->type == JSON_VARIANT_NULL);
122 }
123
124 static void test_2(JsonVariant *v) {
125 JsonVariant *p, *q;
126
127 /* 2 keys + 2 values */
128 assert_se(v->size == 4);
129
130 /* has mutant */
131 p = json_variant_value(v, "mutant");
132 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 4);
133
134 /* mutant[0] == 1 */
135 q = json_variant_element(p, 0);
136 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
137
138 /* mutant[1] == null */
139 q = json_variant_element(p, 1);
140 assert_se(q && q->type == JSON_VARIANT_NULL);
141
142 /* mutant[2] == "1" */
143 q = json_variant_element(p, 2);
144 assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
145
146 /* mutant[3] == JSON_VARIANT_OBJECT */
147 q = json_variant_element(p, 3);
148 assert_se(q && q->type == JSON_VARIANT_OBJECT && q->size == 2);
149
150 /* has 1 */
151 p = json_variant_value(q, "1");
152 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 2);
153
154 /* "1"[0] == 1 */
155 q = json_variant_element(p, 0);
156 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
157
158 /* "1"[1] == "1" */
159 q = json_variant_element(p, 1);
160 assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
161
162 /* has blah */
163 p = json_variant_value(v, "blah");
164 assert_se(p && p->type == JSON_VARIANT_REAL && fabs(json_variant_real(p) - 1.27) < 0.001);
165 }
166
167 int main(int argc, char *argv[]) {
168
169 test_one("x", -EINVAL);
170 test_one("", JSON_END);
171 test_one(" ", JSON_END);
172 test_one("0", JSON_INTEGER, (intmax_t) 0, JSON_END);
173 test_one("1234", JSON_INTEGER, (intmax_t) 1234, JSON_END);
174 test_one("3.141", JSON_REAL, 3.141, JSON_END);
175 test_one("0.0", JSON_REAL, 0.0, JSON_END);
176 test_one("7e3", JSON_REAL, 7e3, JSON_END);
177 test_one("-7e-3", JSON_REAL, -7e-3, JSON_END);
178 test_one("true", JSON_BOOLEAN, true, JSON_END);
179 test_one("false", JSON_BOOLEAN, false, JSON_END);
180 test_one("null", JSON_NULL, JSON_END);
181 test_one("{}", JSON_OBJECT_OPEN, JSON_OBJECT_CLOSE, JSON_END);
182 test_one("\t {\n} \n", JSON_OBJECT_OPEN, JSON_OBJECT_CLOSE, JSON_END);
183 test_one("[]", JSON_ARRAY_OPEN, JSON_ARRAY_CLOSE, JSON_END);
184 test_one("\t [] \n\n", JSON_ARRAY_OPEN, JSON_ARRAY_CLOSE, JSON_END);
185 test_one("\"\"", JSON_STRING, "", JSON_END);
186 test_one("\"foo\"", JSON_STRING, "foo", JSON_END);
187 test_one("\"foo\\nfoo\"", JSON_STRING, "foo\nfoo", JSON_END);
188 test_one("{\"foo\" : \"bar\"}", JSON_OBJECT_OPEN, JSON_STRING, "foo", JSON_COLON, JSON_STRING, "bar", JSON_OBJECT_CLOSE, JSON_END);
189 test_one("{\"foo\" : [true, false]}", JSON_OBJECT_OPEN, JSON_STRING, "foo", JSON_COLON, JSON_ARRAY_OPEN, JSON_BOOLEAN, true, JSON_COMMA, JSON_BOOLEAN, false, JSON_ARRAY_CLOSE, JSON_OBJECT_CLOSE, JSON_END);
190 test_one("\"\xef\xbf\xbd\"", JSON_STRING, "\xef\xbf\xbd", JSON_END);
191 test_one("\"\\ufffd\"", JSON_STRING, "\xef\xbf\xbd", JSON_END);
192 test_one("\"\\uf\"", -EINVAL);
193 test_one("\"\\ud800a\"", -EINVAL);
194 test_one("\"\\udc00\\udc00\"", -EINVAL);
195 test_one("\"\\ud801\\udc37\"", JSON_STRING, "\xf0\x90\x90\xb7", JSON_END);
196
197 test_one("[1, 2]", JSON_ARRAY_OPEN, JSON_INTEGER, (intmax_t) 1, JSON_COMMA, JSON_INTEGER, (intmax_t) 2, JSON_ARRAY_CLOSE, JSON_END);
198
199 test_file("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1);
200 test_file("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"blah\": 1.27}", test_2);
201
202 return 0;
203 }