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/>.
25 #include "string-util.h"
28 static void test_one(const char *data
, ...) {
35 _cleanup_free_
char *str
= NULL
;
36 union json_value v
= {};
39 t
= json_tokenize(&data
, &str
, &v
, &state
, NULL
);
44 if (t
== JSON_END
|| t
< 0)
47 else if (t
== JSON_STRING
) {
50 nn
= va_arg(ap
, const char *);
51 assert_se(streq_ptr(nn
, str
));
53 } else if (t
== JSON_REAL
) {
56 d
= va_arg(ap
, double);
57 assert_se(fabs(d
- v
.real
) < 0.001);
59 } else if (t
== JSON_INTEGER
) {
62 i
= va_arg(ap
, intmax_t);
63 assert_se(i
== v
.integer
);
65 } else if (t
== JSON_BOOLEAN
) {
69 assert_se(b
== v
.boolean
);
76 typedef void (*Test
)(JsonVariant
*);
78 static void test_file(const char *data
, Test test
) {
79 _cleanup_json_variant_unref_ JsonVariant
*v
= NULL
;
82 r
= json_parse(data
, &v
);
85 assert_se(v
->type
== JSON_VARIANT_OBJECT
);
91 static void test_1(JsonVariant
*v
) {
95 /* 3 keys + 3 values */
96 assert_se(v
->size
== 6);
99 p
= json_variant_value(v
, "k");
100 assert_se(p
&& p
->type
== JSON_VARIANT_STRING
);
103 assert_se(streq(json_variant_string(p
), "v"));
106 p
= json_variant_value(v
, "foo");
107 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 3);
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));
116 p
= json_variant_value(v
, "bar");
117 assert_se(p
&& p
->type
== JSON_VARIANT_OBJECT
&& p
->size
== 2);
120 q
= json_variant_value(p
, "zap");
121 assert_se(q
&& q
->type
== JSON_VARIANT_NULL
);
124 static void test_2(JsonVariant
*v
) {
127 /* 2 keys + 2 values */
128 assert_se(v
->size
== 4);
131 p
= json_variant_value(v
, "mutant");
132 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 4);
135 q
= json_variant_element(p
, 0);
136 assert_se(q
&& q
->type
== JSON_VARIANT_INTEGER
&& json_variant_integer(q
) == 1);
138 /* mutant[1] == null */
139 q
= json_variant_element(p
, 1);
140 assert_se(q
&& q
->type
== JSON_VARIANT_NULL
);
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"));
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);
151 p
= json_variant_value(q
, "1");
152 assert_se(p
&& p
->type
== JSON_VARIANT_ARRAY
&& p
->size
== 2);
155 q
= json_variant_element(p
, 0);
156 assert_se(q
&& q
->type
== JSON_VARIANT_INTEGER
&& json_variant_integer(q
) == 1);
159 q
= json_variant_element(p
, 1);
160 assert_se(q
&& q
->type
== JSON_VARIANT_STRING
&& streq(json_variant_string(q
), "1"));
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);
167 int main(int argc
, char *argv
[]) {
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
);
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
);
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
);