blob: 80dec7c9858fecb24dbecbeeb475d8ffa1646884 [file] [log] [blame]
Austin Schuh3e95e5d2019-09-20 00:08:54 -07001#include "aos/json_to_flatbuffer.h"
2
3#include "gtest/gtest.h"
4
5#include "aos/json_to_flatbuffer_generated.h"
6#include "flatbuffers/minireflect.h"
7
8namespace aos {
9namespace testing {
10
11class JsonToFlatbufferTest : public ::testing::Test {
12 public:
13 JsonToFlatbufferTest() {}
14
15 bool JsonAndBack(const ::std::string str) { return JsonAndBack(str, str); }
16
17 bool JsonAndBack(const ::std::string in, const ::std::string out) {
18 printf("Testing: %s\n", in.c_str());
Austin Schuhe93d8642019-10-13 15:27:07 -070019 const flatbuffers::DetachedBuffer fb =
Austin Schuh3e95e5d2019-09-20 00:08:54 -070020 JsonToFlatbuffer(in.data(), ConfigurationTypeTable());
21
22 if (fb.size() == 0) {
23 return false;
24 }
25
Austin Schuhe93d8642019-10-13 15:27:07 -070026 const ::std::string back = FlatbufferToJson(fb, ConfigurationTypeTable());
Austin Schuh3e95e5d2019-09-20 00:08:54 -070027
28 printf("Back to string: %s\n", back.c_str());
29
30 return back == out;
31 }
32};
33
34// Tests that the various escapes work as expected.
35TEST_F(JsonToFlatbufferTest, ValidEscapes) {
36 EXPECT_TRUE(
37 JsonAndBack("{ \"foo_string\": \"a\\\"b\\/c\\bd\\fc\\nd\\re\\tf\" }",
38 "{ \"foo_string\": \"a\\\"b/c\\bd\\fc\\nd\\re\\tf\" }"));
39}
40
41// Test the easy ones. Test every type, single, no nesting.
42TEST_F(JsonToFlatbufferTest, Basic) {
43 EXPECT_TRUE(JsonAndBack("{ \"foo_bool\": true }"));
44
45 EXPECT_TRUE(JsonAndBack("{ \"foo_byte\": 5 }"));
46 EXPECT_TRUE(JsonAndBack("{ \"foo_ubyte\": 5 }"));
47
48 EXPECT_TRUE(JsonAndBack("{ \"foo_short\": 5 }"));
49 EXPECT_TRUE(JsonAndBack("{ \"foo_ushort\": 5 }"));
50
51 EXPECT_TRUE(JsonAndBack("{ \"foo_int\": 5 }"));
52 EXPECT_TRUE(JsonAndBack("{ \"foo_uint\": 5 }"));
53
54 EXPECT_TRUE(JsonAndBack("{ \"foo_long\": 5 }"));
55 EXPECT_TRUE(JsonAndBack("{ \"foo_ulong\": 5 }"));
56
57 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.0 }"));
58 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5.0 }"));
59
Alex Perrycb7da4b2019-08-28 19:35:56 -070060 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"None\" }"));
61 EXPECT_TRUE(JsonAndBack("{ \"foo_enum\": \"UType\" }"));
62
63 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"None\" }"));
64 EXPECT_TRUE(JsonAndBack("{ \"foo_enum_default\": \"UType\" }"));
65
Austin Schuh3e95e5d2019-09-20 00:08:54 -070066 EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"baz\" }"));
67}
68
Austin Schuhbba0c3c2019-11-29 22:00:34 -080069// Tests that NaN is handled correctly
70TEST_F(JsonToFlatbufferTest, Nan) {
71 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": nan }"));
72 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": -nan }"));
73}
74
Austin Schuh84314af2019-10-03 09:11:34 -070075// Tests that we can handle decimal points.
76TEST_F(JsonToFlatbufferTest, DecimalPoint) {
77 EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.1 }"));
78 EXPECT_TRUE(JsonAndBack("{ \"foo_double\": 5.1 }"));
79}
80
Austin Schuh3e95e5d2019-09-20 00:08:54 -070081// Test what happens if you pass a field name that we don't know.
82TEST_F(JsonToFlatbufferTest, InvalidFieldName) {
83 EXPECT_FALSE(JsonAndBack("{ \"foo\": 5 }"));
84}
85
Alex Perrycb7da4b2019-08-28 19:35:56 -070086// Tests that an invalid enum type is handled correctly.
87TEST_F(JsonToFlatbufferTest, InvalidEnumName) {
88 EXPECT_FALSE(JsonAndBack("{ \"foo_enum\": \"5ype\" }"));
89
90 EXPECT_FALSE(JsonAndBack("{ \"foo_enum_default\": \"7ype\" }"));
91}
92
Austin Schuh3e95e5d2019-09-20 00:08:54 -070093// Test that adding a duplicate field results in an error.
94TEST_F(JsonToFlatbufferTest, DuplicateField) {
95 EXPECT_FALSE(
96 JsonAndBack("{ \"foo_int\": 5, \"foo_int\": 7 }", "{ \"foo_int\": 7 }"));
97}
98
99// Test that various syntax errors are caught correctly
100TEST_F(JsonToFlatbufferTest, InvalidSyntax) {
101 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5"));
102 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 "));
103 EXPECT_FALSE(JsonAndBack("{ \"foo_string\": \""));
104 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5 } }"));
105
106 EXPECT_FALSE(JsonAndBack("{ foo_int: 5 }"));
107
108 EXPECT_FALSE(JsonAndBack("{ \"foo_int\": 5, }", "{ \"foo_int\": 5 }"));
109
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700110 EXPECT_FALSE(
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700111 JsonAndBack("{ \"apps\":\n[\n{\n\"name\": \"woot\"\n},\n{\n\"name\": "
112 "\"wow\"\n} ,\n]\n}"));
113
114 EXPECT_FALSE(JsonAndBack(
115 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] , }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700116
117 EXPECT_FALSE(
118 JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] , }"));
119
120 EXPECT_FALSE(
121 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } , }"));
122}
123
124// Test arrays of simple types.
125TEST_F(JsonToFlatbufferTest, Array) {
126 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700127 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_byte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700128 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700129 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ubyte\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700130
131 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700132 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_short\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700133 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700134 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ushort\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700135
136 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700137 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_int\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700138 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700139 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_uint\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700140
141 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700142 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_long\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700143 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700144 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_ulong\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700145
146 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700147 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700148 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700149 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700150
151 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ] }",
152 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }"));
153 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_double\": [ 9, 7, 1 ] }",
154 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
155
156 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ \"bar\", \"baz\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700157 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_string\": [ ] }"));
Ravago Jonescf453ab2020-05-06 21:14:53 -0700158 EXPECT_TRUE(JsonAndBack(
159 "{ \"vector_foo_enum\": [ \"None\", \"UType\", \"Bool\" ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700160 EXPECT_TRUE(JsonAndBack("{ \"vector_foo_enum\": [ ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700161}
162
163// Test nested messages, and arrays of nested messages.
164TEST_F(JsonToFlatbufferTest, NestedStruct) {
165 EXPECT_TRUE(
166 JsonAndBack("{ \"single_application\": { \"name\": \"woot\" } }"));
167
Alex Perrycb7da4b2019-08-28 19:35:56 -0700168 EXPECT_TRUE(JsonAndBack("{ \"single_application\": { } }"));
169
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700170 EXPECT_TRUE(JsonAndBack(
171 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700172
Ravago Jonescf453ab2020-05-06 21:14:53 -0700173 EXPECT_TRUE(JsonAndBack("{ \"apps\": [ { }, { } ] }"));
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700174}
175
Austin Schuh84314af2019-10-03 09:11:34 -0700176// Test that we can parse an empty message.
177TEST_F(JsonToFlatbufferTest, EmptyMessage) {
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700178 // Empty message works.
Austin Schuh84314af2019-10-03 09:11:34 -0700179 EXPECT_TRUE(JsonAndBack("{ }"));
180}
181
Austin Schuh81da4b22019-10-06 14:03:24 -0700182// Tests that comments get stripped.
183TEST_F(JsonToFlatbufferTest, Comments) {
184 EXPECT_TRUE(JsonAndBack("{ /* foo */ \"vector_foo_double\": [ 9, 7, 1 ] }",
185 "{ \"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
186}
187
Austin Schuh9e2532d2019-10-06 14:01:15 -0700188// Tests that multiple arrays get properly handled.
189TEST_F(JsonToFlatbufferTest, MultipleArrays) {
190 EXPECT_TRUE(
191 JsonAndBack("{ \"vector_foo_float\": [ 9, 7, 1 ], \"vector_foo_double\": "
192 "[ 9, 7, 1 ] }",
193 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ], "
194 "\"vector_foo_double\": [ 9.0, 7.0, 1.0 ] }"));
195}
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700196
Alex Perrycb7da4b2019-08-28 19:35:56 -0700197// Tests that multiple arrays get properly handled.
198TEST_F(JsonToFlatbufferTest, NestedArrays) {
199 EXPECT_TRUE(
Ravago Jonescf453ab2020-05-06 21:14:53 -0700200 JsonAndBack("{ \"vov\": { \"v\": [ { \"str\": [ \"a\", \"b\" ] }, { "
201 "\"str\": [ \"c\", \"d\" ] } ] } }"));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700202}
203
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700204// TODO(austin): Missmatched values.
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700205//
206// TODO(austin): unions?
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700207
Austin Schuhd3936202020-04-07 20:11:07 -0700208TEST_F(JsonToFlatbufferTest, TrimmedVector) {
209 std::string json_short = "{ \"vector_foo_int\": [ 0";
210 for (int i = 1; i < 100; ++i) {
211 json_short += ", ";
212 json_short += std::to_string(i);
213 }
214 std::string json_long = json_short;
215 json_short += " ] }";
216 json_long += ", 101 ] }";
217
218 const flatbuffers::DetachedBuffer fb_short =
219 JsonToFlatbuffer(json_short.data(), ConfigurationTypeTable());
220 ASSERT_GT(fb_short.size(), 0);
221 const flatbuffers::DetachedBuffer fb_long =
222 JsonToFlatbuffer(json_long.data(), ConfigurationTypeTable());
223 ASSERT_GT(fb_long.size(), 0);
224
Ravago Jonescf453ab2020-05-06 21:14:53 -0700225 const std::string back_json_short = FlatbufferToJson(
226 fb_short, ConfigurationTypeTable(), {.multi_line = false, .max_vector_size = 100});
227 const std::string back_json_long = FlatbufferToJson(
228 fb_long, ConfigurationTypeTable(), {.multi_line = false, .max_vector_size = 100});
Austin Schuhd3936202020-04-07 20:11:07 -0700229
230 EXPECT_EQ(json_short, back_json_short);
231 EXPECT_EQ("{ \"vector_foo_int\": [ ... 101 elements ... ] }", back_json_long);
232}
233
Austin Schuh7f99e472020-06-17 20:38:17 -0700234// Tests that a nullptr buffer prints nullptr.
235TEST_F(JsonToFlatbufferTest, NullptrData) {
236 EXPECT_EQ("null", TableFlatbufferToJson((const flatbuffers::Table *)(nullptr),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700237 ConfigurationTypeTable()));
Austin Schuh7f99e472020-06-17 20:38:17 -0700238}
239
Austin Schuh3e95e5d2019-09-20 00:08:54 -0700240} // namespace testing
241} // namespace aos