blob: 7c69acd15c27860904cb6e0349eb13ef023d4316 [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 Kuszmaul1ea5e862024-02-09 14:10:25 -080096 // TODO(james): Make FlatbufferToJson() always print out integer
97 // floating-point numbers identically.
98 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.0 }", TestReflection::kNo));
99 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5.0 }", TestReflection::kNo));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700100
Alex Perrycb7da4b2019-08-28 19:35:56 -0700101 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"None\" }"));
102 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"UType\" }"));
103
104 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"None\" }"));
105 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"UType\" }"));
106
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700107 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"baz\" }"));
Brian Silverman5c710412021-02-09 19:09:32 -0800108
109 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Zero\" }"));
110 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Big\" }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700111}
112
James Kuszmaul768c4682023-10-12 21:07:16 -0700113TEST_F(JsonToFlatbufferTest, Structs) {
114 EXPECT_TRUE(
115 JsonAndBack("{ \"foo_struct\": { \"foo_byte\": 1, \"nested_struct\": { "
116 "\"foo_byte\": 2 } } }"));
117 EXPECT_TRUE(JsonAndBack(
118 "{ \"foo_struct_scalars\": { \"foo_float\": 1.234, \"foo_double\": "
119 "4.567, \"foo_int32\": -971, \"foo_uint32\": 4294967294, \"foo_int64\": "
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800120 "-1030, \"foo_uint64\": 18446744073709551614 } }",
121 TestReflection::kNo));
James Kuszmaul768c4682023-10-12 21:07:16 -0700122 // Confirm that we parse integers into floating point fields correctly.
123 EXPECT_TRUE(JsonAndBack(
124 "{ \"foo_struct_scalars\": { \"foo_float\": 1, \"foo_double\": "
125 "2, \"foo_int32\": 3, \"foo_uint32\": 4, \"foo_int64\": "
126 "5, \"foo_uint64\": 6 } }",
127 "{ \"foo_struct_scalars\": { \"foo_float\": 1.0, \"foo_double\": "
128 "2.0, \"foo_int32\": 3, \"foo_uint32\": 4, \"foo_int64\": "
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800129 "5, \"foo_uint64\": 6 } }",
130 TestReflection::kNo));
James Kuszmaul768c4682023-10-12 21:07:16 -0700131 EXPECT_TRUE(JsonAndBack(
132 "{ \"vector_foo_struct_scalars\": [ { \"foo_float\": 1.234, "
133 "\"foo_double\": 4.567, \"foo_int32\": -971, \"foo_uint32\": 4294967294, "
134 "\"foo_int64\": -1030, \"foo_uint64\": 18446744073709551614 }, { "
135 "\"foo_float\": 2.0, \"foo_double\": 4.1, \"foo_int32\": 10, "
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800136 "\"foo_uint32\": 13, \"foo_int64\": 15, \"foo_uint64\": 18 } ] }",
137 TestReflection::kNo));
James Kuszmaul768c4682023-10-12 21:07:16 -0700138 EXPECT_TRUE(
139 JsonAndBack("{ \"foo_struct_enum\": { \"foo_enum\": \"UByte\" } }"));
140 EXPECT_TRUE(
141 JsonAndBack("{ \"vector_foo_struct\": [ { \"foo_byte\": 1, "
142 "\"nested_struct\": { \"foo_byte\": 2 } } ] }"));
143 EXPECT_TRUE(JsonAndBack(
144 "{ \"vector_foo_struct\": [ { \"foo_byte\": 1, \"nested_struct\": { "
145 "\"foo_byte\": 2 } }, { \"foo_byte\": 3, \"nested_struct\": { "
146 "\"foo_byte\": 4 } }, { \"foo_byte\": 5, \"nested_struct\": { "
147 "\"foo_byte\": 6 } } ] }"));
148}
149
150// Confirm that we correctly die when input JSON is missing fields inside of a
151// struct.
152TEST_F(JsonToFlatbufferTest, StructMissingField) {
153 ::testing::internal::CaptureStderr();
154 EXPECT_FALSE(
155 JsonAndBack("{ \"foo_struct\": { \"nested_struct\": { "
156 "\"foo_byte\": 2 } } }"));
157 EXPECT_FALSE(JsonAndBack(
158 "{ \"foo_struct\": { \"foo_byte\": 1, \"nested_struct\": { } } }"));
159 EXPECT_FALSE(JsonAndBack("{ \"foo_struct\": { \"foo_byte\": 1 } }"));
160 std::string output = ::testing::internal::GetCapturedStderr();
161 EXPECT_EQ(
162 R"output(All fields must be specified for struct types (field foo_byte missing).
163All fields must be specified for struct types (field foo_byte missing).
164All fields must be specified for struct types (field foo_byte missing).
165All fields must be specified for struct types (field foo_byte missing).
166All fields must be specified for struct types (field nested_struct missing).
167All fields must be specified for struct types (field nested_struct missing).
168)output",
169 output);
170}
171
Austin Schuh9fa0b8e2021-03-21 19:21:50 -0700172// Tests that Inf is handled correctly
173TEST_F(JsonToFlatbufferTest, Inf) {
174 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": inf }"));
175 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": -inf }"));
176 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": inf }"));
177 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": -inf }"));
178}
179
Austin Schuhbba0c3c2019-11-29 22:00:34 -0800180// Tests that NaN is handled correctly
181TEST_F(JsonToFlatbufferTest, Nan) {
182 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": nan }"));
183 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": -nan }"));
Austin Schuh9fa0b8e2021-03-21 19:21:50 -0700184 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": nan }"));
185 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": -nan }"));
Austin Schuhbba0c3c2019-11-29 22:00:34 -0800186}
187
Pallavi Madhukare2eb2812022-07-19 09:56:09 -0700188// Tests that unicode is handled correctly
189TEST_F(JsonToFlatbufferTest, Unicode) {
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800190 // The reflection-based FlatbufferToJson outputs actual unicode rather than
191 // escaped code-points.
192 EXPECT_TRUE(
193 JsonAndBack("{ \"foo_string\": \"\\uF672\" }", TestReflection::kNo));
194 EXPECT_TRUE(
195 JsonAndBack("{ \"foo_string\": \"\\uEFEF\" }", TestReflection::kNo));
196 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"helloworld\\uD83E\\uDE94\" }",
197 TestReflection::kNo));
198 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"\\uD83C\\uDF32\" }",
199 TestReflection::kNo));
200 EXPECT_FALSE(
201 JsonAndBack("{ \"foo_string\": \"\\uP890\" }", TestReflection::kNo));
202 EXPECT_FALSE(
203 JsonAndBack("{ \"foo_string\": \"\\u!FA8\" }", TestReflection::kNo));
204 EXPECT_FALSE(
205 JsonAndBack("{ \"foo_string\": \"\\uF89\" }", TestReflection::kNo));
206 EXPECT_FALSE(
207 JsonAndBack("{ \"foo_string\": \"\\uD83C\" }", TestReflection::kNo));
Pallavi Madhukare2eb2812022-07-19 09:56:09 -0700208}
209
Austin Schuh84314af2019-10-03 09:11:34 -0700210// Tests that we can handle decimal points.
211TEST_F(JsonToFlatbufferTest, DecimalPoint) {
212 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.1 }"));
213 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5.1 }"));
214}
215
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700216// Test what happens if you pass a field name that we don't know.
217TEST_F(JsonToFlatbufferTest, InvalidFieldName) {
218 EXPECT_FALSE(JsonAndBack("{ \"foo\": 5 }"));
219}
220
Alex Perrycb7da4b2019-08-28 19:35:56 -0700221// Tests that an invalid enum type is handled correctly.
222TEST_F(JsonToFlatbufferTest, InvalidEnumName) {
223 EXPECT_FALSE(JsonAndBack("{ \"foo_enum\": \"5ype\" }"));
224
225 EXPECT_FALSE(JsonAndBack("{ \"foo_enum_default\": \"7ype\" }"));
Brian Silverman5c710412021-02-09 19:09:32 -0800226
227 EXPECT_FALSE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Nope\" }"));
228
229 EXPECT_FALSE(
230 JsonAndBack("{ \"foo_enum_nonconsecutive_default\": \"Nope\" }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700231}
232
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700233// Test that adding a duplicate field results in an error.
234TEST_F(JsonToFlatbufferTest, DuplicateField) {
235 EXPECT_FALSE(
236 JsonAndBack("{ \"foo_int\": 5, \"foo_int\": 7 }", "{ \"foo_int\": 7 }"));
237}
238
239// Test that various syntax errors are caught correctly
240TEST_F(JsonToFlatbufferTest, InvalidSyntax) {
241 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5"));
242 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 "));
243 EXPECT_FALSE(JsonAndBack("{ \"foo_string\": \""));
244 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 } }"));
245
246 EXPECT_FALSE(JsonAndBack("{ foo_int: 5 }"));
247
248 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5, }", "{ \"foo_int\": 5 }"));
249
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700250 EXPECT_FALSE(
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700251 JsonAndBack("{ \"apps\":\n[\n{\n\"name\": \"woot\"\n},\n{\n\"name\": "
252 "\"wow\"\n} ,\n]\n}"));
253
254 EXPECT_FALSE(JsonAndBack(
255 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] , }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700256
257 EXPECT_FALSE(
258 JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] , }"));
259
260 EXPECT_FALSE(
261 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } , }"));
262}
263
264// Test arrays of simple types.
265TEST_F(JsonToFlatbufferTest, Array) {
266 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700267 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700268 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700269 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700270
271 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700272 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700273 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700274 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700275
276 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700277 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700278 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700279 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700280
281 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700282 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700283 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700284 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700285
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800286 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }",
287 TestReflection::kNo));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700288 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ ] }"));
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800289 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
290 TestReflection::kNo));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700291 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700292
293 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ] }",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800294 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }",
295 TestReflection::kNo));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700296 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9, 7, 1 ] }",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800297 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
298 TestReflection::kNo));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700299
300 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700301 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ ] }"));
Ravago Jonescf453ab2020-05-06 21:14:53 -0700302 EXPECT_TRUE(JsonAndBack(
303 "{ \"vector_foo_enum\": [ \"None\", \"UType\", \"Bool\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700304 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_enum\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700305}
306
307// Test nested messages, and arrays of nested messages.
James Kuszmaul768c4682023-10-12 21:07:16 -0700308TEST_F(JsonToFlatbufferTest, NestedTable) {
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700309 EXPECT_TRUE(
310 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } }"));
311
Alex Perrycb7da4b2019-08-28 19:35:56 -0700312 EXPECT_TRUE(JsonAndBack("{ \"single_application\": { } }"));
313
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700314 EXPECT_TRUE(JsonAndBack(
315 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700316
Ravago Jonescf453ab2020-05-06 21:14:53 -0700317 EXPECT_TRUE(JsonAndBack("{ \"apps\": [ { }, { } ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700318}
319
James Kuszmaulbb60dfd2023-01-05 17:13:11 -0800320// Test mixing up whether a field is an object or a vector.
321TEST_F(JsonToFlatbufferTest, IncorrectVectorOfTables) {
322 EXPECT_FALSE(
323 JsonAndBack("{ \"single_application\": [ {\"name\": \"woot\"} ] }"));
324 EXPECT_FALSE(JsonAndBack("{ \"apps\": { \"name\": \"woot\" } }"));
325}
326
Austin Schuh84314af2019-10-03 09:11:34 -0700327// Test that we can parse an empty message.
328TEST_F(JsonToFlatbufferTest, EmptyMessage) {
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700329 // Empty message works.
Austin Schuh84314af2019-10-03 09:11:34 -0700330 EXPECT_TRUE(JsonAndBack("{ }"));
331}
332
Stephan Pleines89836852023-09-15 20:11:57 -0700333// Tests that C style comments get stripped.
334TEST_F(JsonToFlatbufferTest, CStyleComments) {
335 EXPECT_TRUE(JsonAndBack(R"({
336 /* foo */
337 "vector_foo_double": [ 9, 7, 1 ] /* foo */
338} /* foo */)",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800339 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
340 TestReflection::kNo));
Stephan Pleines89836852023-09-15 20:11:57 -0700341}
342
343// Tests that C++ style comments get stripped.
344TEST_F(JsonToFlatbufferTest, CppStyleComments) {
345 EXPECT_TRUE(JsonAndBack(R"({
346 // foo
347 "vector_foo_double": [ 9, 7, 1 ] // foo
348} // foo)",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800349 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
350 TestReflection::kNo));
Brian J Griglak2e16e7b2024-03-01 12:10:46 -0700351
352 // Test empty comment on its own line doesn't remove the next line.
353 EXPECT_TRUE(JsonAndBack(R"({
354 //
355 "vector_foo_double": [ 9, 7, 1 ], // foo
356 "vector_foo_float": [ 3, 1, 4 ]
357} // foo)",
358 "{ \"vector_foo_float\": [ 3.0, 1.0, 4.0 ], "
359 "\"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
360 TestReflection::kNo));
361
362 // Test empty comment at end of line doesn't remove the next line.
363 EXPECT_TRUE(JsonAndBack(R"({
364 // foo
365 "vector_foo_double": [ 2, 7, 1 ], //
366 "vector_foo_float": [ 3, 1, 4 ]
367} // foo)",
368 "{ \"vector_foo_float\": [ 3.0, 1.0, 4.0 ], "
369 "\"vector_foo_double\": [ 2.0, 7.0, 1.0 ] }",
370 TestReflection::kNo));
371
372 // Test empty comment at end of document doesn't cause error.
373 EXPECT_TRUE(JsonAndBack(R"({
374 // foo
375 "vector_foo_double": [ 5, 6, 7 ], // foo
376 "vector_foo_float": [ 7, 8, 9 ]
377} //)",
378 "{ \"vector_foo_float\": [ 7.0, 8.0, 9.0 ], "
379 "\"vector_foo_double\": [ 5.0, 6.0, 7.0 ] }",
380 TestReflection::kNo));
Stephan Pleines89836852023-09-15 20:11:57 -0700381}
382
383// Tests that mixed style comments get stripped.
384TEST_F(JsonToFlatbufferTest, MixedStyleComments) {
385 // Weird comments do not throw us off.
386 EXPECT_TRUE(JsonAndBack(R"({
387 // foo /* foo */
388 "vector_foo_double": [ 9, 7, 1 ] /* // foo */
389}
390// foo
391/* foo */)",
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800392 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
393 TestReflection::kNo));
Austin Schuh81da4b22019-10-06 14:03:24 -0700394}
395
Austin Schuh9e2532d2019-10-06 14:01:15 -0700396// Tests that multiple arrays get properly handled.
397TEST_F(JsonToFlatbufferTest, MultipleArrays) {
398 EXPECT_TRUE(
399 JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ], \"vector_foo_double\": "
400 "[ 9, 7, 1 ] }",
401 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ], "
James Kuszmaul1ea5e862024-02-09 14:10:25 -0800402 "\"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }",
403 TestReflection::kNo));
Austin Schuh9e2532d2019-10-06 14:01:15 -0700404}
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700405
Alex Perrycb7da4b2019-08-28 19:35:56 -0700406// Tests that multiple arrays get properly handled.
407TEST_F(JsonToFlatbufferTest, NestedArrays) {
408 EXPECT_TRUE(
Ravago Jonescf453ab2020-05-06 21:14:53 -0700409 JsonAndBack("{ \"vov\": { \"v\": [ { \"str\": [ \"a\", \"b\" ] }, { "
410 "\"str\": [ \"c\", \"d\" ] } ] } }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700411}
412
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700413// TODO(austin): Missmatched values.
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700414//
415// TODO(austin): unions?
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700416
Austin Schuhd3936202020-04-07 20:11:07 -0700417TEST_F(JsonToFlatbufferTest, TrimmedVector) {
418 std::string json_short = "{ \"vector_foo_int\": [ 0";
419 for (int i = 1; i < 100; ++i) {
420 json_short += ", ";
421 json_short += std::to_string(i);
422 }
423 std::string json_long = json_short;
424 json_short += " ] }";
425 json_long += ", 101 ] }";
426
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800427 const FlatbufferDetachedBuffer<Configuration> fb_short_typetable(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800428 JsonToFlatbuffer<Configuration>(json_short));
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800429 ASSERT_GT(fb_short_typetable.span().size(), 0);
430 const FlatbufferDetachedBuffer<Configuration> fb_long_typetable(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800431 JsonToFlatbuffer<Configuration>(json_long));
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800432 ASSERT_GT(fb_long_typetable.span().size(), 0);
433 const FlatbufferDetachedBuffer<Configuration> fb_short_reflection(
434 JsonToFlatbuffer(json_short, FlatbufferType(&Schema().message())));
435 ASSERT_GT(fb_short_reflection.span().size(), 0);
436 const FlatbufferDetachedBuffer<Configuration> fb_long_reflection(
437 JsonToFlatbuffer(json_long, FlatbufferType(&Schema().message())));
438 ASSERT_GT(fb_long_reflection.span().size(), 0);
Austin Schuhd3936202020-04-07 20:11:07 -0700439
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800440 const std::string back_json_short_typetable = FlatbufferToJson<Configuration>(
441 fb_short_typetable, {.multi_line = false, .max_vector_size = 100});
442 const std::string back_json_long_typetable = FlatbufferToJson<Configuration>(
443 fb_long_typetable, {.multi_line = false, .max_vector_size = 100});
444 const std::string back_json_short_reflection =
445 FlatbufferToJson<Configuration>(
446 fb_short_reflection, {.multi_line = false, .max_vector_size = 100});
447 const std::string back_json_long_reflection = FlatbufferToJson<Configuration>(
448 fb_long_reflection, {.multi_line = false, .max_vector_size = 100});
Austin Schuhd3936202020-04-07 20:11:07 -0700449
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800450 EXPECT_EQ(json_short, back_json_short_typetable);
451 EXPECT_EQ(json_short, back_json_short_reflection);
Austin Schuh041fe9f2021-10-16 23:01:15 -0700452 EXPECT_EQ("{ \"vector_foo_int\": [ \"... 101 elements ...\" ] }",
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800453 back_json_long_typetable);
Austin Schuh041fe9f2021-10-16 23:01:15 -0700454 EXPECT_EQ("{ \"vector_foo_int\": [ \"... 101 elements ...\" ] }",
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800455 back_json_long_reflection);
Austin Schuhd3936202020-04-07 20:11:07 -0700456}
457
Austin Schuh7f99e472020-06-17 20:38:17 -0700458// Tests that a nullptr buffer prints nullptr.
459TEST_F(JsonToFlatbufferTest, NullptrData) {
460 EXPECT_EQ("null", TableFlatbufferToJson((const flatbuffers::Table *)(nullptr),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700461 ConfigurationTypeTable()));
Austin Schuh7f99e472020-06-17 20:38:17 -0700462}
463
Alexander Yeee61cac32023-02-11 19:40:40 -0800464TEST_F(JsonToFlatbufferTest, SpacedData) {
465 EXPECT_TRUE(CompareFlatBuffer(
466 FlatbufferDetachedBuffer<VectorOfStrings>(
467 JsonToFlatbuffer<VectorOfStrings>(R"json({
468 "str": [
469 "f o o",
470 "b a r",
471 "foo bar",
472 "bar foo"
473 ]
474})json")),
475 JsonFileToFlatbuffer<VectorOfStrings>(
476 ArtifactPath("aos/json_to_flatbuffer_test_spaces.json"))));
477}
478
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800479} // namespace aos::testing