blob: 9dc12d26476ad8c74df3ca5c06949007725c1a84 [file] [log] [blame]
Austin Schuh3e95e5d2019-09-20 00:08:54 -07001#include "aos/json_to_flatbuffer.h"
2
Austin Schuh3e95e5d2019-09-20 00:08:54 -07003#include "aos/json_to_flatbuffer_generated.h"
4#include "flatbuffers/minireflect.h"
Brian Silverman5c710412021-02-09 19:09:32 -08005#include "gtest/gtest.h"
Austin Schuh3e95e5d2019-09-20 00:08:54 -07006
7namespace aos {
8namespace testing {
9
10class JsonToFlatbufferTest : public ::testing::Test {
11 public:
12 JsonToFlatbufferTest() {}
13
Brian Silvermanc5105ab2021-02-10 17:55:38 -080014 FlatbufferVector<reflection::Schema> Schema() {
15 return FileToFlatbuffer<reflection::Schema>("aos/json_to_flatbuffer.bfbs");
16 }
17
Austin Schuh3e95e5d2019-09-20 00:08:54 -070018 bool JsonAndBack(const ::std::string str) { return JsonAndBack(str, str); }
19
20 bool JsonAndBack(const ::std::string in, const ::std::string out) {
21 printf("Testing: %s\n", in.c_str());
Brian Silvermanc5105ab2021-02-10 17:55:38 -080022 FlatbufferDetachedBuffer<Configuration> fb_typetable =
Austin Schuhadd6eb32020-11-09 21:24:26 -080023 JsonToFlatbuffer<Configuration>(in.data());
Brian Silvermanc5105ab2021-02-10 17:55:38 -080024 FlatbufferDetachedBuffer<Configuration> fb_reflection =
25 JsonToFlatbuffer(in.data(), FlatbufferType(&Schema().message()));
Austin Schuh3e95e5d2019-09-20 00:08:54 -070026
Brian Silvermanc5105ab2021-02-10 17:55:38 -080027 if (fb_typetable.span().size() == 0) {
28 return false;
29 }
30 if (fb_reflection.span().size() == 0) {
Austin Schuh3e95e5d2019-09-20 00:08:54 -070031 return false;
32 }
33
Brian Silvermanc5105ab2021-02-10 17:55:38 -080034 const ::std::string back_typetable = FlatbufferToJson(fb_typetable);
35 const ::std::string back_reflection = FlatbufferToJson(fb_reflection);
Austin Schuh3e95e5d2019-09-20 00:08:54 -070036
Brian Silvermanc5105ab2021-02-10 17:55:38 -080037 printf("Back to string via TypeTable: %s\n", back_typetable.c_str());
38 printf("Back to string via reflection: %s\n", back_reflection.c_str());
Austin Schuh3e95e5d2019-09-20 00:08:54 -070039
Brian Silvermanc5105ab2021-02-10 17:55:38 -080040 return back_typetable == out && back_reflection == out;
Austin Schuh3e95e5d2019-09-20 00:08:54 -070041 }
42};
43
44// Tests that the various escapes work as expected.
45TEST_F(JsonToFlatbufferTest, ValidEscapes) {
46 EXPECT_TRUE(
47 JsonAndBack("{ \"foo_string\": \"a\\\"b\\/c\\bd\\fc\\nd\\re\\tf\" }",
48 "{ \"foo_string\": \"a\\\"b/c\\bd\\fc\\nd\\re\\tf\" }"));
49}
50
51// Test the easy ones. Test every type, single, no nesting.
52TEST_F(JsonToFlatbufferTest, Basic) {
53 EXPECT_TRUE(JsonAndBack("{ \"foo_bool\": true }"));
54
55 EXPECT_TRUE(JsonAndBack("{ \"foo_byte\": 5 }"));
56 EXPECT_TRUE(JsonAndBack("{ \"foo_ubyte\": 5 }"));
57
58 EXPECT_TRUE(JsonAndBack("{ \"foo_short\": 5 }"));
59 EXPECT_TRUE(JsonAndBack("{ \"foo_ushort\": 5 }"));
60
61 EXPECT_TRUE(JsonAndBack("{ \"foo_int\": 5 }"));
62 EXPECT_TRUE(JsonAndBack("{ \"foo_uint\": 5 }"));
63
64 EXPECT_TRUE(JsonAndBack("{ \"foo_long\": 5 }"));
65 EXPECT_TRUE(JsonAndBack("{ \"foo_ulong\": 5 }"));
66
67 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.0 }"));
68 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5.0 }"));
69
Alex Perrycb7da4b2019-08-28 19:35:56 -070070 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"None\" }"));
71 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"UType\" }"));
72
73 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"None\" }"));
74 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"UType\" }"));
75
Austin Schuh3e95e5d2019-09-20 00:08:54 -070076 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"baz\" }"));
Brian Silverman5c710412021-02-09 19:09:32 -080077
78 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Zero\" }"));
79 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Big\" }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -070080}
81
Austin Schuhbba0c3c2019-11-29 22:00:34 -080082// Tests that NaN is handled correctly
83TEST_F(JsonToFlatbufferTest, Nan) {
84 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": nan }"));
85 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": -nan }"));
86}
87
Austin Schuh84314af2019-10-03 09:11:34 -070088// Tests that we can handle decimal points.
89TEST_F(JsonToFlatbufferTest, DecimalPoint) {
90 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.1 }"));
91 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5.1 }"));
92}
93
Austin Schuh3e95e5d2019-09-20 00:08:54 -070094// Test what happens if you pass a field name that we don't know.
95TEST_F(JsonToFlatbufferTest, InvalidFieldName) {
96 EXPECT_FALSE(JsonAndBack("{ \"foo\": 5 }"));
97}
98
Alex Perrycb7da4b2019-08-28 19:35:56 -070099// Tests that an invalid enum type is handled correctly.
100TEST_F(JsonToFlatbufferTest, InvalidEnumName) {
101 EXPECT_FALSE(JsonAndBack("{ \"foo_enum\": \"5ype\" }"));
102
103 EXPECT_FALSE(JsonAndBack("{ \"foo_enum_default\": \"7ype\" }"));
Brian Silverman5c710412021-02-09 19:09:32 -0800104
105 EXPECT_FALSE(JsonAndBack("{ \"foo_enum_nonconsecutive\": \"Nope\" }"));
106
107 EXPECT_FALSE(
108 JsonAndBack("{ \"foo_enum_nonconsecutive_default\": \"Nope\" }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700109}
110
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700111// Test that adding a duplicate field results in an error.
112TEST_F(JsonToFlatbufferTest, DuplicateField) {
113 EXPECT_FALSE(
114 JsonAndBack("{ \"foo_int\": 5, \"foo_int\": 7 }", "{ \"foo_int\": 7 }"));
115}
116
117// Test that various syntax errors are caught correctly
118TEST_F(JsonToFlatbufferTest, InvalidSyntax) {
119 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5"));
120 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 "));
121 EXPECT_FALSE(JsonAndBack("{ \"foo_string\": \""));
122 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 } }"));
123
124 EXPECT_FALSE(JsonAndBack("{ foo_int: 5 }"));
125
126 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5, }", "{ \"foo_int\": 5 }"));
127
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700128 EXPECT_FALSE(
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700129 JsonAndBack("{ \"apps\":\n[\n{\n\"name\": \"woot\"\n},\n{\n\"name\": "
130 "\"wow\"\n} ,\n]\n}"));
131
132 EXPECT_FALSE(JsonAndBack(
133 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] , }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700134
135 EXPECT_FALSE(
136 JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] , }"));
137
138 EXPECT_FALSE(
139 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } , }"));
140}
141
142// Test arrays of simple types.
143TEST_F(JsonToFlatbufferTest, Array) {
144 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700145 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700146 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700147 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700148
149 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700150 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700151 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700152 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700153
154 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700155 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700156 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700157 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700158
159 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700160 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700161 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700162 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700163
164 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700165 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700166 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700167 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700168
169 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ] }",
170 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }"));
171 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9, 7, 1 ] }",
172 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
173
174 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700175 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ ] }"));
Ravago Jonescf453ab2020-05-06 21:14:53 -0700176 EXPECT_TRUE(JsonAndBack(
177 "{ \"vector_foo_enum\": [ \"None\", \"UType\", \"Bool\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700178 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_enum\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700179}
180
181// Test nested messages, and arrays of nested messages.
182TEST_F(JsonToFlatbufferTest, NestedStruct) {
183 EXPECT_TRUE(
184 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } }"));
185
Alex Perrycb7da4b2019-08-28 19:35:56 -0700186 EXPECT_TRUE(JsonAndBack("{ \"single_application\": { } }"));
187
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700188 EXPECT_TRUE(JsonAndBack(
189 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700190
Ravago Jonescf453ab2020-05-06 21:14:53 -0700191 EXPECT_TRUE(JsonAndBack("{ \"apps\": [ { }, { } ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700192}
193
Austin Schuh84314af2019-10-03 09:11:34 -0700194// Test that we can parse an empty message.
195TEST_F(JsonToFlatbufferTest, EmptyMessage) {
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700196 // Empty message works.
Austin Schuh84314af2019-10-03 09:11:34 -0700197 EXPECT_TRUE(JsonAndBack("{ }"));
198}
199
Austin Schuh81da4b22019-10-06 14:03:24 -0700200// Tests that comments get stripped.
201TEST_F(JsonToFlatbufferTest, Comments) {
202 EXPECT_TRUE(JsonAndBack("{ /* foo */ \"vector_foo_double\": [ 9, 7, 1 ] }",
203 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
204}
205
Austin Schuh9e2532d2019-10-06 14:01:15 -0700206// Tests that multiple arrays get properly handled.
207TEST_F(JsonToFlatbufferTest, MultipleArrays) {
208 EXPECT_TRUE(
209 JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ], \"vector_foo_double\": "
210 "[ 9, 7, 1 ] }",
211 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ], "
212 "\"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
213}
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700214
Alex Perrycb7da4b2019-08-28 19:35:56 -0700215// Tests that multiple arrays get properly handled.
216TEST_F(JsonToFlatbufferTest, NestedArrays) {
217 EXPECT_TRUE(
Ravago Jonescf453ab2020-05-06 21:14:53 -0700218 JsonAndBack("{ \"vov\": { \"v\": [ { \"str\": [ \"a\", \"b\" ] }, { "
219 "\"str\": [ \"c\", \"d\" ] } ] } }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700220}
221
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700222// TODO(austin): Missmatched values.
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700223//
224// TODO(austin): unions?
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700225
Austin Schuhd3936202020-04-07 20:11:07 -0700226TEST_F(JsonToFlatbufferTest, TrimmedVector) {
227 std::string json_short = "{ \"vector_foo_int\": [ 0";
228 for (int i = 1; i < 100; ++i) {
229 json_short += ", ";
230 json_short += std::to_string(i);
231 }
232 std::string json_long = json_short;
233 json_short += " ] }";
234 json_long += ", 101 ] }";
235
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800236 const FlatbufferDetachedBuffer<Configuration> fb_short_typetable(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800237 JsonToFlatbuffer<Configuration>(json_short));
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800238 ASSERT_GT(fb_short_typetable.span().size(), 0);
239 const FlatbufferDetachedBuffer<Configuration> fb_long_typetable(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800240 JsonToFlatbuffer<Configuration>(json_long));
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800241 ASSERT_GT(fb_long_typetable.span().size(), 0);
242 const FlatbufferDetachedBuffer<Configuration> fb_short_reflection(
243 JsonToFlatbuffer(json_short, FlatbufferType(&Schema().message())));
244 ASSERT_GT(fb_short_reflection.span().size(), 0);
245 const FlatbufferDetachedBuffer<Configuration> fb_long_reflection(
246 JsonToFlatbuffer(json_long, FlatbufferType(&Schema().message())));
247 ASSERT_GT(fb_long_reflection.span().size(), 0);
Austin Schuhd3936202020-04-07 20:11:07 -0700248
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800249 const std::string back_json_short_typetable = FlatbufferToJson<Configuration>(
250 fb_short_typetable, {.multi_line = false, .max_vector_size = 100});
251 const std::string back_json_long_typetable = FlatbufferToJson<Configuration>(
252 fb_long_typetable, {.multi_line = false, .max_vector_size = 100});
253 const std::string back_json_short_reflection =
254 FlatbufferToJson<Configuration>(
255 fb_short_reflection, {.multi_line = false, .max_vector_size = 100});
256 const std::string back_json_long_reflection = FlatbufferToJson<Configuration>(
257 fb_long_reflection, {.multi_line = false, .max_vector_size = 100});
Austin Schuhd3936202020-04-07 20:11:07 -0700258
Brian Silvermanc5105ab2021-02-10 17:55:38 -0800259 EXPECT_EQ(json_short, back_json_short_typetable);
260 EXPECT_EQ(json_short, back_json_short_reflection);
261 EXPECT_EQ("{ \"vector_foo_int\": [ ... 101 elements ... ] }",
262 back_json_long_typetable);
263 EXPECT_EQ("{ \"vector_foo_int\": [ ... 101 elements ... ] }",
264 back_json_long_reflection);
Austin Schuhd3936202020-04-07 20:11:07 -0700265}
266
Austin Schuh7f99e472020-06-17 20:38:17 -0700267// Tests that a nullptr buffer prints nullptr.
268TEST_F(JsonToFlatbufferTest, NullptrData) {
269 EXPECT_EQ("null", TableFlatbufferToJson((const flatbuffers::Table *)(nullptr),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700270 ConfigurationTypeTable()));
Austin Schuh7f99e472020-06-17 20:38:17 -0700271}
272
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700273} // namespace testing
274} // namespace aos