Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibTest/TestCase.h>
8
9#include <AK/DeprecatedString.h>
10#include <AK/HashMap.h>
11#include <AK/JsonObject.h>
12#include <AK/JsonValue.h>
13#include <AK/StringBuilder.h>
14
15TEST_CASE(load_form)
16{
17 DeprecatedString raw_form_json = R"(
18 {
19 "name": "Form1",
20 "widgets": [
21 {
22 "enabled": true,
23 "forecolor": "#000000ff",
24 "ruler_visible": false,
25 "autofill": false,
26 "x": 155,
27 "tooltip": null,
28 "height": 121,
29 "width": 126,
30 "y": 10,
31 "class": "GTextEditor",
32 "text": "Hi",
33 "backcolor": "#c0c0c0ff",
34 "visible":true
35 }
36 ]
37 })";
38
39 JsonValue form_json = JsonValue::from_string(raw_form_json).value();
40
41 EXPECT(form_json.is_object());
42
43 auto name = form_json.as_object().get_deprecated_string("name"sv);
44 EXPECT(name.has_value());
45
46 EXPECT_EQ(name.value(), "Form1");
47
48 auto widgets = form_json.as_object().get_array("widgets"sv);
49 EXPECT(widgets.has_value());
50
51 widgets->for_each([&](JsonValue const& widget_value) {
52 auto& widget_object = widget_value.as_object();
53 auto widget_class = widget_object.get_deprecated_string("class"sv).value();
54 widget_object.for_each_member([&]([[maybe_unused]] auto& property_name, [[maybe_unused]] const JsonValue& property_value) {
55 });
56 });
57}
58
59TEST_CASE(json_empty_string)
60{
61 auto json = JsonValue::from_string("\"\""sv).value();
62 EXPECT_EQ(json.type(), JsonValue::Type::String);
63 EXPECT_EQ(json.as_string().is_null(), false);
64 EXPECT_EQ(json.as_string().is_empty(), true);
65}
66
67TEST_CASE(json_string)
68{
69 auto json = JsonValue::from_string("\"A\""sv).value();
70 EXPECT_EQ(json.type(), JsonValue::Type::String);
71 EXPECT_EQ(json.as_string().is_null(), false);
72 EXPECT_EQ(json.as_string().length(), size_t { 1 });
73 EXPECT_EQ(json.as_string() == "A", true);
74}
75
76TEST_CASE(json_utf8_character)
77{
78 auto json = JsonValue::from_string("\"\\u0041\""sv).value();
79 EXPECT_EQ(json.type(), JsonValue::Type::String);
80 EXPECT_EQ(json.as_string().is_null(), false);
81 EXPECT_EQ(json.as_string().length(), size_t { 1 });
82 EXPECT_EQ(json.as_string() == "A", true);
83}
84
85/*
86FIXME: Parse JSON from a Utf8View
87
88TEST_CASE(json_utf8_multibyte)
89{
90 auto json_or_error = JsonValue::from_string("\"š\"");
91 EXPECT_EQ(json_or_error.is_error(), false);
92
93 auto& json = json_or_error.value();
94 EXPECT_EQ(json.type(), JsonValue::Type::String);
95 EXPECT_EQ(json.as_string().is_null(), false);
96 EXPECT_EQ(json.as_string().length(), size_t { 2 });
97 EXPECT_EQ(json.as_string() == "š", true);
98 EXPECT_EQ(json.as_string() == "\xc5\xa1", true);
99}
100*/
101
102TEST_CASE(json_64_bit_value)
103{
104 auto big_value = 0x12345678aabbccddull;
105 JsonValue big_json_value(big_value);
106 JsonValue big_json_value_copy = big_json_value;
107 EXPECT_EQ(big_json_value.as_u64(), big_json_value_copy.as_u64());
108}
109
110TEST_CASE(json_duplicate_keys)
111{
112 JsonObject json;
113 json.set("test", "foo");
114 json.set("test", "bar");
115 json.set("test", "baz");
116 EXPECT_EQ(json.to_deprecated_string(), "{\"test\":\"baz\"}");
117}
118
119TEST_CASE(json_u64_roundtrip)
120{
121 auto big_value = 0xffffffffffffffffull;
122 auto json = JsonValue(big_value).to_deprecated_string();
123 auto value = JsonValue::from_string(json);
124 EXPECT_EQ_FORCE(value.is_error(), false);
125 EXPECT_EQ(value.value().as_u64(), big_value);
126}
127
128TEST_CASE(json_parse_empty_string)
129{
130 auto value = JsonValue::from_string(""sv);
131 EXPECT_EQ(value.is_error(), true);
132}
133
134TEST_CASE(json_parse_long_decimals)
135{
136 auto value = JsonValue::from_string("1644452550.6489999294281"sv);
137 EXPECT_EQ(value.value().as_double(), 1644452550.6489999294281);
138}
139
140TEST_CASE(json_parse_number_with_exponent)
141{
142 auto value_without_fraction = JsonValue::from_string("10e5"sv);
143 EXPECT_EQ(value_without_fraction.value().as_double(), 1000000.0);
144
145 auto value_with_fraction = JsonValue::from_string("10.5e5"sv);
146 EXPECT_EQ(value_with_fraction.value().as_double(), 1050000.0);
147}
148
149TEST_CASE(json_parse_special_numbers)
150{
151#define EXPECT_TO_MATCH_NUMBER_BIT_WISE(string_input, double_input) \
152 do { \
153 auto value_or_error = JsonValue::from_string(string_input##sv); \
154 VERIFY(!value_or_error.is_error()); \
155 if (value_or_error.is_error()) \
156 dbgln("got {}", value_or_error.error()); \
157 EXPECT(value_or_error.value().is_number()); \
158 EXPECT_EQ(bit_cast<u64>(value_or_error.value().to_double(4321.0)), bit_cast<u64>(static_cast<double>(double_input))); \
159 } while (false)
160
161 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0", -0.);
162 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0.0", -0.0);
163 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0.00", -0.00);
164 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0e0", -0e0);
165 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0e1", -0e1);
166 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0e2", -0e2);
167 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0e1000", -0e1000);
168 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-0e-1000", -0e-1000);
169
170 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0", 0.);
171 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0.0", 0.0);
172 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0.00", 0.00);
173 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0e0", 0e0);
174 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0e1", 0e1);
175 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0e2", 0e2);
176 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0e1000", 0e1000);
177 EXPECT_TO_MATCH_NUMBER_BIT_WISE("0e-1000", 0e-1000);
178
179 // These technically can be non zero, but not in doubles
180 EXPECT_TO_MATCH_NUMBER_BIT_WISE("-1e-2000", -0.);
181 EXPECT_TO_MATCH_NUMBER_BIT_WISE("1e-2000", 0.);
182
183#undef EXPECT_TO_MATCH_NUMBER_BIT_WISE
184}
185
186TEST_CASE(json_parse_fails_on_invalid_number)
187{
188#define EXPECT_JSON_PARSE_TO_FAIL(value) \
189 EXPECT(JsonValue::from_string(value##sv).is_error());
190
191 EXPECT_JSON_PARSE_TO_FAIL("-");
192 EXPECT_JSON_PARSE_TO_FAIL("00");
193 EXPECT_JSON_PARSE_TO_FAIL("01");
194 EXPECT_JSON_PARSE_TO_FAIL("-01");
195 EXPECT_JSON_PARSE_TO_FAIL(".1");
196 EXPECT_JSON_PARSE_TO_FAIL("-.1");
197 EXPECT_JSON_PARSE_TO_FAIL("-,1");
198 EXPECT_JSON_PARSE_TO_FAIL(".1e1");
199 EXPECT_JSON_PARSE_TO_FAIL(".1e-1");
200 EXPECT_JSON_PARSE_TO_FAIL("-.1e1");
201 EXPECT_JSON_PARSE_TO_FAIL("-.1e-1");
202 EXPECT_JSON_PARSE_TO_FAIL("1.e1");
203 EXPECT_JSON_PARSE_TO_FAIL("1.e-1");
204 EXPECT_JSON_PARSE_TO_FAIL("-1.e1");
205 EXPECT_JSON_PARSE_TO_FAIL("-1.e-1");
206 EXPECT_JSON_PARSE_TO_FAIL("1e");
207 EXPECT_JSON_PARSE_TO_FAIL("1e+");
208 EXPECT_JSON_PARSE_TO_FAIL("1e-");
209 EXPECT_JSON_PARSE_TO_FAIL("1e-f");
210 EXPECT_JSON_PARSE_TO_FAIL("1.e");
211 EXPECT_JSON_PARSE_TO_FAIL("1.e+");
212 EXPECT_JSON_PARSE_TO_FAIL("1.e-");
213 EXPECT_JSON_PARSE_TO_FAIL("1.e-f");
214 EXPECT_JSON_PARSE_TO_FAIL("1p2");
215 EXPECT_JSON_PARSE_TO_FAIL("1.p2");
216 EXPECT_JSON_PARSE_TO_FAIL("0x1.0p2");
217 EXPECT_JSON_PARSE_TO_FAIL("0x1");
218 EXPECT_JSON_PARSE_TO_FAIL("0x7");
219 EXPECT_JSON_PARSE_TO_FAIL("0xA");
220 EXPECT_JSON_PARSE_TO_FAIL("0x");
221 EXPECT_JSON_PARSE_TO_FAIL("-0x");
222 EXPECT_JSON_PARSE_TO_FAIL("0x");
223 EXPECT_JSON_PARSE_TO_FAIL("1x");
224 EXPECT_JSON_PARSE_TO_FAIL("100x");
225 EXPECT_JSON_PARSE_TO_FAIL("1000000000000000000000x");
226 EXPECT_JSON_PARSE_TO_FAIL("0e2x");
227 EXPECT_JSON_PARSE_TO_FAIL("0.1e2x");
228 EXPECT_JSON_PARSE_TO_FAIL("0.1x");
229 EXPECT_JSON_PARSE_TO_FAIL("1e2x");
230 EXPECT_JSON_PARSE_TO_FAIL("1.2x");
231 EXPECT_JSON_PARSE_TO_FAIL("1.2e2x");
232 EXPECT_JSON_PARSE_TO_FAIL(".0");
233 EXPECT_JSON_PARSE_TO_FAIL(".e1");
234 EXPECT_JSON_PARSE_TO_FAIL("-.0");
235 EXPECT_JSON_PARSE_TO_FAIL("-.e1");
236 EXPECT_JSON_PARSE_TO_FAIL("+0");
237 EXPECT_JSON_PARSE_TO_FAIL("+0.0");
238 EXPECT_JSON_PARSE_TO_FAIL("+0.00");
239 EXPECT_JSON_PARSE_TO_FAIL("+0e0");
240 EXPECT_JSON_PARSE_TO_FAIL("+0e1");
241 EXPECT_JSON_PARSE_TO_FAIL("+0e2");
242 EXPECT_JSON_PARSE_TO_FAIL("+0e1000");
243 EXPECT_JSON_PARSE_TO_FAIL("+0e-1000");
244
245 EXPECT_JSON_PARSE_TO_FAIL("+10");
246 EXPECT_JSON_PARSE_TO_FAIL("+10e1");
247 EXPECT_JSON_PARSE_TO_FAIL("+10.3");
248 EXPECT_JSON_PARSE_TO_FAIL("+10.3e1");
249
250 EXPECT_JSON_PARSE_TO_FAIL("0x1");
251 EXPECT_JSON_PARSE_TO_FAIL("0x2");
252 EXPECT_JSON_PARSE_TO_FAIL("0xA");
253 EXPECT_JSON_PARSE_TO_FAIL("0xB");
254 EXPECT_JSON_PARSE_TO_FAIL("0xF");
255 EXPECT_JSON_PARSE_TO_FAIL("0Xf");
256 EXPECT_JSON_PARSE_TO_FAIL("0X3");
257
258 EXPECT_JSON_PARSE_TO_FAIL("10ee1");
259 EXPECT_JSON_PARSE_TO_FAIL("1e1e1");
260
261 // These could be valid within an array but not as the top level value
262 EXPECT_JSON_PARSE_TO_FAIL("0,0");
263 EXPECT_JSON_PARSE_TO_FAIL(",1");
264 EXPECT_JSON_PARSE_TO_FAIL("10e1,");
265 EXPECT_JSON_PARSE_TO_FAIL("10e,1");
266 EXPECT_JSON_PARSE_TO_FAIL("10,e1");
267 EXPECT_JSON_PARSE_TO_FAIL("1,0e1");
268 EXPECT_JSON_PARSE_TO_FAIL(",10e1");
269
270#undef EXPECT_JSON_PARSE_TO_FAIL
271}
272
273struct CustomError {
274};
275
276template<typename T>
277class CustomErrorOr {
278public:
279 CustomErrorOr(T)
280 : m_is_error(false)
281 {
282 }
283
284 CustomErrorOr(CustomError)
285 : m_is_error(true)
286 {
287 }
288
289 bool is_error() const { return m_is_error; }
290 CustomError release_error() { return CustomError {}; }
291 T release_value() { return T {}; }
292
293private:
294 bool m_is_error { false };
295};
296
297TEST_CASE(fallible_json_object_for_each)
298{
299 DeprecatedString raw_json = R"(
300 {
301 "name": "anon",
302 "home": "/home/anon",
303 "default_browser": "Ladybird"
304 })";
305
306 auto json = JsonValue::from_string(raw_json).value();
307 auto const& object = json.as_object();
308
309 MUST(object.try_for_each_member([](auto const&, auto const&) -> ErrorOr<void> {
310 return {};
311 }));
312
313 auto result1 = object.try_for_each_member([](auto const&, auto const&) -> ErrorOr<void> {
314 return Error::from_string_view("nanananana"sv);
315 });
316 EXPECT(result1.is_error());
317 EXPECT_EQ(result1.error().string_literal(), "nanananana"sv);
318
319 auto result2 = object.try_for_each_member([](auto const&, auto const&) -> ErrorOr<void, CustomError> {
320 return CustomError {};
321 });
322 EXPECT(result2.is_error());
323 EXPECT((IsSame<decltype(result2.release_error()), CustomError>));
324
325 auto result3 = object.try_for_each_member([](auto const&, auto const&) -> CustomErrorOr<int> {
326 return 42;
327 });
328 EXPECT(!result3.is_error());
329
330 auto result4 = object.try_for_each_member([](auto const&, auto const&) -> CustomErrorOr<int> {
331 return CustomError {};
332 });
333 EXPECT(result4.is_error());
334 EXPECT((IsSame<decltype(result4.release_error()), CustomError>));
335}
336
337TEST_CASE(fallible_json_array_for_each)
338{
339 DeprecatedString raw_json = R"(
340 [
341 "anon",
342 "/home/anon",
343 "Ladybird"
344 ])";
345
346 auto json = JsonValue::from_string(raw_json).value();
347 auto const& array = json.as_array();
348
349 MUST(array.try_for_each([](auto const&) -> ErrorOr<void> {
350 return {};
351 }));
352
353 auto result1 = array.try_for_each([](auto const&) -> ErrorOr<void> {
354 return Error::from_string_view("nanananana"sv);
355 });
356 EXPECT(result1.is_error());
357 EXPECT_EQ(result1.error().string_literal(), "nanananana"sv);
358
359 auto result2 = array.try_for_each([](auto const&) -> ErrorOr<void, CustomError> {
360 return CustomError {};
361 });
362 EXPECT(result2.is_error());
363 EXPECT((IsSame<decltype(result2.release_error()), CustomError>));
364
365 auto result3 = array.try_for_each([](auto const&) -> CustomErrorOr<int> {
366 return 42;
367 });
368 EXPECT(!result3.is_error());
369
370 auto result4 = array.try_for_each([](auto const&) -> CustomErrorOr<int> {
371 return CustomError {};
372 });
373 EXPECT(result4.is_error());
374 EXPECT((IsSame<decltype(result4.release_error()), CustomError>));
375}
376
377TEST_CASE(json_value_as_integer)
378{
379 // is_integer() should validate based on the value, not the underlying type.
380 JsonValue value_int { static_cast<int>(42) };
381 JsonValue value_unsigned { static_cast<unsigned>(42) };
382 JsonValue value_long { static_cast<long>(42) };
383 JsonValue value_long_unsigned { static_cast<long unsigned>(42) };
384 JsonValue value_long_long { static_cast<long long>(42) };
385 JsonValue value_long_long_unsigned { static_cast<long long unsigned>(42) };
386
387 auto check_is_valid_for_all_types = [](JsonValue& value) {
388 EXPECT(value.is_integer<u8>());
389 EXPECT_EQ(value.as_integer<u8>(), static_cast<u8>(42));
390 EXPECT(value.is_integer<u16>());
391 EXPECT_EQ(value.as_integer<u16>(), static_cast<u16>(42));
392 EXPECT(value.is_integer<u32>());
393 EXPECT_EQ(value.as_integer<u32>(), static_cast<u32>(42));
394 EXPECT(value.is_integer<u64>());
395 EXPECT_EQ(value.as_integer<u64>(), static_cast<u64>(42));
396 EXPECT(value.is_integer<i8>());
397 EXPECT_EQ(value.as_integer<i8>(), static_cast<i8>(42));
398 EXPECT(value.is_integer<i16>());
399 EXPECT_EQ(value.as_integer<i16>(), static_cast<i16>(42));
400 EXPECT(value.is_integer<i32>());
401 EXPECT_EQ(value.as_integer<i32>(), static_cast<i32>(42));
402 EXPECT(value.is_integer<i64>());
403 EXPECT_EQ(value.as_integer<i64>(), static_cast<i64>(42));
404 };
405
406 check_is_valid_for_all_types(value_int);
407 check_is_valid_for_all_types(value_unsigned);
408 check_is_valid_for_all_types(value_long);
409 check_is_valid_for_all_types(value_long_unsigned);
410 check_is_valid_for_all_types(value_long_long);
411 check_is_valid_for_all_types(value_long_long_unsigned);
412
413 // Negative values should only fit in signed types.
414 JsonValue negative_value { -42 };
415 EXPECT(!negative_value.is_integer<u8>());
416 EXPECT(!negative_value.is_integer<u16>());
417 EXPECT(!negative_value.is_integer<u32>());
418 EXPECT(!negative_value.is_integer<u64>());
419 EXPECT(negative_value.is_integer<i8>());
420 EXPECT(negative_value.is_integer<i16>());
421 EXPECT(negative_value.is_integer<i32>());
422 EXPECT(negative_value.is_integer<i64>());
423
424 // 64-bit only
425 JsonValue very_large_value { INT64_MAX };
426 EXPECT(!very_large_value.is_integer<u8>());
427 EXPECT(!very_large_value.is_integer<u16>());
428 EXPECT(!very_large_value.is_integer<u32>());
429 EXPECT(very_large_value.is_integer<u64>());
430 EXPECT(!very_large_value.is_integer<i8>());
431 EXPECT(!very_large_value.is_integer<i16>());
432 EXPECT(!very_large_value.is_integer<i32>());
433 EXPECT(very_large_value.is_integer<i64>());
434}