]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-json.c
tty-ask-password: Split out password sending
[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 "alloc-util.h"
25 #include "json.h"
26 #include "string-util.h"
27 #include "util.h"
28
29 static void test_one(const char *data, ...) {
30 void *state = NULL;
31 va_list ap;
32
33 va_start(ap, data);
34
35 for (;;) {
36 _cleanup_free_ char *str = NULL;
37 union json_value v = {};
38 int t, tt;
39
40 t = json_tokenize(&data, &str, &v, &state, NULL);
41 tt = va_arg(ap, int);
42
43 assert_se(t == tt);
44
45 if (t == JSON_END || t < 0)
46 break;
47
48 else if (t == JSON_STRING) {
49 const char *nn;
50
51 nn = va_arg(ap, const char *);
52 assert_se(streq_ptr(nn, str));
53
54 } else if (t == JSON_REAL) {
55 double d;
56
57 d = va_arg(ap, double);
58 assert_se(fabs(d - v.real) < 0.001);
59
60 } else if (t == JSON_INTEGER) {
61 intmax_t i;
62
63 i = va_arg(ap, intmax_t);
64 assert_se(i == v.integer);
65
66 } else if (t == JSON_BOOLEAN) {
67 bool b;
68
69 b = va_arg(ap, int);
70 assert_se(b == v.boolean);
71 }
72 }
73
74 va_end(ap);
75 }
76
77 typedef void (*Test)(JsonVariant *);
78
79 static void test_file(const char *data, Test test) {
80 _cleanup_json_variant_unref_ JsonVariant *v = NULL;
81 int r;
82
83 r = json_parse(data, &v);
84 assert_se(r == 0);
85 assert_se(v != NULL);
86 assert_se(v->type == JSON_VARIANT_OBJECT);
87
88 if (test)
89 test(v);
90 }
91
92 static void test_1(JsonVariant *v) {
93 JsonVariant *p, *q;
94 unsigned i;
95
96 /* 3 keys + 3 values */
97 assert_se(v->size == 6);
98
99 /* has k */
100 p = json_variant_value(v, "k");
101 assert_se(p && p->type == JSON_VARIANT_STRING);
102
103 /* k equals v */
104 assert_se(streq(json_variant_string(p), "v"));
105
106 /* has foo */
107 p = json_variant_value(v, "foo");
108 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 3);
109
110 /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */
111 for (i = 0; i < 3; ++i) {
112 q = json_variant_element(p, i);
113 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == (i+1));
114 }
115
116 /* has bar */
117 p = json_variant_value(v, "bar");
118 assert_se(p && p->type == JSON_VARIANT_OBJECT && p->size == 2);
119
120 /* zap is null */
121 q = json_variant_value(p, "zap");
122 assert_se(q && q->type == JSON_VARIANT_NULL);
123 }
124
125 static void test_2(JsonVariant *v) {
126 JsonVariant *p, *q;
127
128 /* 2 keys + 2 values */
129 assert_se(v->size == 4);
130
131 /* has mutant */
132 p = json_variant_value(v, "mutant");
133 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 4);
134
135 /* mutant[0] == 1 */
136 q = json_variant_element(p, 0);
137 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
138
139 /* mutant[1] == null */
140 q = json_variant_element(p, 1);
141 assert_se(q && q->type == JSON_VARIANT_NULL);
142
143 /* mutant[2] == "1" */
144 q = json_variant_element(p, 2);
145 assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
146
147 /* mutant[3] == JSON_VARIANT_OBJECT */
148 q = json_variant_element(p, 3);
149 assert_se(q && q->type == JSON_VARIANT_OBJECT && q->size == 2);
150
151 /* has 1 */
152 p = json_variant_value(q, "1");
153 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 2);
154
155 /* "1"[0] == 1 */
156 q = json_variant_element(p, 0);
157 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
158
159 /* "1"[1] == "1" */
160 q = json_variant_element(p, 1);
161 assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
162
163 /* has blah */
164 p = json_variant_value(v, "blah");
165 assert_se(p && p->type == JSON_VARIANT_REAL && fabs(json_variant_real(p) - 1.27) < 0.001);
166 }
167
168 int main(int argc, char *argv[]) {
169
170 test_one("x", -EINVAL);
171 test_one("", JSON_END);
172 test_one(" ", JSON_END);
173 test_one("0", JSON_INTEGER, (intmax_t) 0, JSON_END);
174 test_one("1234", JSON_INTEGER, (intmax_t) 1234, JSON_END);
175 test_one("3.141", JSON_REAL, 3.141, JSON_END);
176 test_one("0.0", JSON_REAL, 0.0, JSON_END);
177 test_one("7e3", JSON_REAL, 7e3, JSON_END);
178 test_one("-7e-3", JSON_REAL, -7e-3, JSON_END);
179 test_one("true", JSON_BOOLEAN, true, JSON_END);
180 test_one("false", JSON_BOOLEAN, false, JSON_END);
181 test_one("null", JSON_NULL, JSON_END);
182 test_one("{}", JSON_OBJECT_OPEN, JSON_OBJECT_CLOSE, JSON_END);
183 test_one("\t {\n} \n", JSON_OBJECT_OPEN, JSON_OBJECT_CLOSE, JSON_END);
184 test_one("[]", JSON_ARRAY_OPEN, JSON_ARRAY_CLOSE, JSON_END);
185 test_one("\t [] \n\n", JSON_ARRAY_OPEN, JSON_ARRAY_CLOSE, JSON_END);
186 test_one("\"\"", JSON_STRING, "", JSON_END);
187 test_one("\"foo\"", JSON_STRING, "foo", JSON_END);
188 test_one("\"foo\\nfoo\"", JSON_STRING, "foo\nfoo", JSON_END);
189 test_one("{\"foo\" : \"bar\"}", JSON_OBJECT_OPEN, JSON_STRING, "foo", JSON_COLON, JSON_STRING, "bar", JSON_OBJECT_CLOSE, JSON_END);
190 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);
191 test_one("\"\xef\xbf\xbd\"", JSON_STRING, "\xef\xbf\xbd", JSON_END);
192 test_one("\"\\ufffd\"", JSON_STRING, "\xef\xbf\xbd", JSON_END);
193 test_one("\"\\uf\"", -EINVAL);
194 test_one("\"\\ud800a\"", -EINVAL);
195 test_one("\"\\udc00\\udc00\"", -EINVAL);
196 test_one("\"\\ud801\\udc37\"", JSON_STRING, "\xf0\x90\x90\xb7", JSON_END);
197
198 test_one("[1, 2]", JSON_ARRAY_OPEN, JSON_INTEGER, (intmax_t) 1, JSON_COMMA, JSON_INTEGER, (intmax_t) 2, JSON_ARRAY_CLOSE, JSON_END);
199
200 test_file("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1);
201 test_file("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"blah\": 1.27}", test_2);
202
203 return 0;
204 }