1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
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.
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.
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/>.
24 #include "alloc-util.h"
26 #include "string-util.h"
29 static void test_one(const char *data
, ...) {
36 _cleanup_free_
char *str
= NULL
;
37 union json_value v
= {};
40 t
= json_tokenize(&data
, &str
, &v
, &state
, NULL
);
45 if (t
== JSON_END
|| t
< 0)
48 else if (t
== JSON_STRING
) {
51 nn
= va_arg(ap
, const char *);
52 assert_se(streq_ptr(nn
, str
));
54 } else if (t
== JSON_REAL
) {
57 d
= va_arg(ap
, double);
58 assert_se(fabs(d
- v
.real
) < 0.001);
60 } else if (t
== JSON_INTEGER
) {
63 i
= va_arg(ap
, intmax_t);
64 assert_se(i
== v
.integer
);
66 } else if (t
== JSON_BOOLEAN
) {
70 assert_se(b
== v
.boolean
);
77 typedef void (*Test
)(JsonVariant
*);
79 static void test_file(const char *data
, Test test
) {
80 _cleanup_json_variant_unref_ JsonVariant
*v
= NULL
;
83 r
= json_parse(data
, &v
);
86 assert_se(v
->type
== JSON_VARIANT_OBJECT
);
92 static void test_1(JsonVariant
*v
) {
96 /* 3 keys + 3 values */
97 assert_se(v
->size
== 6);
100 p
= json_variant_value(v
, "k");
101 assert_se(p
&& p
->type
== JSON_VARIANT_STRING
);
104 assert_se(streq(json_variant_string(p
), "v"));
107 p
= json_variant_value(v
, "foo");
108 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 3);
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));
117 p
= json_variant_value(v
, "bar");
118 assert_se(p
&& p
->type
== JSON_VARIANT_OBJECT
&& p
->size
== 2);
121 q
= json_variant_value(p
, "zap");
122 assert_se(q
&& q
->type
== JSON_VARIANT_NULL
);
125 static void test_2(JsonVariant
*v
) {
128 /* 2 keys + 2 values */
129 assert_se(v
->size
== 4);
132 p
= json_variant_value(v
, "mutant");
133 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 4);
136 q
= json_variant_element(p
, 0);
137 assert_se(q
&& q
->type
== JSON_VARIANT_INTEGER
&& json_variant_integer(q
) == 1);
139 /* mutant[1] == null */
140 q
= json_variant_element(p
, 1);
141 assert_se(q
&& q
->type
== JSON_VARIANT_NULL
);
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"));
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);
152 p
= json_variant_value(q
, "1");
153 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 2);
156 q
= json_variant_element(p
, 0);
157 assert_se(q
&& q
->type
== JSON_VARIANT_INTEGER
&& json_variant_integer(q
) == 1);
160 q
= json_variant_element(p
, 1);
161 assert_se(q
&& q
->type
== JSON_VARIANT_STRING
&& streq(json_variant_string(q
), "1"));
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);
168 int main(int argc
, char *argv
[]) {
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
);
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
);
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
);