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