1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/core/lib/json/json_object_loader.h"
16
17 #include <cstdint>
18
19 #include "absl/status/status.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22
23 #include <grpc/support/json.h>
24
25 #include "src/core/lib/gprpp/ref_counted.h"
26 #include "src/core/lib/gprpp/ref_counted_ptr.h"
27 #include "src/core/lib/json/json_reader.h"
28 #include "src/core/lib/json/json_writer.h"
29
30 namespace grpc_core {
31 namespace {
32
33 template <typename T>
Parse(absl::string_view json,const JsonArgs & args=JsonArgs ())34 absl::StatusOr<T> Parse(absl::string_view json,
35 const JsonArgs& args = JsonArgs()) {
36 auto parsed = JsonParse(json);
37 if (!parsed.ok()) return parsed.status();
38 return LoadFromJson<T>(*parsed, args);
39 }
40
41 //
42 // Signed integer tests
43 //
44
45 template <typename T>
46 class SignedIntegerTest : public ::testing::Test {};
47
48 TYPED_TEST_SUITE_P(SignedIntegerTest);
49
TYPED_TEST_P(SignedIntegerTest,IntegerFields)50 TYPED_TEST_P(SignedIntegerTest, IntegerFields) {
51 struct TestStruct {
52 TypeParam value = 0;
53 TypeParam optional_value = 0;
54 absl::optional<TypeParam> absl_optional_value;
55 std::unique_ptr<TypeParam> unique_ptr_value;
56
57 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
58 static const auto* loader =
59 JsonObjectLoader<TestStruct>()
60 .Field("value", &TestStruct::value)
61 .OptionalField("optional_value", &TestStruct::optional_value)
62 .OptionalField("absl_optional_value",
63 &TestStruct::absl_optional_value)
64 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
65 .Finish();
66 return loader;
67 }
68 };
69 // Positive number.
70 auto test_struct = Parse<TestStruct>("{\"value\": 5}");
71 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
72 EXPECT_EQ(test_struct->value, 5);
73 EXPECT_EQ(test_struct->optional_value, 0);
74 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
75 // Negative number.
76 test_struct = Parse<TestStruct>("{\"value\": -5}");
77 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
78 EXPECT_EQ(test_struct->value, -5);
79 EXPECT_EQ(test_struct->optional_value, 0);
80 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
81 // Encoded in a JSON string.
82 test_struct = Parse<TestStruct>("{\"value\": \"5\"}");
83 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
84 EXPECT_EQ(test_struct->value, 5);
85 EXPECT_EQ(test_struct->optional_value, 0);
86 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
87 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
88 // Fails to parse number from JSON string.
89 test_struct = Parse<TestStruct>("{\"value\": \"foo\"}");
90 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
91 EXPECT_EQ(
92 test_struct.status().message(),
93 "errors validating JSON: [field:value error:failed to parse number]")
94 << test_struct.status();
95 // Fails if required field is not present.
96 test_struct = Parse<TestStruct>("{}");
97 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
98 EXPECT_EQ(test_struct.status().message(),
99 "errors validating JSON: [field:value error:field not present]")
100 << test_struct.status();
101 // Optional fields present.
102 test_struct = Parse<TestStruct>(
103 "{\"value\": 5, \"optional_value\": 7, "
104 "\"absl_optional_value\": 9, \"unique_ptr_value\": 11}");
105 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
106 EXPECT_EQ(test_struct->value, 5);
107 EXPECT_EQ(test_struct->optional_value, 7);
108 EXPECT_EQ(test_struct->absl_optional_value, 9);
109 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
110 EXPECT_EQ(*test_struct->unique_ptr_value, 11);
111 // Optional fields null.
112 test_struct = Parse<TestStruct>(
113 "{\"value\": 5, \"optional_value\": null, "
114 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
115 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
116 EXPECT_EQ(test_struct->value, 5);
117 EXPECT_EQ(test_struct->optional_value, 0);
118 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
119 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
120 // Wrong JSON type.
121 test_struct = Parse<TestStruct>(
122 "{\"value\": [], \"optional_value\": {}, "
123 "\"absl_optional_value\": true, \"unique_ptr_value\": false}");
124 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
125 EXPECT_EQ(test_struct.status().message(),
126 "errors validating JSON: ["
127 "field:absl_optional_value error:is not a number; "
128 "field:optional_value error:is not a number; "
129 "field:unique_ptr_value error:is not a number; "
130 "field:value error:is not a number]")
131 << test_struct.status();
132 }
133
134 REGISTER_TYPED_TEST_SUITE_P(SignedIntegerTest, IntegerFields);
135
136 using IntegerTypes = ::testing::Types<int32_t, int64_t>;
137 INSTANTIATE_TYPED_TEST_SUITE_P(My, SignedIntegerTest, IntegerTypes);
138
139 //
140 // Unsigned integer tests
141 //
142
143 template <typename T>
144 class UnsignedIntegerTest : public ::testing::Test {};
145
146 TYPED_TEST_SUITE_P(UnsignedIntegerTest);
147
TYPED_TEST_P(UnsignedIntegerTest,IntegerFields)148 TYPED_TEST_P(UnsignedIntegerTest, IntegerFields) {
149 struct TestStruct {
150 TypeParam value = 0;
151 TypeParam optional_value = 0;
152 absl::optional<TypeParam> absl_optional_value;
153 std::unique_ptr<TypeParam> unique_ptr_value;
154
155 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
156 static const auto* loader =
157 JsonObjectLoader<TestStruct>()
158 .Field("value", &TestStruct::value)
159 .OptionalField("optional_value", &TestStruct::optional_value)
160 .OptionalField("absl_optional_value",
161 &TestStruct::absl_optional_value)
162 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
163 .Finish();
164 return loader;
165 }
166 };
167 // Positive number.
168 auto test_struct = Parse<TestStruct>("{\"value\": 5}");
169 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
170 EXPECT_EQ(test_struct->value, 5);
171 EXPECT_EQ(test_struct->optional_value, 0);
172 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
173 // Negative number.
174 test_struct = Parse<TestStruct>("{\"value\": -5}");
175 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
176 EXPECT_EQ(test_struct.status().message(),
177 "errors validating JSON: ["
178 "field:value error:failed to parse non-negative number]")
179 << test_struct.status();
180 // Encoded in a JSON string.
181 test_struct = Parse<TestStruct>("{\"value\": \"5\"}");
182 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
183 EXPECT_EQ(test_struct->value, 5);
184 EXPECT_EQ(test_struct->optional_value, 0);
185 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
186 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
187 // Fails to parse number from JSON string.
188 test_struct = Parse<TestStruct>("{\"value\": \"foo\"}");
189 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
190 EXPECT_EQ(test_struct.status().message(),
191 "errors validating JSON: ["
192 "field:value error:failed to parse non-negative number]")
193 << test_struct.status();
194 // Fails if required field is not present.
195 test_struct = Parse<TestStruct>("{}");
196 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
197 EXPECT_EQ(test_struct.status().message(),
198 "errors validating JSON: [field:value error:field not present]")
199 << test_struct.status();
200 // Optional fields present.
201 test_struct = Parse<TestStruct>(
202 "{\"value\": 5, \"optional_value\": 7, "
203 "\"absl_optional_value\": 9, \"unique_ptr_value\": 11}");
204 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
205 EXPECT_EQ(test_struct->value, 5);
206 EXPECT_EQ(test_struct->optional_value, 7);
207 ASSERT_TRUE(test_struct->absl_optional_value.has_value());
208 EXPECT_EQ(*test_struct->absl_optional_value, 9);
209 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
210 EXPECT_EQ(*test_struct->unique_ptr_value, 11);
211 // Optional fields null.
212 test_struct = Parse<TestStruct>(
213 "{\"value\": 5, \"optional_value\": null, "
214 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
215 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
216 EXPECT_EQ(test_struct->value, 5);
217 EXPECT_EQ(test_struct->optional_value, 0);
218 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
219 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
220 // Wrong JSON type.
221 test_struct = Parse<TestStruct>(
222 "{\"value\": [], \"optional_value\": {}, "
223 "\"absl_optional_value\": true, \"unique_ptr_value\": false}");
224 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
225 EXPECT_EQ(test_struct.status().message(),
226 "errors validating JSON: ["
227 "field:absl_optional_value error:is not a number; "
228 "field:optional_value error:is not a number; "
229 "field:unique_ptr_value error:is not a number; "
230 "field:value error:is not a number]")
231 << test_struct.status();
232 }
233
234 REGISTER_TYPED_TEST_SUITE_P(UnsignedIntegerTest, IntegerFields);
235
236 using UnsignedIntegerTypes = ::testing::Types<uint32_t, uint64_t>;
237 INSTANTIATE_TYPED_TEST_SUITE_P(My, UnsignedIntegerTest, UnsignedIntegerTypes);
238
239 //
240 // Floating-point tests
241 //
242
243 template <typename T>
244 class FloatingPointTest : public ::testing::Test {};
245
246 TYPED_TEST_SUITE_P(FloatingPointTest);
247
TYPED_TEST_P(FloatingPointTest,FloatFields)248 TYPED_TEST_P(FloatingPointTest, FloatFields) {
249 struct TestStruct {
250 TypeParam value = 0;
251 TypeParam optional_value = 0;
252 absl::optional<TypeParam> absl_optional_value;
253 std::unique_ptr<TypeParam> unique_ptr_value;
254
255 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
256 static const auto* loader =
257 JsonObjectLoader<TestStruct>()
258 .Field("value", &TestStruct::value)
259 .OptionalField("optional_value", &TestStruct::optional_value)
260 .OptionalField("absl_optional_value",
261 &TestStruct::absl_optional_value)
262 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
263 .Finish();
264 return loader;
265 }
266 };
267 // Positive number.
268 auto test_struct = Parse<TestStruct>("{\"value\": 5.2}");
269 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
270 EXPECT_NEAR(test_struct->value, 5.2, 0.0001);
271 EXPECT_EQ(test_struct->optional_value, 0);
272 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
273 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
274 // Negative number.
275 test_struct = Parse<TestStruct>("{\"value\": -5.2}");
276 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
277 EXPECT_NEAR(test_struct->value, -5.2, 0.0001);
278 // Encoded in a JSON string.
279 test_struct = Parse<TestStruct>("{\"value\": \"5.2\"}");
280 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
281 EXPECT_NEAR(test_struct->value, 5.2, 0.0001);
282 EXPECT_EQ(test_struct->optional_value, 0);
283 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
284 // Fails to parse number from JSON string.
285 test_struct = Parse<TestStruct>("{\"value\": \"foo\"}");
286 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
287 EXPECT_EQ(test_struct.status().message(),
288 "errors validating JSON: ["
289 "field:value error:failed to parse floating-point number]")
290 << test_struct.status();
291 // Fails if required field is not present.
292 test_struct = Parse<TestStruct>("{}");
293 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
294 EXPECT_EQ(test_struct.status().message(),
295 "errors validating JSON: [field:value error:field not present]")
296 << test_struct.status();
297 // Optional fields present.
298 test_struct = Parse<TestStruct>(
299 "{\"value\": 5.2, \"optional_value\": 7.5, "
300 "\"absl_optional_value\": 9.8, \"unique_ptr_value\": 11.5}");
301 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
302 EXPECT_NEAR(test_struct->value, 5.2, 0.0001);
303 EXPECT_NEAR(test_struct->optional_value, 7.5, 0.0001);
304 ASSERT_TRUE(test_struct->absl_optional_value.has_value());
305 EXPECT_NEAR(*test_struct->absl_optional_value, 9.8, 0.0001);
306 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
307 EXPECT_NEAR(*test_struct->unique_ptr_value, 11.5, 0.0001);
308 // Optional fields null.
309 test_struct = Parse<TestStruct>(
310 "{\"value\": 5.2, \"optional_value\": null, "
311 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
312 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
313 EXPECT_NEAR(test_struct->value, 5.2, 0.0001);
314 EXPECT_EQ(test_struct->optional_value, 0);
315 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
316 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
317 // Wrong JSON type.
318 test_struct = Parse<TestStruct>(
319 "{\"value\": [], \"optional_value\": {}, "
320 "\"absl_optional_value\": true, \"unique_ptr_value\": false}");
321 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
322 EXPECT_EQ(test_struct.status().message(),
323 "errors validating JSON: ["
324 "field:absl_optional_value error:is not a number; "
325 "field:optional_value error:is not a number; "
326 "field:unique_ptr_value error:is not a number; "
327 "field:value error:is not a number]")
328 << test_struct.status();
329 }
330
331 REGISTER_TYPED_TEST_SUITE_P(FloatingPointTest, FloatFields);
332
333 using FloatingPointTypes = ::testing::Types<float, double>;
334 INSTANTIATE_TYPED_TEST_SUITE_P(My, FloatingPointTest, FloatingPointTypes);
335
336 //
337 // Boolean tests
338 //
339
TEST(JsonObjectLoader,BooleanFields)340 TEST(JsonObjectLoader, BooleanFields) {
341 struct TestStruct {
342 bool value = false;
343 bool optional_value = true;
344 absl::optional<bool> absl_optional_value;
345 std::unique_ptr<bool> unique_ptr_value;
346
347 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
348 static const auto* loader =
349 JsonObjectLoader<TestStruct>()
350 .Field("value", &TestStruct::value)
351 .OptionalField("optional_value", &TestStruct::optional_value)
352 .OptionalField("absl_optional_value",
353 &TestStruct::absl_optional_value)
354 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
355 .Finish();
356 return loader;
357 }
358 };
359 // True.
360 auto test_struct = Parse<TestStruct>("{\"value\": true}");
361 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
362 EXPECT_EQ(test_struct->value, true);
363 EXPECT_EQ(test_struct->optional_value, true); // Unmodified.
364 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
365 // False.
366 test_struct = Parse<TestStruct>("{\"value\": false}");
367 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
368 EXPECT_EQ(test_struct->value, false);
369 EXPECT_EQ(test_struct->optional_value, true); // Unmodified.
370 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
371 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
372 // Fails if required field is not present.
373 test_struct = Parse<TestStruct>("{}");
374 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
375 EXPECT_EQ(test_struct.status().message(),
376 "errors validating JSON: [field:value error:field not present]")
377 << test_struct.status();
378 // Optional fields present.
379 test_struct = Parse<TestStruct>(
380 "{\"value\": true, \"optional_value\": false,"
381 "\"absl_optional_value\": true, \"unique_ptr_value\": false}");
382 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
383 EXPECT_EQ(test_struct->value, true);
384 EXPECT_EQ(test_struct->optional_value, false);
385 EXPECT_EQ(test_struct->absl_optional_value, true);
386 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
387 EXPECT_EQ(*test_struct->unique_ptr_value, false);
388 // Optional fields null.
389 test_struct = Parse<TestStruct>(
390 "{\"value\": true, \"optional_value\": null,"
391 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
392 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
393 EXPECT_EQ(test_struct->value, true);
394 EXPECT_EQ(test_struct->optional_value, true); // Unmodified.
395 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
396 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
397 // Wrong JSON type.
398 test_struct = Parse<TestStruct>(
399 "{\"value\": [], \"optional_value\": {}, "
400 "\"absl_optional_value\": 1, \"unique_ptr_value\": \"foo\"}");
401 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
402 EXPECT_EQ(test_struct.status().message(),
403 "errors validating JSON: ["
404 "field:absl_optional_value error:is not a boolean; "
405 "field:optional_value error:is not a boolean; "
406 "field:unique_ptr_value error:is not a boolean; "
407 "field:value error:is not a boolean]")
408 << test_struct.status();
409 }
410
411 //
412 // String tests
413 //
414
TEST(JsonObjectLoader,StringFields)415 TEST(JsonObjectLoader, StringFields) {
416 struct TestStruct {
417 std::string value;
418 std::string optional_value;
419 absl::optional<std::string> absl_optional_value;
420 std::unique_ptr<std::string> unique_ptr_value;
421
422 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
423 static const auto* loader =
424 JsonObjectLoader<TestStruct>()
425 .Field("value", &TestStruct::value)
426 .OptionalField("optional_value", &TestStruct::optional_value)
427 .OptionalField("absl_optional_value",
428 &TestStruct::absl_optional_value)
429 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
430 .Finish();
431 return loader;
432 }
433 };
434 // Valid string.
435 auto test_struct = Parse<TestStruct>("{\"value\": \"foo\"}");
436 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
437 EXPECT_EQ(test_struct->value, "foo");
438 EXPECT_EQ(test_struct->optional_value, "");
439 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
440 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
441 // Fails if required field is not present.
442 test_struct = Parse<TestStruct>("{}");
443 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
444 EXPECT_EQ(test_struct.status().message(),
445 "errors validating JSON: [field:value error:field not present]")
446 << test_struct.status();
447 // Optional fields present.
448 test_struct = Parse<TestStruct>(
449 "{\"value\": \"foo\", \"optional_value\": \"bar\","
450 "\"absl_optional_value\": \"baz\", \"unique_ptr_value\": \"quux\"}");
451 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
452 EXPECT_EQ(test_struct->value, "foo");
453 EXPECT_EQ(test_struct->optional_value, "bar");
454 EXPECT_EQ(test_struct->absl_optional_value, "baz");
455 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
456 EXPECT_EQ(*test_struct->unique_ptr_value, "quux");
457 // Optional fields null.
458 test_struct = Parse<TestStruct>(
459 "{\"value\": \"foo\", \"optional_value\": null,"
460 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
461 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
462 EXPECT_EQ(test_struct->value, "foo");
463 EXPECT_EQ(test_struct->optional_value, "");
464 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
465 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
466 // Wrong JSON type.
467 test_struct = Parse<TestStruct>(
468 "{\"value\": [], \"optional_value\": {}, "
469 "\"absl_optional_value\": 1, \"unique_ptr_value\": true}");
470 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
471 EXPECT_EQ(test_struct.status().message(),
472 "errors validating JSON: ["
473 "field:absl_optional_value error:is not a string; "
474 "field:optional_value error:is not a string; "
475 "field:unique_ptr_value error:is not a string; "
476 "field:value error:is not a string]")
477 << test_struct.status();
478 }
479
480 //
481 // Duration tests
482 //
483
TEST(JsonObjectLoader,DurationFields)484 TEST(JsonObjectLoader, DurationFields) {
485 struct TestStruct {
486 Duration value = Duration::Zero();
487 Duration optional_value = Duration::Zero();
488 absl::optional<Duration> absl_optional_value;
489 std::unique_ptr<Duration> unique_ptr_value;
490
491 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
492 static const auto* loader =
493 JsonObjectLoader<TestStruct>()
494 .Field("value", &TestStruct::value)
495 .OptionalField("optional_value", &TestStruct::optional_value)
496 .OptionalField("absl_optional_value",
497 &TestStruct::absl_optional_value)
498 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
499 .Finish();
500 return loader;
501 }
502 };
503 // Valid duration string.
504 auto test_struct = Parse<TestStruct>("{\"value\": \"3s\"}");
505 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
506 EXPECT_EQ(test_struct->value, Duration::Seconds(3));
507 EXPECT_EQ(test_struct->optional_value, Duration::Zero());
508 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
509 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
510 // Invalid duration strings.
511 test_struct = Parse<TestStruct>(
512 "{\"value\": \"3sec\", \"optional_value\": \"foos\","
513 "\"absl_optional_value\": \"1.0123456789s\"}");
514 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
515 EXPECT_EQ(test_struct.status().message(),
516 "errors validating JSON: ["
517 "field:absl_optional_value error:"
518 "Not a duration (too many digits after decimal); "
519 "field:optional_value error:"
520 "Not a duration (not a number of seconds); "
521 "field:value error:Not a duration (no s suffix)]")
522 << test_struct.status();
523 test_struct = Parse<TestStruct>("{\"value\": \"315576000001s\"}");
524 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
525 EXPECT_EQ(test_struct.status().message(),
526 "errors validating JSON: ["
527 "field:value error:seconds must be in the range [0, 315576000000]]")
528 << test_struct.status();
529 test_struct = Parse<TestStruct>("{\"value\": \"3.xs\"}");
530 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
531 EXPECT_EQ(test_struct.status().message(),
532 "errors validating JSON: ["
533 "field:value error:Not a duration (not a number of nanoseconds)]")
534 << test_struct.status();
535 // Fails if required field is not present.
536 test_struct = Parse<TestStruct>("{}");
537 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
538 EXPECT_EQ(test_struct.status().message(),
539 "errors validating JSON: [field:value error:field not present]")
540 << test_struct.status();
541 // Optional fields present.
542 test_struct = Parse<TestStruct>(
543 "{\"value\": \"3s\", \"optional_value\": \"3.2s\", "
544 "\"absl_optional_value\": \"10s\", \"unique_ptr_value\": \"11s\"}");
545 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
546 EXPECT_EQ(test_struct->value, Duration::Seconds(3));
547 EXPECT_EQ(test_struct->optional_value, Duration::Milliseconds(3200));
548 EXPECT_EQ(test_struct->absl_optional_value, Duration::Seconds(10));
549 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
550 EXPECT_EQ(*test_struct->unique_ptr_value, Duration::Seconds(11));
551 // Optional fields null.
552 test_struct = Parse<TestStruct>(
553 "{\"value\": \"3s\", \"optional_value\": null, "
554 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
555 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
556 EXPECT_EQ(test_struct->value, Duration::Seconds(3));
557 EXPECT_EQ(test_struct->optional_value, Duration::Zero());
558 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
559 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
560 // Wrong JSON type.
561 test_struct = Parse<TestStruct>(
562 "{\"value\": [], \"optional_value\": {}, "
563 "\"absl_optional_value\": 1, \"unique_ptr_value\": true}");
564 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
565 EXPECT_EQ(test_struct.status().message(),
566 "errors validating JSON: ["
567 "field:absl_optional_value error:is not a string; "
568 "field:optional_value error:is not a string; "
569 "field:unique_ptr_value error:is not a string; "
570 "field:value error:is not a string]")
571 << test_struct.status();
572 }
573
574 //
575 // Json::Object tests
576 //
577
TEST(JsonObjectLoader,JsonObjectFields)578 TEST(JsonObjectLoader, JsonObjectFields) {
579 struct TestStruct {
580 Json::Object value;
581 Json::Object optional_value;
582 absl::optional<Json::Object> absl_optional_value;
583 std::unique_ptr<Json::Object> unique_ptr_value;
584
585 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
586 static const auto* loader =
587 JsonObjectLoader<TestStruct>()
588 .Field("value", &TestStruct::value)
589 .OptionalField("optional_value", &TestStruct::optional_value)
590 .OptionalField("absl_optional_value",
591 &TestStruct::absl_optional_value)
592 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
593 .Finish();
594 return loader;
595 }
596 };
597 // Valid object.
598 auto test_struct = Parse<TestStruct>("{\"value\": {\"a\":1}}");
599 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
600 EXPECT_EQ(JsonDump(Json::FromObject(test_struct->value)), "{\"a\":1}");
601 EXPECT_EQ(JsonDump(Json::FromObject(test_struct->optional_value)), "{}");
602 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
603 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
604 // Fails if required field is not present.
605 test_struct = Parse<TestStruct>("{}");
606 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
607 EXPECT_EQ(test_struct.status().message(),
608 "errors validating JSON: [field:value error:field not present]")
609 << test_struct.status();
610 // Optional fields present.
611 test_struct = Parse<TestStruct>(
612 "{\"value\": {\"a\":1}, \"optional_value\": {\"b\":2}, "
613 "\"absl_optional_value\": {\"c\":3}, \"unique_ptr_value\": {\"d\":4}}");
614 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
615 EXPECT_EQ(JsonDump(Json::FromObject(test_struct->value)), "{\"a\":1}");
616 EXPECT_EQ(JsonDump(Json::FromObject(test_struct->optional_value)),
617 "{\"b\":2}");
618 ASSERT_TRUE(test_struct->absl_optional_value.has_value());
619 EXPECT_EQ(JsonDump(Json::FromObject(*test_struct->absl_optional_value)),
620 "{\"c\":3}");
621 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
622 EXPECT_EQ(JsonDump(Json::FromObject(*test_struct->unique_ptr_value)),
623 "{\"d\":4}");
624 // Optional fields null.
625 test_struct = Parse<TestStruct>(
626 "{\"value\": {\"a\":1}, \"optional_value\": null, "
627 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
628 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
629 EXPECT_EQ(JsonDump(Json::FromObject(test_struct->value)), "{\"a\":1}");
630 EXPECT_EQ(JsonDump(Json::FromObject(test_struct->optional_value)), "{}");
631 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
632 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
633 // Wrong JSON type.
634 test_struct = Parse<TestStruct>(
635 "{\"value\": [], \"optional_value\": true, "
636 "\"absl_optional_value\": 1, \"unique_ptr_value\": \"foo\"}");
637 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
638 EXPECT_EQ(test_struct.status().message(),
639 "errors validating JSON: ["
640 "field:absl_optional_value error:is not an object; "
641 "field:optional_value error:is not an object; "
642 "field:unique_ptr_value error:is not an object; "
643 "field:value error:is not an object]")
644 << test_struct.status();
645 }
646
647 //
648 // Json::Array tests
649 //
650
TEST(JsonObjectLoader,JsonArrayFields)651 TEST(JsonObjectLoader, JsonArrayFields) {
652 struct TestStruct {
653 Json::Array value;
654 Json::Array optional_value;
655 absl::optional<Json::Array> absl_optional_value;
656 std::unique_ptr<Json::Array> unique_ptr_value;
657
658 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
659 static const auto* loader =
660 JsonObjectLoader<TestStruct>()
661 .Field("value", &TestStruct::value)
662 .OptionalField("optional_value", &TestStruct::optional_value)
663 .OptionalField("absl_optional_value",
664 &TestStruct::absl_optional_value)
665 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
666 .Finish();
667 return loader;
668 }
669 };
670 // Valid object.
671 auto test_struct = Parse<TestStruct>("{\"value\": [1, \"a\"]}");
672 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
673 EXPECT_EQ(JsonDump(Json::FromArray(test_struct->value)), "[1,\"a\"]");
674 EXPECT_EQ(JsonDump(Json::FromArray(test_struct->optional_value)), "[]");
675 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
676 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
677 // Fails if required field is not present.
678 test_struct = Parse<TestStruct>("{}");
679 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
680 EXPECT_EQ(test_struct.status().message(),
681 "errors validating JSON: [field:value error:field not present]")
682 << test_struct.status();
683 // Optional fields present.
684 test_struct = Parse<TestStruct>(
685 "{\"value\": [1, \"a\"], \"optional_value\": [2, \"b\"], "
686 "\"absl_optional_value\": [3, \"c\"], \"unique_ptr_value\": [4, \"d\"]}");
687 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
688 EXPECT_EQ(JsonDump(Json::FromArray(test_struct->value)), "[1,\"a\"]");
689 EXPECT_EQ(JsonDump(Json::FromArray(test_struct->optional_value)),
690 "[2,\"b\"]");
691 ASSERT_TRUE(test_struct->absl_optional_value.has_value());
692 EXPECT_EQ(JsonDump(Json::FromArray(*test_struct->absl_optional_value)),
693 "[3,\"c\"]");
694 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
695 EXPECT_EQ(JsonDump(Json::FromArray(*test_struct->unique_ptr_value)),
696 "[4,\"d\"]");
697 // Optional fields null.
698 test_struct = Parse<TestStruct>(
699 "{\"value\": [1, \"a\"], \"optional_value\": null, "
700 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
701 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
702 EXPECT_EQ(JsonDump(Json::FromArray(test_struct->value)), "[1,\"a\"]");
703 EXPECT_EQ(JsonDump(Json::FromArray(test_struct->optional_value)), "[]");
704 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
705 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
706 // Wrong JSON type.
707 test_struct = Parse<TestStruct>(
708 "{\"value\": {}, \"optional_value\": true, "
709 "\"absl_optional_value\": 1, \"unique_ptr_value\": \"foo\"}");
710 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
711 EXPECT_EQ(test_struct.status().message(),
712 "errors validating JSON: ["
713 "field:absl_optional_value error:is not an array; "
714 "field:optional_value error:is not an array; "
715 "field:unique_ptr_value error:is not an array; "
716 "field:value error:is not an array]")
717 << test_struct.status();
718 }
719
720 //
721 // map<> tests
722 //
723
TEST(JsonObjectLoader,MapFields)724 TEST(JsonObjectLoader, MapFields) {
725 struct TestStruct {
726 std::map<std::string, int32_t> value;
727 std::map<std::string, std::string> optional_value;
728 absl::optional<std::map<std::string, bool>> absl_optional_value;
729 std::unique_ptr<std::map<std::string, int32_t>> unique_ptr_value;
730
731 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
732 static const auto* loader =
733 JsonObjectLoader<TestStruct>()
734 .Field("value", &TestStruct::value)
735 .OptionalField("optional_value", &TestStruct::optional_value)
736 .OptionalField("absl_optional_value",
737 &TestStruct::absl_optional_value)
738 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
739 .Finish();
740 return loader;
741 }
742 };
743 // Valid map.
744 auto test_struct = Parse<TestStruct>("{\"value\": {\"a\":1}}");
745 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
746 EXPECT_THAT(test_struct->value,
747 ::testing::ElementsAre(::testing::Pair("a", 1)));
748 EXPECT_THAT(test_struct->optional_value, ::testing::ElementsAre());
749 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
750 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
751 // Fails if required field is not present.
752 test_struct = Parse<TestStruct>("{}");
753 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
754 EXPECT_EQ(test_struct.status().message(),
755 "errors validating JSON: [field:value error:field not present]")
756 << test_struct.status();
757 // Optional fields present.
758 test_struct = Parse<TestStruct>(
759 "{\"value\": {\"a\":1}, \"optional_value\": {\"b\":\"foo\"}, "
760 "\"absl_optional_value\": {\"c\":true}, "
761 "\"unique_ptr_value\": {\"d\":4}}");
762 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
763 EXPECT_THAT(test_struct->value,
764 ::testing::ElementsAre(::testing::Pair("a", 1)));
765 EXPECT_THAT(test_struct->optional_value,
766 ::testing::ElementsAre(::testing::Pair("b", "foo")));
767 ASSERT_TRUE(test_struct->absl_optional_value.has_value());
768 EXPECT_THAT(*test_struct->absl_optional_value,
769 ::testing::ElementsAre(::testing::Pair("c", true)));
770 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
771 EXPECT_THAT(*test_struct->unique_ptr_value,
772 ::testing::ElementsAre(::testing::Pair("d", 4)));
773 // Optional fields null.
774 test_struct = Parse<TestStruct>(
775 "{\"value\": {\"a\":1}, \"optional_value\": null, "
776 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
777 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
778 EXPECT_THAT(test_struct->value,
779 ::testing::ElementsAre(::testing::Pair("a", 1)));
780 EXPECT_THAT(test_struct->optional_value, ::testing::ElementsAre());
781 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
782 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
783 // Wrong JSON type.
784 test_struct = Parse<TestStruct>(
785 "{\"value\": [], \"optional_value\": true, "
786 "\"absl_optional_value\": 1, \"unique_ptr_value\": \"foo\"}");
787 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
788 EXPECT_EQ(test_struct.status().message(),
789 "errors validating JSON: ["
790 "field:absl_optional_value error:is not an object; "
791 "field:optional_value error:is not an object; "
792 "field:unique_ptr_value error:is not an object; "
793 "field:value error:is not an object]")
794 << test_struct.status();
795 // Wrong JSON type for map value.
796 test_struct = Parse<TestStruct>(
797 "{\"value\": {\"a\":\"foo\"}, \"optional_value\": {\"b\":true}, "
798 "\"absl_optional_value\": {\"c\":1}}");
799 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
800 EXPECT_EQ(test_struct.status().message(),
801 "errors validating JSON: ["
802 "field:absl_optional_value[\"c\"] error:is not a boolean; "
803 "field:optional_value[\"b\"] error:is not a string; "
804 "field:value[\"a\"] error:failed to parse number]")
805 << test_struct.status();
806 }
807
808 //
809 // vector<> tests
810 //
811
TEST(JsonObjectLoader,VectorFields)812 TEST(JsonObjectLoader, VectorFields) {
813 struct TestStruct {
814 std::vector<int32_t> value;
815 std::vector<std::string> optional_value;
816 absl::optional<std::vector<bool>> absl_optional_value;
817 std::unique_ptr<std::vector<int32_t>> unique_ptr_value;
818
819 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
820 static const auto* loader =
821 JsonObjectLoader<TestStruct>()
822 .Field("value", &TestStruct::value)
823 .OptionalField("optional_value", &TestStruct::optional_value)
824 .OptionalField("absl_optional_value",
825 &TestStruct::absl_optional_value)
826 .OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
827 .Finish();
828 return loader;
829 }
830 };
831 // Valid map.
832 auto test_struct = Parse<TestStruct>("{\"value\": [1, 2, 3]}");
833 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
834 EXPECT_THAT(test_struct->value, ::testing::ElementsAre(1, 2, 3));
835 EXPECT_THAT(test_struct->optional_value, ::testing::ElementsAre());
836 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
837 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
838 // Fails if required field is not present.
839 test_struct = Parse<TestStruct>("{}");
840 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
841 EXPECT_EQ(test_struct.status().message(),
842 "errors validating JSON: [field:value error:field not present]")
843 << test_struct.status();
844 // Optional fields present.
845 test_struct = Parse<TestStruct>(
846 "{\"value\": [4, 5, 6], \"optional_value\": [\"foo\", \"bar\"], "
847 "\"absl_optional_value\": [true, false, true], "
848 "\"unique_ptr_value\": [1, 2, 3]}");
849 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
850 EXPECT_THAT(test_struct->value, ::testing::ElementsAre(4, 5, 6));
851 EXPECT_THAT(test_struct->optional_value,
852 ::testing::ElementsAre("foo", "bar"));
853 ASSERT_TRUE(test_struct->absl_optional_value.has_value());
854 EXPECT_THAT(*test_struct->absl_optional_value,
855 ::testing::ElementsAre(true, false, true));
856 ASSERT_NE(test_struct->unique_ptr_value, nullptr);
857 EXPECT_THAT(*test_struct->unique_ptr_value, ::testing::ElementsAre(1, 2, 3));
858 // Optional fields null.
859 test_struct = Parse<TestStruct>(
860 "{\"value\": [4, 5, 6], \"optional_value\": null, "
861 "\"absl_optional_value\": null, \"unique_ptr_value\": null}");
862 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
863 EXPECT_THAT(test_struct->value, ::testing::ElementsAre(4, 5, 6));
864 EXPECT_THAT(test_struct->optional_value, ::testing::ElementsAre());
865 EXPECT_FALSE(test_struct->absl_optional_value.has_value());
866 EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
867 // Wrong JSON type.
868 test_struct = Parse<TestStruct>(
869 "{\"value\": {}, \"optional_value\": true, "
870 "\"absl_optional_value\": 1, \"unique_ptr_value\": \"foo\"}");
871 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
872 EXPECT_EQ(test_struct.status().message(),
873 "errors validating JSON: ["
874 "field:absl_optional_value error:is not an array; "
875 "field:optional_value error:is not an array; "
876 "field:unique_ptr_value error:is not an array; "
877 "field:value error:is not an array]")
878 << test_struct.status();
879 // Wrong JSON type for map value.
880 test_struct = Parse<TestStruct>(
881 "{\"value\": [\"foo\", \"bar\"], \"optional_value\": [true, false], "
882 "\"absl_optional_value\": [1, 2]}");
883 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
884 EXPECT_EQ(test_struct.status().message(),
885 "errors validating JSON: ["
886 "field:absl_optional_value[0] error:is not a boolean; "
887 "field:absl_optional_value[1] error:is not a boolean; "
888 "field:optional_value[0] error:is not a string; "
889 "field:optional_value[1] error:is not a string; "
890 "field:value[0] error:failed to parse number; "
891 "field:value[1] error:failed to parse number]")
892 << test_struct.status();
893 }
894
895 //
896 // Nested struct tests
897 //
898
TEST(JsonObjectLoader,NestedStructFields)899 TEST(JsonObjectLoader, NestedStructFields) {
900 struct NestedStruct {
901 int32_t inner = 0;
902
903 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
904 static const auto* loader = JsonObjectLoader<NestedStruct>()
905 .Field("inner", &NestedStruct::inner)
906 .Finish();
907 return loader;
908 }
909 };
910 struct TestStruct {
911 NestedStruct outer;
912 NestedStruct optional_outer;
913 absl::optional<NestedStruct> absl_optional_outer;
914 std::unique_ptr<NestedStruct> unique_ptr_outer;
915
916 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
917 static const auto* loader =
918 JsonObjectLoader<TestStruct>()
919 .Field("outer", &TestStruct::outer)
920 .OptionalField("optional_outer", &TestStruct::optional_outer)
921 .OptionalField("absl_optional_outer",
922 &TestStruct::absl_optional_outer)
923 .OptionalField("unique_ptr_outer", &TestStruct::unique_ptr_outer)
924 .Finish();
925 return loader;
926 }
927 };
928 // Valid nested struct.
929 auto test_struct = Parse<TestStruct>("{\"outer\": {\"inner\": 1}}");
930 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
931 EXPECT_EQ(test_struct->outer.inner, 1);
932 EXPECT_EQ(test_struct->optional_outer.inner, 0);
933 EXPECT_FALSE(test_struct->absl_optional_outer.has_value());
934 EXPECT_EQ(test_struct->unique_ptr_outer, nullptr);
935 // Fails if required field is not present.
936 test_struct = Parse<TestStruct>("{}");
937 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
938 EXPECT_EQ(test_struct.status().message(),
939 "errors validating JSON: [field:outer error:field not present]")
940 << test_struct.status();
941 // Fails if inner required field is not present.
942 test_struct = Parse<TestStruct>("{\"outer\": {}}");
943 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
944 EXPECT_EQ(
945 test_struct.status().message(),
946 "errors validating JSON: [field:outer.inner error:field not present]")
947 << test_struct.status();
948 // Optional fields present.
949 test_struct = Parse<TestStruct>(
950 "{\"outer\": {\"inner\":1}, \"optional_outer\": {\"inner\":2}, "
951 "\"absl_optional_outer\": {\"inner\":3}, "
952 "\"unique_ptr_outer\": {\"inner\":4}}");
953 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
954 EXPECT_EQ(test_struct->outer.inner, 1);
955 EXPECT_EQ(test_struct->optional_outer.inner, 2);
956 ASSERT_TRUE(test_struct->absl_optional_outer.has_value());
957 EXPECT_EQ(test_struct->absl_optional_outer->inner, 3);
958 ASSERT_NE(test_struct->unique_ptr_outer, nullptr);
959 EXPECT_EQ(test_struct->unique_ptr_outer->inner, 4);
960 // Optional fields null.
961 test_struct = Parse<TestStruct>(
962 "{\"outer\": {\"inner\":1}, \"optional_outer\": null, "
963 "\"absl_optional_outer\": null, \"unique_ptr_outer\": null}");
964 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
965 EXPECT_EQ(test_struct->outer.inner, 1);
966 EXPECT_EQ(test_struct->optional_outer.inner, 0);
967 EXPECT_FALSE(test_struct->absl_optional_outer.has_value());
968 EXPECT_EQ(test_struct->unique_ptr_outer, nullptr);
969 // Wrong JSON type.
970 test_struct = Parse<TestStruct>(
971 "{\"outer\": \"foo\", \"optional_outer\": true, "
972 "\"absl_optional_outer\": 1, \"unique_ptr_outer\": \"foo\"}");
973 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
974 EXPECT_EQ(test_struct.status().message(),
975 "errors validating JSON: ["
976 "field:absl_optional_outer error:is not an object; "
977 "field:optional_outer error:is not an object; "
978 "field:outer error:is not an object; "
979 "field:unique_ptr_outer error:is not an object]")
980 << test_struct.status();
981 // Wrong JSON type for inner value.
982 test_struct = Parse<TestStruct>(
983 "{\"outer\": {\"inner\":\"foo\"}, \"optional_outer\": {\"inner\":true}, "
984 "\"absl_optional_outer\": {\"inner\":[]}}");
985 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
986 EXPECT_EQ(test_struct.status().message(),
987 "errors validating JSON: ["
988 "field:absl_optional_outer.inner error:is not a number; "
989 "field:optional_outer.inner error:is not a number; "
990 "field:outer.inner error:failed to parse number]")
991 << test_struct.status();
992 }
993
TEST(JsonObjectLoader,BareString)994 TEST(JsonObjectLoader, BareString) {
995 auto parsed = Parse<std::string>("\"foo\"");
996 ASSERT_TRUE(parsed.ok()) << parsed.status();
997 EXPECT_EQ(*parsed, "foo");
998 parsed = Parse<std::string>("null");
999 EXPECT_EQ(parsed.status().message(),
1000 "errors validating JSON: [field: error:is not a string]")
1001 << parsed.status();
1002 }
1003
TEST(JsonObjectLoader,BareDuration)1004 TEST(JsonObjectLoader, BareDuration) {
1005 auto parsed = Parse<Duration>("\"1.5s\"");
1006 ASSERT_TRUE(parsed.ok()) << parsed.status();
1007 EXPECT_EQ(*parsed, Duration::Milliseconds(1500));
1008 parsed = Parse<Duration>("null");
1009 EXPECT_EQ(parsed.status().message(),
1010 "errors validating JSON: [field: error:is not a string]")
1011 << parsed.status();
1012 }
1013
TEST(JsonObjectLoader,BareSignedInteger)1014 TEST(JsonObjectLoader, BareSignedInteger) {
1015 auto parsed = Parse<int32_t>("5");
1016 ASSERT_TRUE(parsed.ok()) << parsed.status();
1017 EXPECT_EQ(*parsed, 5);
1018 parsed = Parse<int32_t>("null");
1019 EXPECT_EQ(parsed.status().message(),
1020 "errors validating JSON: [field: error:is not a number]")
1021 << parsed.status();
1022 }
1023
TEST(JsonObjectLoader,BareUnsignedInteger)1024 TEST(JsonObjectLoader, BareUnsignedInteger) {
1025 auto parsed = Parse<uint32_t>("5");
1026 ASSERT_TRUE(parsed.ok()) << parsed.status();
1027 EXPECT_EQ(*parsed, 5);
1028 parsed = Parse<uint32_t>("null");
1029 EXPECT_EQ(parsed.status().message(),
1030 "errors validating JSON: [field: error:is not a number]")
1031 << parsed.status();
1032 }
1033
TEST(JsonObjectLoader,BareFloat)1034 TEST(JsonObjectLoader, BareFloat) {
1035 auto parsed = Parse<float>("5.2");
1036 ASSERT_TRUE(parsed.ok()) << parsed.status();
1037 EXPECT_NEAR(*parsed, 5.2, 0.001);
1038 parsed = Parse<float>("null");
1039 EXPECT_EQ(parsed.status().message(),
1040 "errors validating JSON: [field: error:is not a number]")
1041 << parsed.status();
1042 }
1043
TEST(JsonObjectLoader,BareBool)1044 TEST(JsonObjectLoader, BareBool) {
1045 auto parsed = Parse<bool>("true");
1046 ASSERT_TRUE(parsed.ok()) << parsed.status();
1047 EXPECT_TRUE(*parsed);
1048 parsed = Parse<bool>("null");
1049 EXPECT_EQ(parsed.status().message(),
1050 "errors validating JSON: [field: error:is not a boolean]")
1051 << parsed.status();
1052 }
1053
TEST(JsonObjectLoader,BareOptional)1054 TEST(JsonObjectLoader, BareOptional) {
1055 auto parsed = Parse<absl::optional<uint32_t>>("3");
1056 ASSERT_TRUE(parsed.ok()) << parsed.status();
1057 ASSERT_TRUE(parsed->has_value());
1058 EXPECT_EQ(**parsed, 3);
1059 parsed = Parse<absl::optional<uint32_t>>("null");
1060 EXPECT_EQ(parsed.status().message(),
1061 "errors validating JSON: [field: error:is not a number]")
1062 << parsed.status();
1063 }
1064
TEST(JsonObjectLoader,BareUniquePtr)1065 TEST(JsonObjectLoader, BareUniquePtr) {
1066 auto parsed = Parse<std::unique_ptr<uint32_t>>("3");
1067 ASSERT_TRUE(parsed.ok()) << parsed.status();
1068 ASSERT_NE(*parsed, nullptr);
1069 EXPECT_EQ(**parsed, 3);
1070 parsed = Parse<std::unique_ptr<uint32_t>>("null");
1071 EXPECT_EQ(parsed.status().message(),
1072 "errors validating JSON: [field: error:is not a number]")
1073 << parsed.status();
1074 }
1075
TEST(JsonObjectLoader,BareRefCountedPtr)1076 TEST(JsonObjectLoader, BareRefCountedPtr) {
1077 class RefCountedObject : public RefCounted<RefCountedObject> {
1078 public:
1079 RefCountedObject() = default;
1080
1081 int value() const { return value_; }
1082
1083 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
1084 static const auto* loader = JsonObjectLoader<RefCountedObject>()
1085 .Field("value", &RefCountedObject::value_)
1086 .Finish();
1087 return loader;
1088 }
1089
1090 private:
1091 int value_ = -1;
1092 };
1093 auto parsed = Parse<RefCountedPtr<RefCountedObject>>("{\"value\": 3}");
1094 ASSERT_TRUE(parsed.ok()) << parsed.status();
1095 ASSERT_NE(*parsed, nullptr);
1096 EXPECT_EQ((*parsed)->value(), 3);
1097 parsed = Parse<RefCountedPtr<RefCountedObject>>("null");
1098 EXPECT_EQ(parsed.status().message(),
1099 "errors validating JSON: [field: error:is not an object]")
1100 << parsed.status();
1101 }
1102
TEST(JsonObjectLoader,BareVector)1103 TEST(JsonObjectLoader, BareVector) {
1104 auto parsed = Parse<std::vector<int32_t>>("[1, 2, 3]");
1105 ASSERT_TRUE(parsed.ok()) << parsed.status();
1106 EXPECT_THAT(*parsed, ::testing::ElementsAre(1, 2, 3));
1107 parsed = Parse<std::vector<int32_t>>("null");
1108 EXPECT_EQ(parsed.status().message(),
1109 "errors validating JSON: [field: error:is not an array]")
1110 << parsed.status();
1111 }
1112
TEST(JsonObjectLoader,BareMap)1113 TEST(JsonObjectLoader, BareMap) {
1114 auto parsed =
1115 Parse<std::map<std::string, int32_t>>("{\"a\":1, \"b\":2, \"c\":3}");
1116 ASSERT_TRUE(parsed.ok()) << parsed.status();
1117 EXPECT_THAT(*parsed, ::testing::ElementsAre(::testing::Pair("a", 1),
1118 ::testing::Pair("b", 2),
1119 ::testing::Pair("c", 3)));
1120 parsed = Parse<std::map<std::string, int32_t>>("null");
1121 EXPECT_EQ(parsed.status().message(),
1122 "errors validating JSON: [field: error:is not an object]")
1123 << parsed.status();
1124 }
1125
TEST(JsonObjectLoader,IgnoresUnsupportedFields)1126 TEST(JsonObjectLoader, IgnoresUnsupportedFields) {
1127 struct TestStruct {
1128 int32_t a = 0;
1129
1130 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
1131 static const auto* loader =
1132 JsonObjectLoader<TestStruct>().Field("a", &TestStruct::a).Finish();
1133 return loader;
1134 }
1135 };
1136 auto test_struct = Parse<TestStruct>("{\"a\": 3, \"b\":false}");
1137 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
1138 EXPECT_EQ(test_struct->a, 3);
1139 }
1140
TEST(JsonObjectLoader,IgnoresDisabledFields)1141 TEST(JsonObjectLoader, IgnoresDisabledFields) {
1142 class FakeJsonArgs : public JsonArgs {
1143 public:
1144 FakeJsonArgs() = default;
1145
1146 bool IsEnabled(absl::string_view key) const override {
1147 return key != "disabled";
1148 }
1149 };
1150 struct TestStruct {
1151 int32_t a = 0;
1152 int32_t b = 0;
1153 int32_t c = 0;
1154
1155 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
1156 static const auto* loader =
1157 JsonObjectLoader<TestStruct>()
1158 .Field("a", &TestStruct::a, "disabled")
1159 .OptionalField("b", &TestStruct::b, "disabled")
1160 .OptionalField("c", &TestStruct::c, "enabled")
1161 .Finish();
1162 return loader;
1163 }
1164 };
1165 // Fields "a" and "b" have the wrong types, but we ignore them,
1166 // because they're disabled.
1167 auto test_struct =
1168 Parse<TestStruct>("{\"a\":false, \"b\":false, \"c\":1}", FakeJsonArgs());
1169 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
1170 EXPECT_EQ(test_struct->a, 0);
1171 EXPECT_EQ(test_struct->b, 0);
1172 EXPECT_EQ(test_struct->c, 1);
1173 }
1174
TEST(JsonObjectLoader,PostLoadHook)1175 TEST(JsonObjectLoader, PostLoadHook) {
1176 struct TestStruct {
1177 int32_t a = 0;
1178
1179 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
1180 static const auto* loader = JsonObjectLoader<TestStruct>()
1181 .OptionalField("a", &TestStruct::a)
1182 .Finish();
1183 return loader;
1184 }
1185
1186 void JsonPostLoad(const Json& /*source*/, const JsonArgs& /*args*/,
1187 ValidationErrors* /*errors*/) {
1188 ++a;
1189 }
1190 };
1191 auto test_struct = Parse<TestStruct>("{\"a\": 1}");
1192 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
1193 EXPECT_EQ(test_struct->a, 2);
1194 test_struct = Parse<TestStruct>("{}");
1195 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
1196 EXPECT_EQ(test_struct->a, 1);
1197 }
1198
TEST(JsonObjectLoader,CustomValidationInPostLoadHook)1199 TEST(JsonObjectLoader, CustomValidationInPostLoadHook) {
1200 struct TestStruct {
1201 int32_t a = 0;
1202
1203 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
1204 static const auto* loader =
1205 JsonObjectLoader<TestStruct>().Field("a", &TestStruct::a).Finish();
1206 return loader;
1207 }
1208
1209 void JsonPostLoad(const Json& /*source*/, const JsonArgs& /*args*/,
1210 ValidationErrors* errors) {
1211 ValidationErrors::ScopedField field(errors, ".a");
1212 if (!errors->FieldHasErrors() && a <= 0) {
1213 errors->AddError("must be greater than 0");
1214 }
1215 }
1216 };
1217 // Value greater than 0.
1218 auto test_struct = Parse<TestStruct>("{\"a\": 1}");
1219 ASSERT_TRUE(test_struct.ok()) << test_struct.status();
1220 EXPECT_EQ(test_struct->a, 1);
1221 // Value 0, triggers custom validation.
1222 test_struct = Parse<TestStruct>("{\"a\": 0}");
1223 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
1224 EXPECT_EQ(test_struct.status().message(),
1225 "errors validating JSON: [field:a error:must be greater than 0]")
1226 << test_struct.status();
1227 // Invalid type, generates built-in parsing error, so custom
1228 // validation will not generate a new error.
1229 test_struct = Parse<TestStruct>("{\"a\": []}");
1230 EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
1231 EXPECT_EQ(test_struct.status().message(),
1232 "errors validating JSON: [field:a error:is not a number]")
1233 << test_struct.status();
1234 }
1235
TEST(JsonObjectLoader,LoadFromJsonWithValidationErrors)1236 TEST(JsonObjectLoader, LoadFromJsonWithValidationErrors) {
1237 struct TestStruct {
1238 int32_t a = 0;
1239
1240 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
1241 static const auto* loader =
1242 JsonObjectLoader<TestStruct>().Field("a", &TestStruct::a).Finish();
1243 return loader;
1244 }
1245 };
1246 // Valid.
1247 {
1248 absl::string_view json_str = "{\"a\":1}";
1249 auto json = JsonParse(json_str);
1250 ASSERT_TRUE(json.ok()) << json.status();
1251 ValidationErrors errors;
1252 TestStruct test_struct =
1253 LoadFromJson<TestStruct>(*json, JsonArgs(), &errors);
1254 ASSERT_TRUE(errors.ok()) << errors.status(
1255 absl::StatusCode::kInvalidArgument, "unexpected errors");
1256 EXPECT_EQ(test_struct.a, 1);
1257 }
1258 // Invalid.
1259 {
1260 absl::string_view json_str = "{\"a\":\"foo\"}";
1261 auto json = JsonParse(json_str);
1262 ASSERT_TRUE(json.ok()) << json.status();
1263 ValidationErrors errors;
1264 LoadFromJson<TestStruct>(*json, JsonArgs(), &errors);
1265 absl::Status status = errors.status(absl::StatusCode::kInvalidArgument,
1266 "errors validating JSON");
1267 EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
1268 EXPECT_EQ(status.message(),
1269 "errors validating JSON: [field:a error:failed to parse number]")
1270 << status;
1271 }
1272 }
1273
TEST(JsonObjectLoader,LoadJsonObjectField)1274 TEST(JsonObjectLoader, LoadJsonObjectField) {
1275 absl::string_view json_str = "{\"int\":1}";
1276 auto json = JsonParse(json_str);
1277 ASSERT_TRUE(json.ok()) << json.status();
1278 // Load a valid field.
1279 {
1280 ValidationErrors errors;
1281 auto value = LoadJsonObjectField<int32_t>(json->object(), JsonArgs(), "int",
1282 &errors);
1283 ASSERT_TRUE(value.has_value()) << errors.status(
1284 absl::StatusCode::kInvalidArgument, "unexpected errors");
1285 EXPECT_EQ(*value, 1);
1286 EXPECT_TRUE(errors.ok());
1287 }
1288 // An optional field that is not present.
1289 {
1290 ValidationErrors errors;
1291 auto value = LoadJsonObjectField<int32_t>(json->object(), JsonArgs(),
1292 "not_present", &errors,
1293 /*required=*/false);
1294 EXPECT_FALSE(value.has_value());
1295 EXPECT_TRUE(errors.ok());
1296 }
1297 // A required field that is not present.
1298 {
1299 ValidationErrors errors;
1300 auto value = LoadJsonObjectField<int32_t>(json->object(), JsonArgs(),
1301 "not_present", &errors);
1302 EXPECT_FALSE(value.has_value());
1303 auto status = errors.status(absl::StatusCode::kInvalidArgument,
1304 "errors validating JSON");
1305 EXPECT_THAT(status.code(), absl::StatusCode::kInvalidArgument);
1306 EXPECT_EQ(status.message(),
1307 "errors validating JSON: ["
1308 "field:not_present error:field not present]")
1309 << status;
1310 }
1311 // Value has the wrong type.
1312 {
1313 ValidationErrors errors;
1314 auto value = LoadJsonObjectField<std::string>(json->object(), JsonArgs(),
1315 "int", &errors);
1316 EXPECT_FALSE(value.has_value());
1317 auto status = errors.status(absl::StatusCode::kInvalidArgument,
1318 "errors validating JSON");
1319 EXPECT_THAT(status.code(), absl::StatusCode::kInvalidArgument);
1320 EXPECT_EQ(status.message(),
1321 "errors validating JSON: [field:int error:is not a string]")
1322 << status;
1323 }
1324 }
1325
1326 } // namespace
1327 } // namespace grpc_core
1328
main(int argc,char ** argv)1329 int main(int argc, char** argv) {
1330 ::testing::InitGoogleTest(&argc, argv);
1331 return RUN_ALL_TESTS();
1332 }
1333