2 This file is part of systemd.
4 Copyright 2014 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "alloc-util.h"
24 #include "string-util.h"
27 static void test_one(const char *data
, ...) {
34 _cleanup_free_
char *str
= NULL
;
35 union json_value v
= {};
38 t
= json_tokenize(&data
, &str
, &v
, &state
, NULL
);
43 if (t
== JSON_END
|| t
< 0)
46 else if (t
== JSON_STRING
) {
49 nn
= va_arg(ap
, const char *);
50 assert_se(streq_ptr(nn
, str
));
52 } else if (t
== JSON_REAL
) {
55 d
= va_arg(ap
, double);
56 assert_se(fabs(d
- v
.real
) < 0.001);
58 } else if (t
== JSON_INTEGER
) {
61 i
= va_arg(ap
, intmax_t);
62 assert_se(i
== v
.integer
);
64 } else if (t
== JSON_BOOLEAN
) {
68 assert_se(b
== v
.boolean
);
75 typedef void (*Test
)(JsonVariant
*);
77 static void test_file(const char *data
, Test test
) {
78 _cleanup_json_variant_unref_ JsonVariant
*v
= NULL
;
81 r
= json_parse(data
, &v
);
84 assert_se(v
->type
== JSON_VARIANT_OBJECT
);
90 static void test_1(JsonVariant
*v
) {
94 /* 3 keys + 3 values */
95 assert_se(v
->size
== 6);
98 p
= json_variant_value(v
, "k");
99 assert_se(p
&& p
->type
== JSON_VARIANT_STRING
);
102 assert_se(streq(json_variant_string(p
), "v"));
105 p
= json_variant_value(v
, "foo");
106 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 3);
108 /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */
109 for (i
= 0; i
< 3; ++i
) {
110 q
= json_variant_element(p
, i
);
111 assert_se(q
&& q
->type
== JSON_VARIANT_INTEGER
&& json_variant_integer(q
) == (i
+1));
115 p
= json_variant_value(v
, "bar");
116 assert_se(p
&& p
->type
== JSON_VARIANT_OBJECT
&& p
->size
== 2);
119 q
= json_variant_value(p
, "zap");
120 assert_se(q
&& q
->type
== JSON_VARIANT_NULL
);
123 static void test_2(JsonVariant
*v
) {
126 /* 2 keys + 2 values */
127 assert_se(v
->size
== 4);
130 p
= json_variant_value(v
, "mutant");
131 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 4);
134 q
= json_variant_element(p
, 0);
135 assert_se(q
&& q
->type
== JSON_VARIANT_INTEGER
&& json_variant_integer(q
) == 1);
137 /* mutant[1] == null */
138 q
= json_variant_element(p
, 1);
139 assert_se(q
&& q
->type
== JSON_VARIANT_NULL
);
141 /* mutant[2] == "1" */
142 q
= json_variant_element(p
, 2);
143 assert_se(q
&& q
->type
== JSON_VARIANT_STRING
&& streq(json_variant_string(q
), "1"));
145 /* mutant[3] == JSON_VARIANT_OBJECT */
146 q
= json_variant_element(p
, 3);
147 assert_se(q
&& q
->type
== JSON_VARIANT_OBJECT
&& q
->size
== 2);
150 p
= json_variant_value(q
, "1");
151 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 2);
154 q
= json_variant_element(p
, 0);
155 assert_se(q
&& q
->type
== JSON_VARIANT_INTEGER
&& json_variant_integer(q
) == 1);
158 q
= json_variant_element(p
, 1);
159 assert_se(q
&& q
->type
== JSON_VARIANT_STRING
&& streq(json_variant_string(q
), "1"));
162 p
= json_variant_value(v
, "blah");
163 assert_se(p
&& p
->type
== JSON_VARIANT_REAL
&& fabs(json_variant_real(p
) - 1.27) < 0.001);
166 int main(int argc
, char *argv
[]) {
168 test_one("x", -EINVAL
);
169 test_one("", JSON_END
);
170 test_one(" ", JSON_END
);
171 test_one("0", JSON_INTEGER
, (intmax_t) 0, JSON_END
);
172 test_one("1234", JSON_INTEGER
, (intmax_t) 1234, JSON_END
);
173 test_one("3.141", JSON_REAL
, 3.141, JSON_END
);
174 test_one("0.0", JSON_REAL
, 0.0, JSON_END
);
175 test_one("7e3", JSON_REAL
, 7e3
, JSON_END
);
176 test_one("-7e-3", JSON_REAL
, -7e-3, JSON_END
);
177 test_one("true", JSON_BOOLEAN
, true, JSON_END
);
178 test_one("false", JSON_BOOLEAN
, false, JSON_END
);
179 test_one("null", JSON_NULL
, JSON_END
);
180 test_one("{}", JSON_OBJECT_OPEN
, JSON_OBJECT_CLOSE
, JSON_END
);
181 test_one("\t {\n} \n", JSON_OBJECT_OPEN
, JSON_OBJECT_CLOSE
, JSON_END
);
182 test_one("[]", JSON_ARRAY_OPEN
, JSON_ARRAY_CLOSE
, JSON_END
);
183 test_one("\t [] \n\n", JSON_ARRAY_OPEN
, JSON_ARRAY_CLOSE
, JSON_END
);
184 test_one("\"\"", JSON_STRING
, "", JSON_END
);
185 test_one("\"foo\"", JSON_STRING
, "foo", JSON_END
);
186 test_one("\"foo\\nfoo\"", JSON_STRING
, "foo\nfoo", JSON_END
);
187 test_one("{\"foo\" : \"bar\"}", JSON_OBJECT_OPEN
, JSON_STRING
, "foo", JSON_COLON
, JSON_STRING
, "bar", JSON_OBJECT_CLOSE
, JSON_END
);
188 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
);
189 test_one("\"\xef\xbf\xbd\"", JSON_STRING
, "\xef\xbf\xbd", JSON_END
);
190 test_one("\"\\ufffd\"", JSON_STRING
, "\xef\xbf\xbd", JSON_END
);
191 test_one("\"\\uf\"", -EINVAL
);
192 test_one("\"\\ud800a\"", -EINVAL
);
193 test_one("\"\\udc00\\udc00\"", -EINVAL
);
194 test_one("\"\\ud801\\udc37\"", JSON_STRING
, "\xf0\x90\x90\xb7", JSON_END
);
196 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 test_file("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1
);
199 test_file("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"blah\": 1.27}", test_2
);