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