blob: ca63249b23580bf9686fd2f232453eeae586a31b [file] [log] [blame]
Austin Schuh09d7ffa2019-10-03 23:43:34 -07001#include "aos/flatbuffer_merge.h"
2
3#include "gtest/gtest.h"
4
5#include "aos/json_to_flatbuffer.h"
6#include "aos/json_to_flatbuffer_generated.h"
7#include "flatbuffers/minireflect.h"
8
9namespace aos {
10namespace testing {
11
12class FlatbufferMerge : public ::testing::Test {
13 public:
14 FlatbufferMerge() {}
15
16 void JsonMerge(const ::std::string in1, const ::std::string in2,
17 const ::std::string out) {
18 printf("Merging: %s\n", in1.c_str());
19 printf("Merging: %s\n", in2.c_str());
Austin Schuhe93d8642019-10-13 15:27:07 -070020 const flatbuffers::DetachedBuffer fb1 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070021 static_cast<const char *>(in1.c_str()), ConfigurationTypeTable());
22
23 const ::std::string in1_nested = "{ \"nested_config\": " + in1 + " }";
Austin Schuhe93d8642019-10-13 15:27:07 -070024 const flatbuffers::DetachedBuffer fb1_nested =
25 JsonToFlatbuffer(static_cast<const char *>(in1_nested.c_str()),
26 ConfigurationTypeTable());
Austin Schuh09d7ffa2019-10-03 23:43:34 -070027
Austin Schuhe93d8642019-10-13 15:27:07 -070028 const flatbuffers::DetachedBuffer fb2 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070029 static_cast<const char *>(in2.c_str()), ConfigurationTypeTable());
30
31 const ::std::string in2_nested = "{ \"nested_config\": " + in2 + " }";
Austin Schuhe93d8642019-10-13 15:27:07 -070032 const flatbuffers::DetachedBuffer fb2_nested =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070033 JsonToFlatbuffer(static_cast<const char *>(in2_nested.c_str()),
34 ConfigurationTypeTable());
35
36 const ::std::string out_nested = "{ \"nested_config\": " + out + " }";
37
Austin Schuhe93d8642019-10-13 15:27:07 -070038 const flatbuffers::DetachedBuffer empty =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070039 JsonToFlatbuffer("{ }", ConfigurationTypeTable());
40
41 ASSERT_NE(fb1.size(), 0u);
42 ASSERT_NE(fb2.size(), 0u);
43 ASSERT_NE(fb1_nested.size(), 0u);
44 ASSERT_NE(fb2_nested.size(), 0u);
45
46 // We now want to run 7 tests.
47 // in1 merged "" -> in1.
48 // in2 merged "" -> in2.
49 // "" merged in1 -> in1.
50 // "" merged in2 -> in2.
51 // nullptr merged in1 -> in1.
52 // in1 merged nullptr -> in1.
53 // in1 merged in2 -> out.
54
55 {
56 // in1 merged with "" => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -070057 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070058 MergeFlatBuffers<Configuration>(fb1.data(), empty.data());
59 ASSERT_NE(fb_merged.size(), 0u);
60
Austin Schuhe93d8642019-10-13 15:27:07 -070061 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070062 }
63
64 {
65 // in2 merged with "" => in2.
Austin Schuhe93d8642019-10-13 15:27:07 -070066 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070067 MergeFlatBuffers<Configuration>(fb2.data(), empty.data());
68 ASSERT_NE(fb_merged.size(), 0u);
69
Austin Schuhe93d8642019-10-13 15:27:07 -070070 EXPECT_EQ(in2, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070071 }
72
73 {
74 // "" merged with in1 => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -070075 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070076 MergeFlatBuffers<Configuration>(empty.data(), fb1.data());
77 ASSERT_NE(fb_merged.size(), 0u);
78
Austin Schuhe93d8642019-10-13 15:27:07 -070079 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070080 }
81
82 {
83 // "" merged with in2 => in2.
Austin Schuhe93d8642019-10-13 15:27:07 -070084 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070085 MergeFlatBuffers<Configuration>(empty.data(), fb2.data());
86 ASSERT_NE(fb_merged.size(), 0u);
87
Austin Schuhe93d8642019-10-13 15:27:07 -070088 EXPECT_EQ(in2, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070089 }
90
91 {
92 // nullptr merged with in1 => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -070093 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070094 MergeFlatBuffers<Configuration>(nullptr, fb1.data());
95 ASSERT_NE(fb_merged.size(), 0u);
96
Austin Schuhe93d8642019-10-13 15:27:07 -070097 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070098 }
99
100 {
101 // in1 merged with nullptr => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -0700102 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700103 MergeFlatBuffers<Configuration>(fb1.data(), nullptr);
104 ASSERT_NE(fb_merged.size(), 0u);
105
Austin Schuhe93d8642019-10-13 15:27:07 -0700106 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700107 }
108
109 {
110 // in1 merged with in2 => out.
Austin Schuhe93d8642019-10-13 15:27:07 -0700111 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700112 MergeFlatBuffers<Configuration>(fb1.data(), fb2.data());
113 ASSERT_NE(fb_merged.size(), 0u);
114
115 const ::std::string merged_output =
Austin Schuhe93d8642019-10-13 15:27:07 -0700116 FlatbufferToJson(fb_merged, ConfigurationTypeTable());
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700117 EXPECT_EQ(out, merged_output);
118
119 printf("Merged to: %s\n", merged_output.c_str());
120 }
121
122 // Now, to make things extra exciting, nest a config inside a config. And
123 // run all the tests. This will exercise some fun nested merges and copies.
124
125 {
126 // in1_nested merged with "" => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -0700127 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700128 MergeFlatBuffers<Configuration>(fb1_nested.data(), empty.data());
129 ASSERT_NE(fb_merged.size(), 0u);
130
131 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700132 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700133 }
134
135 {
136 // in2_nested merged with "" => in2_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700137 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700138 MergeFlatBuffers<Configuration>(fb2_nested.data(), empty.data());
139 ASSERT_NE(fb_merged.size(), 0u);
140
141 EXPECT_EQ(in2_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700142 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700143 }
144
145 {
146 // "" merged with in1_nested => in1_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700147 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700148 MergeFlatBuffers<Configuration>(empty.data(), fb1_nested.data());
149 ASSERT_NE(fb_merged.size(), 0u);
150
151 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700152 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700153 }
154
155 {
156 // "" merged with in2_nested => in2_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700157 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700158 MergeFlatBuffers<Configuration>(empty.data(), fb2_nested.data());
159 ASSERT_NE(fb_merged.size(), 0u);
160
161 EXPECT_EQ(in2_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700162 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700163 }
164
165 {
166 // nullptr merged with in1_nested => in1_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700167 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700168 MergeFlatBuffers<Configuration>(nullptr, fb1_nested.data());
169 ASSERT_NE(fb_merged.size(), 0u);
170
171 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700172 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700173 }
174
175 {
176 // nullptr merged with in1_nested => in1_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700177 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700178 MergeFlatBuffers<Configuration>(fb1_nested.data(), nullptr);
179 ASSERT_NE(fb_merged.size(), 0u);
180
181 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700182 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700183 }
184
185 {
186 // in1_nested merged with in2_nested => out_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700187 flatbuffers::DetachedBuffer fb_merged =
188 MergeFlatBuffers<Configuration>(fb1_nested, fb2_nested);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700189 ASSERT_NE(fb_merged.size(), 0u);
190
191 EXPECT_EQ(out_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700192 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700193 }
194 }
195};
196
197// Test the easy ones. Test every type, single, no nesting.
198TEST_F(FlatbufferMerge, Basic) {
199 JsonMerge("{ \"foo_bool\": true }", "{ \"foo_bool\": false }",
200 "{ \"foo_bool\": false }");
201
202 JsonMerge("{ \"foo_bool\": false }", "{ \"foo_bool\": true }",
203 "{ \"foo_bool\": true }");
204
205 JsonMerge("{ \"foo_byte\": 5 }", "{ \"foo_byte\": -7 }",
206 "{ \"foo_byte\": -7 }");
207
208 JsonMerge("{ \"foo_ubyte\": 5 }", "{ \"foo_ubyte\": 7 }",
209 "{ \"foo_ubyte\": 7 }");
210
211 JsonMerge("{ \"foo_short\": 5 }", "{ \"foo_short\": 7 }",
212 "{ \"foo_short\": 7 }");
213
214 JsonMerge("{ \"foo_int\": 5 }", "{ \"foo_int\": 7 }", "{ \"foo_int\": 7 }");
215
216 JsonMerge("{ \"foo_uint\": 5 }", "{ \"foo_uint\": 7 }",
217 "{ \"foo_uint\": 7 }");
218
219 JsonMerge("{ \"foo_long\": 5 }", "{ \"foo_long\": 7 }",
220 "{ \"foo_long\": 7 }");
221
222 JsonMerge("{ \"foo_ulong\": 5 }", "{ \"foo_ulong\": 7 }",
223 "{ \"foo_ulong\": 7 }");
224
225 JsonMerge("{ \"foo_float\": 5.0 }", "{ \"foo_float\": 7.1 }",
226 "{ \"foo_float\": 7.1 }");
227
228 JsonMerge("{ \"foo_double\": 5.0 }", "{ \"foo_double\": 7.1 }",
229 "{ \"foo_double\": 7.1 }");
230}
231
232// Test arrays of simple types.
233TEST_F(FlatbufferMerge, Array) {
234 JsonMerge("{ \"foo_string\": \"baz\" }", "{ \"foo_string\": \"bar\" }",
235 "{ \"foo_string\": \"bar\" }");
236
237 JsonMerge("{ \"vector_foo_bool\": [ true, true, false ] }",
238 "{ \"vector_foo_bool\": [ false, true, true, false ] }",
239 "{ \"vector_foo_bool\": [ true, true, false, false, "
240 "true, true, false ] }");
241
242 JsonMerge("{ \"vector_foo_byte\": [ 9, 7, 1 ] }",
243 "{ \"vector_foo_byte\": [ -3, 1, 3, 2 ] }",
244 "{ \"vector_foo_byte\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
245
246 JsonMerge("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }",
247 "{ \"vector_foo_ubyte\": [ 3, 1, 3, 2 ] }",
248 "{ \"vector_foo_ubyte\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
249
250 JsonMerge("{ \"vector_foo_short\": [ 9, 7, 1 ] }",
251 "{ \"vector_foo_short\": [ -3, 1, 3, 2 ] }",
252 "{ \"vector_foo_short\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
253
254 JsonMerge("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }",
255 "{ \"vector_foo_ushort\": [ 3, 1, 3, 2 ] }",
256 "{ \"vector_foo_ushort\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
257
258 JsonMerge("{ \"vector_foo_int\": [ 9, 7, 1 ] }",
259 "{ \"vector_foo_int\": [ -3, 1, 3, 2 ] }",
260 "{ \"vector_foo_int\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
261
262 JsonMerge("{ \"vector_foo_uint\": [ 9, 7, 1 ] }",
263 "{ \"vector_foo_uint\": [ 3, 1, 3, 2 ] }",
264 "{ \"vector_foo_uint\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
265
266 JsonMerge("{ \"vector_foo_long\": [ 9, 7, 1 ] }",
267 "{ \"vector_foo_long\": [ -3, 1, 3, 2 ] }",
268 "{ \"vector_foo_long\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
269
270 JsonMerge("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }",
271 "{ \"vector_foo_ulong\": [ 3, 1, 3, 2 ] }",
272 "{ \"vector_foo_ulong\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
273
274 JsonMerge("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }",
275 "{ \"vector_foo_float\": [ -3.0, 1.3, 3.0, 2.0 ] }",
276 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0, -3.0, 1.3, 3.0, 2.0 ] }");
277
Austin Schuhe93d8642019-10-13 15:27:07 -0700278 JsonMerge(
279 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \" ] }",
280 "{ \"vector_foo_string\": [ \"31\", \"32\" ] }",
281 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \", \"31\", \"32\" ] }");
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700282}
283
284// Test nested messages, and arrays of nested messages.
285TEST_F(FlatbufferMerge, NestedStruct) {
286 JsonMerge(
287 "{ \"single_application\": { \"name\": \"woot\" } }",
288 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
289 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }");
290
291 JsonMerge(
292 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
293 "{ \"single_application\": { \"name\": \"woot\" } }",
294 "{ \"single_application\": { \"name\": \"woot\", \"priority\": 7 } }");
295
296 JsonMerge("{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }",
297 "{ \"apps\": [ { \"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }",
298 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" }, { "
299 "\"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }");
300}
301
302// TODO(austin): enums
303// TODO(austin): unions
304// TODO(austin): struct
305
306} // namespace testing
307} // namespace aos