blob: 720c55d971ce0d4d44e279a1559eb223ced4e785 [file] [log] [blame]
Austin Schuh3e95e5d2019-09-20 00:08:54 -07001#include "aos/json_to_flatbuffer.h"
2
Philipp Schrader790cb542023-07-05 21:06:52 -07003#include "flatbuffers/minireflect.h"
4#include "gtest/gtest.h"
5
Alexander Yeee61cac32023-02-11 19:40:40 -08006#include "aos/flatbuffer_merge.h"
Austin Schuh3e95e5d2019-09-20 00:08:54 -07007#include "aos/json_to_flatbuffer_generated.h"
Austin Schuh373f1762021-06-02 21:07:09 -07008#include "aos/testing/path.h"
Austin Schuh3e95e5d2019-09-20 00:08:54 -07009
Stephan Pleinesf63bde82024-01-13 15:59:33 -080010namespace aos::testing {
Austin Schuh3e95e5d2019-09-20 00:08:54 -070011
12class JsonToFlatbufferTest : public ::testing::Test {
13 public:
James Kuszmaul1ea5e862024-02-09 14:10:25 -080014 enum class TestReflection { kYes, kNo };
15
Austin Schuh3e95e5d2019-09-20 00:08:54 -070016 JsonToFlatbufferTest() {}
17
Brian Silvermanc5105ab2021-02-10 17:55:38 -080018 FlatbufferVector<reflection::Schema> Schema() {
Austin Schuh373f1762021-06-02 21:07:09 -070019 return FileToFlatbuffer<reflection::Schema>(
20 ArtifactPath("aos/json_to_flatbuffer.bfbs"));
Brian Silvermanc5105ab2021-02-10 17:55:38 -080021 }
22
James Kuszmaul1ea5e862024-02-09 14:10:25 -080023 // JsonAndBack tests using both the reflection::Schema* as well as the
24 // minireflect tables for both parsing and outputting JSON. However, there are
25 // currently minor discrepencies between how the JSON output works for the two
26 // modes, so some tests must manually disable testing of the
27 // FlatbufferToJson() overload that takes a reflection::Schema*.
28 bool JsonAndBack(const char *str, TestReflection test_reflection_to_json =
29 TestReflection::kYes) {
30 return JsonAndBack(str, str, test_reflection_to_json);
31 }
Austin Schuh3e95e5d2019-09-20 00:08:54 -070032
James Kuszmaul1ea5e862024-02-09 14:10:25 -080033 bool JsonAndBack(
34 const char *in, const char *out,
35 TestReflection test_reflection_to_json = TestReflection::kYes) {
Brian Silvermanc5105ab2021-02-10 17:55:38 -080036 FlatbufferDetachedBuffer<Configuration> fb_typetable =
James Kuszmaul1ea5e862024-02-09 14:10:25 -080037 JsonToFlatbuffer<Configuration>(in);
Brian Silvermanc5105ab2021-02-10 17:55:38 -080038 FlatbufferDetachedBuffer<Configuration> fb_reflection =
James Kuszmaul1ea5e862024-02-09 14:10:25 -080039 JsonToFlatbuffer(in, FlatbufferType(&Schema().message()));
Austin Schuh3e95e5d2019-09-20 00:08:54 -070040
Brian Silvermanc5105ab2021-02-10 17:55:38 -080041 if (fb_typetable.span().size() == 0) {
42 return false;
43 }
44 if (fb_reflection.span().size() == 0) {
Austin Schuh3e95e5d2019-09-20 00:08:54 -070045 return false;
46 }
47
Brian Silvermanc5105ab2021-02-10 17:55:38 -080048 const ::std::string back_typetable = FlatbufferToJson(fb_typetable);
49 const ::std::string back_reflection = FlatbufferToJson(fb_reflection);
James Kuszmaul1ea5e862024-02-09 14:10:25 -080050 const ::std::string back_reflection_reflection =
51 FlatbufferToJson(&Schema().message(), fb_reflection.span().data());
Austin Schuh3e95e5d2019-09-20 00:08:54 -070052
James Kuszmaul1ea5e862024-02-09 14:10:25 -080053 printf("Back to table via TypeTable and to string via TypeTable: %s\n",
54 back_typetable.c_str());
55 printf("Back to table via reflection and to string via TypeTable: %s\n",
56 back_reflection.c_str());
57 if (test_reflection_to_json == TestReflection::kYes) {
58 printf("Back to table via reflection and to string via reflection: %s\n",
59 back_reflection_reflection.c_str());
60 }
Austin Schuh3e95e5d2019-09-20 00:08:54 -070061
James Kuszmaul1ea5e862024-02-09 14:10:25 -080062 const bool as_expected =
63 back_typetable == out && back_reflection == out &&
64 ((test_reflection_to_json == TestReflection::kNo) ||
65 (back_reflection_reflection == out));
Stephan Pleines89836852023-09-15 20:11:57 -070066 if (!as_expected) {
James Kuszmaul1ea5e862024-02-09 14:10:25 -080067 printf("But expected: %s\n", out);
Stephan Pleines89836852023-09-15 20:11:57 -070068 }
69 return as_expected;
Austin Schuh3e95e5d2019-09-20 00:08:54 -070070 }
71};
72
73// Tests that the various escapes work as expected.
74TEST_F(JsonToFlatbufferTest, ValidEscapes) {
75 EXPECT_TRUE(
76 JsonAndBack("{ \"foo_string\": \"a\\\"b\\/c\\bd\\fc\\nd\\re\\tf\" }",
77 "{ \"foo_string\": \"a\\\"b/c\\bd\\fc\\nd\\re\\tf\" }"));
78}
79
80// Test the easy ones. Test every type, single, no nesting.
81TEST_F(JsonToFlatbufferTest, Basic) {
82 EXPECT_TRUE(JsonAndBack("{ \"foo_bool\": true }"));
83
84 EXPECT_TRUE(JsonAndBack("{ \"foo_byte\": 5 }"));
85 EXPECT_TRUE(JsonAndBack("{ \"foo_ubyte\": 5 }"));
86
87 EXPECT_TRUE(JsonAndBack("{ \"foo_short\": 5 }"));
88 EXPECT_TRUE(JsonAndBack("{ \"foo_ushort\": 5 }"));
89
90 EXPECT_TRUE(JsonAndBack("{ \"foo_int\": 5 }"));
91 EXPECT_TRUE(JsonAndBack("{ \"foo_uint\": 5 }"));
92
93 EXPECT_TRUE(JsonAndBack("{ \"foo_long\": 5 }"));
94 EXPECT_TRUE(JsonAndBack("{ \"foo_ulong\": 5 }"));
95
James Kuszmaul98c798d2024-04-24 15:58:09 -070096 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5 }"));
97 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 50 }"));
98 // Test that we can distinguish between floats that vary by a single bit.
99 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 1.1 }"));
100 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 1.0999999 }"));
101 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5 }"));
102 // Check that we handle/distinguish between doubles that vary by a single bit.
103 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 1.561154546713 }"));
104 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 1.56115454671299 }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700105
Alex Perrycb7da4b2019-08-28 19:35:56 -0700106 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"None\" }"));
107 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"UType\" }"));
108
109 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"None\" }"));
110 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"UType\" }"));
111
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700112 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"baz\" }"));
Brian Silverman5c710412021-02-09 19:09:32 -0800113
114 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Zero\" }"));
115 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Big\" }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700116}
117
James Kuszmaul768c4682023-10-12 21:07:16 -0700118TEST_F(JsonToFlatbufferTest, Structs) {
119 EXPECT_TRUE(
120 JsonAndBack("{ \"foo_struct\": { \"foo_byte\": 1, \"nested_struct\": { "
121 "\"foo_byte\": 2 } } }"));
122 EXPECT_TRUE(JsonAndBack(
123 "{ \"foo_struct_scalars\": { \"foo_float\": 1.234, \"foo_double\": "
James Kuszmaul98c798d2024-04-24 15:58:09 -0700124 "4.567, \"foo_int32\": -971, \"foo_uint32\": 4294967294, "
125 "\"foo_int64\": -1030, \"foo_uint64\": 18446744073709551614 } }",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800126 TestReflection::kNo));
James Kuszmaul768c4682023-10-12 21:07:16 -0700127 // Confirm that we parse integers into floating point fields correctly.
128 EXPECT_TRUE(JsonAndBack(
129 "{ \"foo_struct_scalars\": { \"foo_float\": 1, \"foo_double\": "
130 "2, \"foo_int32\": 3, \"foo_uint32\": 4, \"foo_int64\": "
131 "5, \"foo_uint64\": 6 } }",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800132 TestReflection::kNo));
James Kuszmaul768c4682023-10-12 21:07:16 -0700133 EXPECT_TRUE(JsonAndBack(
134 "{ \"vector_foo_struct_scalars\": [ { \"foo_float\": 1.234, "
James Kuszmaul98c798d2024-04-24 15:58:09 -0700135 "\"foo_double\": 4.567, \"foo_int32\": -971, "
136 "\"foo_uint32\": 4294967294, \"foo_int64\": -1030, \"foo_uint64\": "
137 "18446744073709551614 }, { \"foo_float\": 2, \"foo_double\": "
138 "4.1, \"foo_int32\": 10, \"foo_uint32\": 13, "
139 "\"foo_int64\": 15, \"foo_uint64\": 18 } ] }",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800140 TestReflection::kNo));
James Kuszmaul768c4682023-10-12 21:07:16 -0700141 EXPECT_TRUE(
142 JsonAndBack("{ \"foo_struct_enum\": { \"foo_enum\": \"UByte\" } }"));
143 EXPECT_TRUE(
144 JsonAndBack("{ \"vector_foo_struct\": [ { \"foo_byte\": 1, "
145 "\"nested_struct\": { \"foo_byte\": 2 } } ] }"));
146 EXPECT_TRUE(JsonAndBack(
147 "{ \"vector_foo_struct\": [ { \"foo_byte\": 1, \"nested_struct\": { "
148 "\"foo_byte\": 2 } }, { \"foo_byte\": 3, \"nested_struct\": { "
149 "\"foo_byte\": 4 } }, { \"foo_byte\": 5, \"nested_struct\": { "
150 "\"foo_byte\": 6 } } ] }"));
151}
152
153// Confirm that we correctly die when input JSON is missing fields inside of a
154// struct.
155TEST_F(JsonToFlatbufferTest, StructMissingField) {
156 ::testing::internal::CaptureStderr();
157 EXPECT_FALSE(
158 JsonAndBack("{ \"foo_struct\": { \"nested_struct\": { "
159 "\"foo_byte\": 2 } } }"));
160 EXPECT_FALSE(JsonAndBack(
161 "{ \"foo_struct\": { \"foo_byte\": 1, \"nested_struct\": { } } }"));
162 EXPECT_FALSE(JsonAndBack("{ \"foo_struct\": { \"foo_byte\": 1 } }"));
163 std::string output = ::testing::internal::GetCapturedStderr();
164 EXPECT_EQ(
165 R"output(All fields must be specified for struct types (field foo_byte missing).
166All fields must be specified for struct types (field foo_byte missing).
167All fields must be specified for struct types (field foo_byte missing).
168All fields must be specified for struct types (field foo_byte missing).
169All fields must be specified for struct types (field nested_struct missing).
170All fields must be specified for struct types (field nested_struct missing).
171)output",
172 output);
173}
174
Austin Schuh9fa0b8e2021-03-21 19:21:50 -0700175// Tests that Inf is handled correctly
176TEST_F(JsonToFlatbufferTest, Inf) {
177 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": inf }"));
178 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": -inf }"));
179 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": inf }"));
180 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": -inf }"));
181}
182
Austin Schuhbba0c3c2019-11-29 22:00:34 -0800183// Tests that NaN is handled correctly
184TEST_F(JsonToFlatbufferTest, Nan) {
185 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": nan }"));
186 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": -nan }"));
Austin Schuh9fa0b8e2021-03-21 19:21:50 -0700187 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": nan }"));
188 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": -nan }"));
Austin Schuhbba0c3c2019-11-29 22:00:34 -0800189}
190
Pallavi Madhukare2eb2812022-07-19 09:56:09 -0700191// Tests that unicode is handled correctly
192TEST_F(JsonToFlatbufferTest, Unicode) {
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800193 // The reflection-based FlatbufferToJson outputs actual unicode rather than
194 // escaped code-points.
195 EXPECT_TRUE(
196 JsonAndBack("{ \"foo_string\": \"\\uF672\" }", TestReflection::kNo));
197 EXPECT_TRUE(
198 JsonAndBack("{ \"foo_string\": \"\\uEFEF\" }", TestReflection::kNo));
199 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"helloworld\\uD83E\\uDE94\" }",
200 TestReflection::kNo));
201 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"\\uD83C\\uDF32\" }",
202 TestReflection::kNo));
203 EXPECT_FALSE(
204 JsonAndBack("{ \"foo_string\": \"\\uP890\" }", TestReflection::kNo));
205 EXPECT_FALSE(
206 JsonAndBack("{ \"foo_string\": \"\\u!FA8\" }", TestReflection::kNo));
207 EXPECT_FALSE(
208 JsonAndBack("{ \"foo_string\": \"\\uF89\" }", TestReflection::kNo));
209 EXPECT_FALSE(
210 JsonAndBack("{ \"foo_string\": \"\\uD83C\" }", TestReflection::kNo));
Pallavi Madhukare2eb2812022-07-19 09:56:09 -0700211}
212
Austin Schuh84314af2019-10-03 09:11:34 -0700213// Tests that we can handle decimal points.
214TEST_F(JsonToFlatbufferTest, DecimalPoint) {
James Kuszmaul98c798d2024-04-24 15:58:09 -0700215 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.099999 }"));
216 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5.099999999999 }"));
Austin Schuh84314af2019-10-03 09:11:34 -0700217}
218
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700219// Test what happens if you pass a field name that we don't know.
220TEST_F(JsonToFlatbufferTest, InvalidFieldName) {
221 EXPECT_FALSE(JsonAndBack("{ \"foo\": 5 }"));
222}
223
Alex Perrycb7da4b2019-08-28 19:35:56 -0700224// Tests that an invalid enum type is handled correctly.
225TEST_F(JsonToFlatbufferTest, InvalidEnumName) {
226 EXPECT_FALSE(JsonAndBack("{ \"foo_enum\": \"5ype\" }"));
227
228 EXPECT_FALSE(JsonAndBack("{ \"foo_enum_default\": \"7ype\" }"));
Brian Silverman5c710412021-02-09 19:09:32 -0800229
230 EXPECT_FALSE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Nope\" }"));
231
232 EXPECT_FALSE(
233 JsonAndBack("{ \"foo_enum_nonconsecutive_default\": \"Nope\" }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700234}
235
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700236// Test that adding a duplicate field results in an error.
237TEST_F(JsonToFlatbufferTest, DuplicateField) {
238 EXPECT_FALSE(
239 JsonAndBack("{ \"foo_int\": 5, \"foo_int\": 7 }", "{ \"foo_int\": 7 }"));
240}
241
242// Test that various syntax errors are caught correctly
243TEST_F(JsonToFlatbufferTest, InvalidSyntax) {
244 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5"));
245 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 "));
246 EXPECT_FALSE(JsonAndBack("{ \"foo_string\": \""));
247 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 } }"));
248
249 EXPECT_FALSE(JsonAndBack("{ foo_int: 5 }"));
250
251 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5, }", "{ \"foo_int\": 5 }"));
252
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700253 EXPECT_FALSE(
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700254 JsonAndBack("{ \"apps\":\n[\n{\n\"name\": \"woot\"\n},\n{\n\"name\": "
255 "\"wow\"\n} ,\n]\n}"));
256
257 EXPECT_FALSE(JsonAndBack(
258 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] , }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700259
260 EXPECT_FALSE(
261 JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] , }"));
262
263 EXPECT_FALSE(
264 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } , }"));
265}
266
267// Test arrays of simple types.
268TEST_F(JsonToFlatbufferTest, Array) {
269 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700270 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700271 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700272 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700273
274 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700275 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700276 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700277 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700278
279 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700280 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700281 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700282 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700283
284 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700285 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700286 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700287 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700288
James Kuszmaul98c798d2024-04-24 15:58:09 -0700289 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700290 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ ] }"));
James Kuszmaul98c798d2024-04-24 15:58:09 -0700291 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700292 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700293
James Kuszmaul98c798d2024-04-24 15:58:09 -0700294 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }",
295 "{ \"vector_foo_float\": [ 9, 7, 1 ] }"));
296 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
297 "{ \"vector_foo_double\": [ 9, 7, 1 ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700298
299 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700300 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ ] }"));
Ravago Jonescf453ab2020-05-06 21:14:53 -0700301 EXPECT_TRUE(JsonAndBack(
302 "{ \"vector_foo_enum\": [ \"None\", \"UType\", \"Bool\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700303 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_enum\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700304}
305
306// Test nested messages, and arrays of nested messages.
James Kuszmaul768c4682023-10-12 21:07:16 -0700307TEST_F(JsonToFlatbufferTest, NestedTable) {
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700308 EXPECT_TRUE(
309 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } }"));
310
Alex Perrycb7da4b2019-08-28 19:35:56 -0700311 EXPECT_TRUE(JsonAndBack("{ \"single_application\": { } }"));
312
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700313 EXPECT_TRUE(JsonAndBack(
314 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700315
Ravago Jonescf453ab2020-05-06 21:14:53 -0700316 EXPECT_TRUE(JsonAndBack("{ \"apps\": [ { }, { } ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700317}
318
James Kuszmaulbb60dfd2023-01-05 17:13:11 -0800319// Test mixing up whether a field is an object or a vector.
320TEST_F(JsonToFlatbufferTest, IncorrectVectorOfTables) {
321 EXPECT_FALSE(
322 JsonAndBack("{ \"single_application\": [ {\"name\": \"woot\"} ] }"));
323 EXPECT_FALSE(JsonAndBack("{ \"apps\": { \"name\": \"woot\" } }"));
324}
325
Austin Schuh84314af2019-10-03 09:11:34 -0700326// Test that we can parse an empty message.
327TEST_F(JsonToFlatbufferTest, EmptyMessage) {
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700328 // Empty message works.
Austin Schuh84314af2019-10-03 09:11:34 -0700329 EXPECT_TRUE(JsonAndBack("{ }"));
330}
331
Stephan Pleines89836852023-09-15 20:11:57 -0700332// Tests that C style comments get stripped.
333TEST_F(JsonToFlatbufferTest, CStyleComments) {
334 EXPECT_TRUE(JsonAndBack(R"({
335 /* foo */
336 "vector_foo_double": [ 9, 7, 1 ] /* foo */
337} /* foo */)",
James Kuszmaul98c798d2024-04-24 15:58:09 -0700338 "{ \"vector_foo_double\": [ 9, 7, 1 ] }"));
Stephan Pleines89836852023-09-15 20:11:57 -0700339}
340
341// Tests that C++ style comments get stripped.
342TEST_F(JsonToFlatbufferTest, CppStyleComments) {
343 EXPECT_TRUE(JsonAndBack(R"({
344 // foo
345 "vector_foo_double": [ 9, 7, 1 ] // foo
346} // foo)",
James Kuszmaul98c798d2024-04-24 15:58:09 -0700347 "{ \"vector_foo_double\": [ 9, 7, 1 ] }"));
Brian J Griglak2e16e7b2024-03-01 12:10:46 -0700348
349 // Test empty comment on its own line doesn't remove the next line.
350 EXPECT_TRUE(JsonAndBack(R"({
351 //
352 "vector_foo_double": [ 9, 7, 1 ], // foo
353 "vector_foo_float": [ 3, 1, 4 ]
354} // foo)",
James Kuszmaul98c798d2024-04-24 15:58:09 -0700355 "{ \"vector_foo_float\": [ 3, 1, 4 ], "
356 "\"vector_foo_double\": [ 9, 7, 1 ] }",
Brian J Griglak2e16e7b2024-03-01 12:10:46 -0700357 TestReflection::kNo));
358
359 // Test empty comment at end of line doesn't remove the next line.
360 EXPECT_TRUE(JsonAndBack(R"({
361 // foo
362 "vector_foo_double": [ 2, 7, 1 ], //
363 "vector_foo_float": [ 3, 1, 4 ]
364} // foo)",
James Kuszmaul98c798d2024-04-24 15:58:09 -0700365 "{ \"vector_foo_float\": [ 3, 1, 4 ], "
366 "\"vector_foo_double\": [ 2, 7, 1 ] }",
Brian J Griglak2e16e7b2024-03-01 12:10:46 -0700367 TestReflection::kNo));
368
369 // Test empty comment at end of document doesn't cause error.
370 EXPECT_TRUE(JsonAndBack(R"({
371 // foo
372 "vector_foo_double": [ 5, 6, 7 ], // foo
373 "vector_foo_float": [ 7, 8, 9 ]
374} //)",
James Kuszmaul98c798d2024-04-24 15:58:09 -0700375 "{ \"vector_foo_float\": [ 7, 8, 9 ], "
376 "\"vector_foo_double\": [ 5, 6, 7 ] }",
Brian J Griglak2e16e7b2024-03-01 12:10:46 -0700377 TestReflection::kNo));
Stephan Pleines89836852023-09-15 20:11:57 -0700378}
379
380// Tests that mixed style comments get stripped.
381TEST_F(JsonToFlatbufferTest, MixedStyleComments) {
382 // Weird comments do not throw us off.
383 EXPECT_TRUE(JsonAndBack(R"({
384 // foo /* foo */
385 "vector_foo_double": [ 9, 7, 1 ] /* // foo */
386}
387// foo
388/* foo */)",
James Kuszmaul98c798d2024-04-24 15:58:09 -0700389 "{ \"vector_foo_double\": [ 9, 7, 1 ] }",
390 TestReflection::kYes));
Austin Schuh81da4b22019-10-06 14:03:24 -0700391}
392
Austin Schuh9e2532d2019-10-06 14:01:15 -0700393// Tests that multiple arrays get properly handled.
394TEST_F(JsonToFlatbufferTest, MultipleArrays) {
395 EXPECT_TRUE(
396 JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ], \"vector_foo_double\": "
397 "[ 9, 7, 1 ] }",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800398 TestReflection::kNo));
Austin Schuh9e2532d2019-10-06 14:01:15 -0700399}
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700400
Alex Perrycb7da4b2019-08-28 19:35:56 -0700401// Tests that multiple arrays get properly handled.
402TEST_F(JsonToFlatbufferTest, NestedArrays) {
403 EXPECT_TRUE(
Ravago Jonescf453ab2020-05-06 21:14:53 -0700404 JsonAndBack("{ \"vov\": { \"v\": [ { \"str\": [ \"a\", \"b\" ] }, { "
405 "\"str\": [ \"c\", \"d\" ] } ] } }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700406}
407
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700408// TODO(austin): Missmatched values.
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700409//
410// TODO(austin): unions?
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700411
Austin Schuhd3936202020-04-07 20:11:07 -0700412TEST_F(JsonToFlatbufferTest, TrimmedVector) {
413 std::string json_short = "{ \"vector_foo_int\": [ 0";
414 for (int i = 1; i < 100; ++i) {
415 json_short += ", ";
416 json_short += std::to_string(i);
417 }
418 std::string json_long = json_short;
419 json_short += " ] }";
420 json_long += ", 101 ] }";
421
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800422 const FlatbufferDetachedBuffer<Configuration> fb_short_typetable(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800423 JsonToFlatbuffer<Configuration>(json_short));
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800424 ASSERT_GT(fb_short_typetable.span().size(), 0);
425 const FlatbufferDetachedBuffer<Configuration> fb_long_typetable(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800426 JsonToFlatbuffer<Configuration>(json_long));
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800427 ASSERT_GT(fb_long_typetable.span().size(), 0);
428 const FlatbufferDetachedBuffer<Configuration> fb_short_reflection(
429 JsonToFlatbuffer(json_short, FlatbufferType(&Schema().message())));
430 ASSERT_GT(fb_short_reflection.span().size(), 0);
431 const FlatbufferDetachedBuffer<Configuration> fb_long_reflection(
432 JsonToFlatbuffer(json_long, FlatbufferType(&Schema().message())));
433 ASSERT_GT(fb_long_reflection.span().size(), 0);
Austin Schuhd3936202020-04-07 20:11:07 -0700434
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800435 const std::string back_json_short_typetable = FlatbufferToJson<Configuration>(
436 fb_short_typetable, {.multi_line = false, .max_vector_size = 100});
437 const std::string back_json_long_typetable = FlatbufferToJson<Configuration>(
438 fb_long_typetable, {.multi_line = false, .max_vector_size = 100});
439 const std::string back_json_short_reflection =
440 FlatbufferToJson<Configuration>(
441 fb_short_reflection, {.multi_line = false, .max_vector_size = 100});
442 const std::string back_json_long_reflection = FlatbufferToJson<Configuration>(
443 fb_long_reflection, {.multi_line = false, .max_vector_size = 100});
Austin Schuhd3936202020-04-07 20:11:07 -0700444
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800445 EXPECT_EQ(json_short, back_json_short_typetable);
446 EXPECT_EQ(json_short, back_json_short_reflection);
Austin Schuh041fe9f2021-10-16 23:01:15 -0700447 EXPECT_EQ("{ \"vector_foo_int\": [ \"... 101 elements ...\" ] }",
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800448 back_json_long_typetable);
Austin Schuh041fe9f2021-10-16 23:01:15 -0700449 EXPECT_EQ("{ \"vector_foo_int\": [ \"... 101 elements ...\" ] }",
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800450 back_json_long_reflection);
Austin Schuhd3936202020-04-07 20:11:07 -0700451}
452
Austin Schuh7f99e472020-06-17 20:38:17 -0700453// Tests that a nullptr buffer prints nullptr.
454TEST_F(JsonToFlatbufferTest, NullptrData) {
455 EXPECT_EQ("null", TableFlatbufferToJson((const flatbuffers::Table *)(nullptr),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700456 ConfigurationTypeTable()));
Austin Schuh7f99e472020-06-17 20:38:17 -0700457}
458
Alexander Yeee61cac32023-02-11 19:40:40 -0800459TEST_F(JsonToFlatbufferTest, SpacedData) {
460 EXPECT_TRUE(CompareFlatBuffer(
461 FlatbufferDetachedBuffer<VectorOfStrings>(
462 JsonToFlatbuffer<VectorOfStrings>(R"json({
463 "str": [
464 "f o o",
465 "b a r",
466 "foo bar",
467 "bar foo"
468 ]
469})json")),
470 JsonFileToFlatbuffer<VectorOfStrings>(
471 ArtifactPath("aos/json_to_flatbuffer_test_spaces.json"))));
472}
473
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800474} // namespace aos::testing