]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-json.c
util: split out escaping code into escape.[ch]
[thirdparty/systemd.git] / src / test / test-json.c
CommitLineData
e7eebcfc
LP
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
30c873fb
TA
22#include <math.h>
23
e7eebcfc
LP
24#include "util.h"
25#include "json.h"
26
27static void test_one(const char *data, ...) {
28 void *state = NULL;
29 va_list ap;
30
31 va_start(ap, data);
32
33 for (;;) {
34 _cleanup_free_ char *str = NULL;
35 union json_value v = {};
36 int t, tt;
37
38 t = json_tokenize(&data, &str, &v, &state, NULL);
39 tt = va_arg(ap, int);
40
41 assert_se(t == tt);
42
43 if (t == JSON_END || t < 0)
44 break;
45
46 else if (t == JSON_STRING) {
47 const char *nn;
48
49 nn = va_arg(ap, const char *);
50 assert_se(streq_ptr(nn, str));
51
52 } else if (t == JSON_REAL) {
53 double d;
54
55 d = va_arg(ap, double);
30c873fb 56 assert_se(fabs(d - v.real) < 0.001);
e7eebcfc
LP
57
58 } else if (t == JSON_INTEGER) {
59 intmax_t i;
60
61 i = va_arg(ap, intmax_t);
62 assert_se(i == v.integer);
63
64 } else if (t == JSON_BOOLEAN) {
65 bool b;
66
67 b = va_arg(ap, int);
68 assert_se(b == v.boolean);
69 }
70 }
71
72 va_end(ap);
73}
74
d4fc45af
PO
75typedef void (*Test)(JsonVariant *);
76
77static void test_file(const char *data, Test test) {
dde8bb32
LP
78 _cleanup_json_variant_unref_ JsonVariant *v = NULL;
79 int r;
d4fc45af 80
dde8bb32 81 r = json_parse(data, &v);
d4fc45af
PO
82 assert_se(r == 0);
83 assert_se(v != NULL);
84 assert_se(v->type == JSON_VARIANT_OBJECT);
85
86 if (test)
87 test(v);
d4fc45af
PO
88}
89
90static void test_1(JsonVariant *v) {
91 JsonVariant *p, *q;
92 unsigned i;
93
94 /* 3 keys + 3 values */
95 assert_se(v->size == 6);
96
97 /* has k */
98 p = json_variant_value(v, "k");
99 assert_se(p && p->type == JSON_VARIANT_STRING);
100
101 /* k equals v */
102 assert_se(streq(json_variant_string(p), "v"));
103
104 /* has foo */
105 p = json_variant_value(v, "foo");
106 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 3);
107
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));
112 }
113
114 /* has bar */
115 p = json_variant_value(v, "bar");
116 assert_se(p && p->type == JSON_VARIANT_OBJECT && p->size == 2);
117
118 /* zap is null */
119 q = json_variant_value(p, "zap");
120 assert_se(q && q->type == JSON_VARIANT_NULL);
121}
122
123static void test_2(JsonVariant *v) {
124 JsonVariant *p, *q;
125
126 /* 2 keys + 2 values */
127 assert_se(v->size == 4);
128
129 /* has mutant */
130 p = json_variant_value(v, "mutant");
131 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 4);
132
133 /* mutant[0] == 1 */
134 q = json_variant_element(p, 0);
135 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
136
137 /* mutant[1] == null */
138 q = json_variant_element(p, 1);
139 assert_se(q && q->type == JSON_VARIANT_NULL);
140
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"));
144
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);
148
149 /* has 1 */
150 p = json_variant_value(q, "1");
151 assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 2);
152
153 /* "1"[0] == 1 */
154 q = json_variant_element(p, 0);
155 assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
156
157 /* "1"[1] == "1" */
158 q = json_variant_element(p, 1);
159 assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
160
161 /* has blah */
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);
164}
165
e7eebcfc
LP
166int main(int argc, char *argv[]) {
167
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);
2bb4c7e3 191 test_one("\"\\uf\"", -EINVAL);
9bae67d4
TG
192 test_one("\"\\ud800a\"", -EINVAL);
193 test_one("\"\\udc00\\udc00\"", -EINVAL);
194 test_one("\"\\ud801\\udc37\"", JSON_STRING, "\xf0\x90\x90\xb7", JSON_END);
e7eebcfc 195
85dbc307 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);
d4fc45af
PO
197
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);
200
e7eebcfc
LP
201 return 0;
202}