1 /*
2  * Copyright 2014 Google Inc. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 using System.IO;
18 using System.Text;
19 using MyGame.Example;
20 
21 namespace FlatBuffers.Test
22 {
23     [FlatBuffersTestClass]
24     public class FlatBuffersExampleTests
25     {
RunTests()26         public void RunTests()
27         {
28             CanCreateNewFlatBufferFromScratch();
29             CanReadCppGeneratedWireFile();
30             TestEnums();
31         }
32 
33         [FlatBuffersTestMethod]
CanCreateNewFlatBufferFromScratch()34         public void CanCreateNewFlatBufferFromScratch()
35         {
36             CanCreateNewFlatBufferFromScratch(true);
37             CanCreateNewFlatBufferFromScratch(false);
38         }
39 
CanCreateNewFlatBufferFromScratch(bool sizePrefix)40         private void CanCreateNewFlatBufferFromScratch(bool sizePrefix)
41         {
42             // Second, let's create a FlatBuffer from scratch in C#, and test it also.
43             // We use an initial size of 1 to exercise the reallocation algorithm,
44             // normally a size larger than the typical FlatBuffer you generate would be
45             // better for performance.
46             var fbb = new FlatBufferBuilder(1);
47 
48             StringOffset[] names = { fbb.CreateString("Frodo"), fbb.CreateString("Barney"), fbb.CreateString("Wilma") };
49             Offset<Monster>[] off = new Offset<Monster>[3];
50             Monster.StartMonster(fbb);
51             Monster.AddName(fbb, names[0]);
52             off[0] = Monster.EndMonster(fbb);
53             Monster.StartMonster(fbb);
54             Monster.AddName(fbb, names[1]);
55             off[1] = Monster.EndMonster(fbb);
56             Monster.StartMonster(fbb);
57             Monster.AddName(fbb, names[2]);
58             off[2] = Monster.EndMonster(fbb);
59             var sortMons = Monster.CreateSortedVectorOfMonster(fbb, off);
60 
61             // We set up the same values as monsterdata.json:
62 
63             var str = fbb.CreateString("MyMonster");
64             var test1 = fbb.CreateString("test1");
65             var test2 = fbb.CreateString("test2");
66 
67 
68             Monster.StartInventoryVector(fbb, 5);
69             for (int i = 4; i >= 0; i--)
70             {
71                 fbb.AddByte((byte)i);
72             }
73             var inv = fbb.EndVector();
74 
75             var fred = fbb.CreateString("Fred");
76             Monster.StartMonster(fbb);
77             Monster.AddName(fbb, fred);
78             var mon2 = Monster.EndMonster(fbb);
79 
80             Monster.StartTest4Vector(fbb, 2);
81             MyGame.Example.Test.CreateTest(fbb, (short)10, (sbyte)20);
82             MyGame.Example.Test.CreateTest(fbb, (short)30, (sbyte)40);
83             var test4 = fbb.EndVector();
84 
85             Monster.StartTestarrayofstringVector(fbb, 2);
86             fbb.AddOffset(test2.Value);
87             fbb.AddOffset(test1.Value);
88             var testArrayOfString = fbb.EndVector();
89 
90             Monster.StartMonster(fbb);
91             Monster.AddPos(fbb, Vec3.CreateVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
92                                                      Color.Green, (short)5, (sbyte)6));
93             Monster.AddHp(fbb, (short)80);
94             Monster.AddName(fbb, str);
95             Monster.AddInventory(fbb, inv);
96             Monster.AddTestType(fbb, Any.Monster);
97             Monster.AddTest(fbb, mon2.Value);
98             Monster.AddTest4(fbb, test4);
99             Monster.AddTestarrayofstring(fbb, testArrayOfString);
100             Monster.AddTestbool(fbb, true);
101             Monster.AddTestarrayoftables(fbb, sortMons);
102             var mon = Monster.EndMonster(fbb);
103 
104             if (sizePrefix)
105             {
106                 Monster.FinishSizePrefixedMonsterBuffer(fbb, mon);
107             }
108             else
109             {
110                 Monster.FinishMonsterBuffer(fbb, mon);
111             }
112 
113             // Dump to output directory so we can inspect later, if needed
114             #if ENABLE_SPAN_T
115             var data = fbb.DataBuffer.ToSizedArray();
116             string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
117             File.WriteAllBytes(filename, data);
118             #else
119             using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset))
120             {
121                 var data = ms.ToArray();
122                 string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
123                 File.WriteAllBytes(filename, data);
124             }
125             #endif
126 
127             // Remove the size prefix if necessary for further testing
128             ByteBuffer dataBuffer = fbb.DataBuffer;
129             if (sizePrefix)
130             {
131                 Assert.AreEqual(ByteBufferUtil.GetSizePrefix(dataBuffer) + FlatBufferConstants.SizePrefixLength,
132                                 dataBuffer.Length - dataBuffer.Position);
133                 dataBuffer = ByteBufferUtil.RemoveSizePrefix(dataBuffer);
134             }
135 
136             // Now assert the buffer
137             TestBuffer(dataBuffer);
138 
139             //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
140             // revert to original values after testing
141             Monster monster = Monster.GetRootAsMonster(dataBuffer);
142 
143 
144             // mana is optional and does not exist in the buffer so the mutation should fail
145             // the mana field should retain its default value
146             Assert.AreEqual(monster.MutateMana((short)10), false);
147             Assert.AreEqual(monster.Mana, (short)150);
148 
149             // Accessing a vector of sorted by the key tables
150             Assert.AreEqual(monster.Testarrayoftables(0).Value.Name, "Barney");
151             Assert.AreEqual(monster.Testarrayoftables(1).Value.Name, "Frodo");
152             Assert.AreEqual(monster.Testarrayoftables(2).Value.Name, "Wilma");
153 
154             // Example of searching for a table by the key
155             Assert.IsTrue(monster.TestarrayoftablesByKey("Frodo") != null);
156             Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null);
157             Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null);
158 
159             // testType is an existing field
160             Assert.AreEqual(monster.TestType, Any.Monster);
161 
162             //mutate the inventory vector
163             Assert.AreEqual(monster.MutateInventory(0, 1), true);
164             Assert.AreEqual(monster.MutateInventory(1, 2), true);
165             Assert.AreEqual(monster.MutateInventory(2, 3), true);
166             Assert.AreEqual(monster.MutateInventory(3, 4), true);
167             Assert.AreEqual(monster.MutateInventory(4, 5), true);
168 
169             for (int i = 0; i < monster.InventoryLength; i++)
170             {
171                 Assert.AreEqual(monster.Inventory(i), i + 1);
172             }
173 
174             //reverse mutation
175             Assert.AreEqual(monster.MutateInventory(0, 0), true);
176             Assert.AreEqual(monster.MutateInventory(1, 1), true);
177             Assert.AreEqual(monster.MutateInventory(2, 2), true);
178             Assert.AreEqual(monster.MutateInventory(3, 3), true);
179             Assert.AreEqual(monster.MutateInventory(4, 4), true);
180 
181             // get a struct field and edit one of its fields
182             Vec3 pos = (Vec3)monster.Pos;
183             Assert.AreEqual(pos.X, 1.0f);
184             pos.MutateX(55.0f);
185             Assert.AreEqual(pos.X, 55.0f);
186             pos.MutateX(1.0f);
187             Assert.AreEqual(pos.X, 1.0f);
188 
189             TestBuffer(dataBuffer);
190             TestObjectAPI(Monster.GetRootAsMonster(dataBuffer));
191         }
192 
TestBuffer(ByteBuffer bb)193         private void TestBuffer(ByteBuffer bb)
194         {
195             Monster monster = Monster.GetRootAsMonster(bb);
196 
197             Assert.AreEqual(80, monster.Hp);
198             Assert.AreEqual(150, monster.Mana);
199             Assert.AreEqual("MyMonster", monster.Name);
200 
201             var pos = monster.Pos.Value;
202             Assert.AreEqual(1.0f, pos.X);
203             Assert.AreEqual(2.0f, pos.Y);
204             Assert.AreEqual(3.0f, pos.Z);
205 
206             Assert.AreEqual(3.0f, pos.Test1);
207             Assert.AreEqual(Color.Green, pos.Test2);
208             var t = (MyGame.Example.Test)pos.Test3;
209             Assert.AreEqual((short)5, t.A);
210             Assert.AreEqual((sbyte)6, t.B);
211 
212             Assert.AreEqual(Any.Monster, monster.TestType);
213 
214             var monster2 = monster.Test<Monster>().Value;
215             Assert.AreEqual("Fred", monster2.Name);
216 
217 
218             Assert.AreEqual(5, monster.InventoryLength);
219             var invsum = 0;
220             for (var i = 0; i < monster.InventoryLength; i++)
221             {
222                 invsum += monster.Inventory(i);
223             }
224             Assert.AreEqual(10, invsum);
225 
226             // Get the inventory as an array and subtract the
227             // sum to get it back to 0
228             var inventoryArray = monster.GetInventoryArray();
229             Assert.AreEqual(5, inventoryArray.Length);
230             foreach(var inv in inventoryArray)
231             {
232                 invsum -= inv;
233             }
234             Assert.AreEqual(0, invsum);
235 
236             var test0 = monster.Test4(0).Value;
237             var test1 = monster.Test4(1).Value;
238             Assert.AreEqual(2, monster.Test4Length);
239 
240             Assert.AreEqual(100, test0.A + test0.B + test1.A + test1.B);
241 
242             Assert.AreEqual(2, monster.TestarrayofstringLength);
243             Assert.AreEqual("test1", monster.Testarrayofstring(0));
244             Assert.AreEqual("test2", monster.Testarrayofstring(1));
245 
246             Assert.AreEqual(true, monster.Testbool);
247 
248             #if ENABLE_SPAN_T
249             var nameBytes = monster.GetNameBytes();
250             Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.ToArray(), 0, nameBytes.Length));
251 
252             if (0 == monster.TestarrayofboolsLength)
253             {
254                 Assert.IsFalse(monster.GetTestarrayofboolsBytes().Length != 0);
255             }
256             else
257             {
258                 Assert.IsTrue(monster.GetTestarrayofboolsBytes().Length != 0);
259             }
260 
261             var longArrayBytes = monster.GetVectorOfLongsBytes();
262             Assert.IsTrue(monster.VectorOfLongsLength * 8 == longArrayBytes.Length);
263 
264             var doubleArrayBytes = monster.GetVectorOfDoublesBytes();
265             Assert.IsTrue(monster.VectorOfDoublesLength * 8 == doubleArrayBytes.Length);
266             #else
267             var nameBytes = monster.GetNameBytes().Value;
268             Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count));
269 
270             if (0 == monster.TestarrayofboolsLength)
271             {
272                 Assert.IsFalse(monster.GetTestarrayofboolsBytes().HasValue);
273             }
274             else
275             {
276                 Assert.IsTrue(monster.GetTestarrayofboolsBytes().HasValue);
277             }
278             #endif
279         }
280 
281         [FlatBuffersTestMethod]
CanReadCppGeneratedWireFile()282         public void CanReadCppGeneratedWireFile()
283         {
284             var data = File.ReadAllBytes(@"Resources/monsterdata_test.mon");
285             var bb = new ByteBuffer(data);
286             TestBuffer(bb);
287             TestObjectAPI(Monster.GetRootAsMonster(bb));
288         }
289 
290         [FlatBuffersTestMethod]
CanReadJsonFile()291         public void CanReadJsonFile()
292         {
293             var jsonText = File.ReadAllText(@"Resources/monsterdata_test.json");
294             var mon = MonsterT.DeserializeFromJson(jsonText);
295             var fbb = new FlatBufferBuilder(1);
296             fbb.Finish(Monster.Pack(fbb, mon).Value);
297             TestBuffer(fbb.DataBuffer);
298         }
299 
300         [FlatBuffersTestMethod]
TestEnums()301         public void TestEnums()
302         {
303             Assert.AreEqual("Red", Color.Red.ToString());
304             Assert.AreEqual("Blue", Color.Blue.ToString());
305             Assert.AreEqual("NONE", Any.NONE.ToString());
306             Assert.AreEqual("Monster", Any.Monster.ToString());
307         }
308 
309         [FlatBuffersTestMethod]
TestVectorOfEnums()310         public void TestVectorOfEnums()
311         {
312             const string monsterName = "TestVectorOfEnumsMonster";
313             var colorVec = new Color[] { Color.Red, Color.Green, Color.Blue };
314             var fbb = new FlatBufferBuilder(32);
315             var str1 = fbb.CreateString(monsterName);
316             var vec1 = Monster.CreateVectorOfEnumsVector(fbb, colorVec);
317             Monster.StartMonster(fbb);
318             Monster.AddName(fbb, str1);
319             Monster.AddVectorOfEnums(fbb, vec1);
320             var monster1 = Monster.EndMonster(fbb);
321             Monster.FinishMonsterBuffer(fbb, monster1);
322 
323             var mons = Monster.GetRootAsMonster(fbb.DataBuffer);
324             var colors = mons.GetVectorOfEnumsArray();
325             Assert.ArrayEqual(colorVec, colors);
326 
327             TestObjectAPI(mons);
328         }
329 
330         [FlatBuffersTestMethod]
TestNestedFlatBuffer()331         public void TestNestedFlatBuffer()
332         {
333             const string nestedMonsterName = "NestedMonsterName";
334             const short nestedMonsterHp = 600;
335             const short nestedMonsterMana = 1024;
336             // Create nested buffer as a Monster type
337             var fbb1 = new FlatBufferBuilder(16);
338             var str1 = fbb1.CreateString(nestedMonsterName);
339             Monster.StartMonster(fbb1);
340             Monster.AddName(fbb1, str1);
341             Monster.AddHp(fbb1, nestedMonsterHp);
342             Monster.AddMana(fbb1, nestedMonsterMana);
343             var monster1 = Monster.EndMonster(fbb1);
344             Monster.FinishMonsterBuffer(fbb1, monster1);
345             var fbb1Bytes = fbb1.SizedByteArray();
346             fbb1 = null;
347 
348             // Create a Monster which has the first buffer as a nested buffer
349             var fbb2 = new FlatBufferBuilder(16);
350             var str2 = fbb2.CreateString("My Monster");
351             var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
352             Monster.StartMonster(fbb2);
353             Monster.AddName(fbb2, str2);
354             Monster.AddHp(fbb2, 50);
355             Monster.AddMana(fbb2, 32);
356             Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
357             var monster = Monster.EndMonster(fbb2);
358             Monster.FinishMonsterBuffer(fbb2, monster);
359 
360             // Now test the data extracted from the nested buffer
361             var mons = Monster.GetRootAsMonster(fbb2.DataBuffer);
362             var nestedMonster = mons.GetTestnestedflatbufferAsMonster().Value;
363 
364             Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
365             Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
366             Assert.AreEqual(nestedMonsterName, nestedMonster.Name);
367 
368             TestObjectAPI(mons);
369             TestObjectAPI(nestedMonster);
370         }
371 
372         [FlatBuffersTestMethod]
TestFixedLenghtArrays()373         public void TestFixedLenghtArrays()
374         {
375             FlatBufferBuilder builder = new FlatBufferBuilder(100);
376 
377             float   a;
378             int[]   b = new int[15];
379             sbyte   c;
380             int[,]  d_a = new int[2, 2];
381             TestEnum[]  d_b = new TestEnum[2];
382             TestEnum[,] d_c = new TestEnum[2, 2];
383             long[,]     d_d = new long[2, 2];
384             int         e;
385             long[]      f = new long[2];
386 
387             a = 0.5f;
388             for (int i = 0; i < 15; i++) b[i] = i;
389             c = 1;
390             d_a[0, 0] = 1;
391             d_a[0, 1] = 2;
392             d_a[1, 0] = 3;
393             d_a[1, 1] = 4;
394             d_b[0] = TestEnum.B;
395             d_b[1] = TestEnum.C;
396             d_c[0, 0] = TestEnum.A;
397             d_c[0, 1] = TestEnum.B;
398             d_c[1, 0] = TestEnum.C;
399             d_c[1, 1] = TestEnum.B;
400             d_d[0, 0] = -1;
401             d_d[0, 1] = 1;
402             d_d[1, 0] = -2;
403             d_d[1, 1] = 2;
404             e = 2;
405             f[0] = -1;
406             f[1] = 1;
407 
408             Offset<ArrayStruct> arrayOffset = ArrayStruct.CreateArrayStruct(
409                 builder, a, b, c, d_a, d_b, d_c, d_d, e, f);
410 
411             // Create a table with the ArrayStruct.
412             ArrayTable.StartArrayTable(builder);
413             ArrayTable.AddA(builder, arrayOffset);
414             Offset<ArrayTable> tableOffset = ArrayTable.EndArrayTable(builder);
415 
416             ArrayTable.FinishArrayTableBuffer(builder, tableOffset);
417 
418             ArrayTable table = ArrayTable.GetRootAsArrayTable(builder.DataBuffer);
419 
420             Assert.AreEqual(table.A.Value.A, 0.5f);
421             for (int i = 0; i < 15; i++) Assert.AreEqual(table.A.Value.B(i), i);
422             Assert.AreEqual(table.A.Value.C, (sbyte)1);
423             Assert.AreEqual(table.A.Value.D(0).A(0), 1);
424             Assert.AreEqual(table.A.Value.D(0).A(1), 2);
425             Assert.AreEqual(table.A.Value.D(1).A(0), 3);
426             Assert.AreEqual(table.A.Value.D(1).A(1), 4);
427             Assert.AreEqual(table.A.Value.D(0).B, TestEnum.B);
428             Assert.AreEqual(table.A.Value.D(1).B, TestEnum.C);
429             Assert.AreEqual(table.A.Value.D(0).C(0), TestEnum.A);
430             Assert.AreEqual(table.A.Value.D(0).C(1), TestEnum.B);
431             Assert.AreEqual(table.A.Value.D(1).C(0), TestEnum.C);
432             Assert.AreEqual(table.A.Value.D(1).C(1), TestEnum.B);
433             Assert.AreEqual(table.A.Value.D(0).D(0), -1);
434             Assert.AreEqual(table.A.Value.D(0).D(1), 1);
435             Assert.AreEqual(table.A.Value.D(1).D(0), -2);
436             Assert.AreEqual(table.A.Value.D(1).D(1), 2);
437             Assert.AreEqual(table.A.Value.E, 2);
438             Assert.AreEqual(table.A.Value.F(0), -1);
439             Assert.AreEqual(table.A.Value.F(1), 1);
440 
441             TestObjectAPI(table);
442         }
443 
444         [FlatBuffersTestMethod]
TestUnionVector()445         public void TestUnionVector()
446         {
447             var fbb = new FlatBufferBuilder(100);
448             var rapunzel = Rapunzel.CreateRapunzel(fbb, 40).Value;
449 
450             var characterTypes = new[]
451             {
452                 Character.MuLan,
453                 Character.Belle,
454                 Character.Other,
455             };
456             var characterTypesOffset = Movie.CreateCharactersTypeVector(fbb, characterTypes);
457 
458             var characters = new[]
459             {
460                 Attacker.CreateAttacker(fbb, 10).Value,
461                 BookReader.CreateBookReader(fbb, 20).Value,
462                 fbb.CreateSharedString("Chip").Value,
463             };
464             var charactersOffset = Movie.CreateCharactersVector(fbb, characters);
465 
466             var movieOffset = Movie.CreateMovie(
467                 fbb,
468                 Character.Rapunzel,
469                 rapunzel,
470                 characterTypesOffset,
471                 charactersOffset);
472             Movie.FinishMovieBuffer(fbb, movieOffset);
473 
474             var movie = Movie.GetRootAsMovie(fbb.DataBuffer);
475             Assert.AreEqual(Character.Rapunzel, movie.MainCharacterType);
476             Assert.AreEqual(40, movie.MainCharacter<Rapunzel>().Value.HairLength);
477 
478             Assert.AreEqual(3, movie.CharactersLength);
479             Assert.AreEqual(Character.MuLan, movie.CharactersType(0));
480             Assert.AreEqual(10, movie.Characters<Attacker>(0).Value.SwordAttackDamage);
481             Assert.AreEqual(Character.Belle, movie.CharactersType(1));
482             Assert.AreEqual(20, movie.Characters<BookReader>(1).Value.BooksRead);
483             Assert.AreEqual(Character.Other, movie.CharactersType(2));
484             Assert.AreEqual("Chip", movie.CharactersAsString(2));
485 
486             TestObjectAPI(movie);
487         }
488 
AreEqual(Monster a, MonsterT b)489         private void AreEqual(Monster a, MonsterT b)
490         {
491             Assert.AreEqual(a.Hp, b.Hp);
492             Assert.AreEqual(a.Mana, b.Mana);
493             Assert.AreEqual(a.Name, b.Name);
494 
495             var posA = a.Pos;
496             var posB = b.Pos;
497             if (posA != null)
498             {
499                 Assert.AreEqual(posA.Value.X, posB.X);
500                 Assert.AreEqual(posA.Value.Y, posB.Y);
501                 Assert.AreEqual(posA.Value.Z, posB.Z);
502 
503                 Assert.AreEqual(posA.Value.Test1, posB.Test1);
504                 Assert.AreEqual(posA.Value.Test2, posB.Test2);
505                 var tA = posA.Value.Test3;
506                 var tB = posB.Test3;
507                 Assert.AreEqual(tA.A, tB.A);
508                 Assert.AreEqual(tA.B, tB.B);
509             }
510 
511             Assert.AreEqual(a.TestType, b.Test.Type);
512             if (a.TestType == Any.Monster)
513             {
514                 var monster2A = a.Test<Monster>().Value;
515                 var monster2B = b.Test.AsMonster();
516                 Assert.AreEqual(monster2A.Name, monster2B.Name);
517             }
518 
519             Assert.AreEqual(a.InventoryLength, b.Inventory.Count);
520             for (var i = 0; i < a.InventoryLength; ++i)
521             {
522                 Assert.AreEqual(a.Inventory(i), b.Inventory[i]);
523             }
524 
525             var inventoryArray = a.GetInventoryArray();
526             var inventoryArrayLength = inventoryArray == null ? 0 : inventoryArray.Length;
527             Assert.AreEqual(inventoryArrayLength, b.Inventory.Count);
528             for (var i = 0; i < inventoryArrayLength; ++i)
529             {
530                 Assert.AreEqual(inventoryArray[i], b.Inventory[i]);
531             }
532 
533             Assert.AreEqual(a.Test4Length, b.Test4.Count);
534             for (var i = 0; i < a.Test4Length; ++i)
535             {
536                 var t4A = a.Test4(i);
537                 var t4B = b.Test4[i];
538                 Assert.AreEqual(t4A.Value.A, t4B.A);
539                 Assert.AreEqual(t4A.Value.B, t4B.B);
540             }
541 
542             Assert.AreEqual(a.TestarrayofstringLength, b.Testarrayofstring.Count);
543             for (var i = 0; i < a.TestarrayofstringLength; ++i)
544             {
545                 Assert.AreEqual(a.Testarrayofstring(i), b.Testarrayofstring[i]);
546             }
547 
548             Assert.AreEqual(a.Testbool, b.Testbool);
549 
550             Assert.AreEqual(a.TestarrayofboolsLength, b.Testarrayofbools.Count);
551             for (var i = 0; i < a.TestarrayofboolsLength; ++i)
552             {
553                 Assert.AreEqual(a.Testarrayofbools(i), b.Testarrayofbools[i]);
554             }
555 
556             Assert.AreEqual(a.VectorOfLongsLength, b.VectorOfLongs.Count);
557             for (var i = 0; i < a.VectorOfLongsLength; ++i)
558             {
559                 Assert.AreEqual(a.VectorOfLongs(i), b.VectorOfLongs[i]);
560             }
561 
562             Assert.AreEqual(a.VectorOfDoublesLength, b.VectorOfDoubles.Count);
563             for (var i = 0; i < a.VectorOfDoublesLength; ++i)
564             {
565                 Assert.AreEqual(a.VectorOfDoubles(i), b.VectorOfDoubles[i]);
566             }
567 
568             Assert.AreEqual(a.VectorOfEnumsLength, b.VectorOfEnums.Count);
569             for (var i = 0; i < a.VectorOfEnumsLength; ++i)
570             {
571                 Assert.AreEqual(a.VectorOfEnums(i), b.VectorOfEnums[i]);
572             }
573         }
574 
AreEqual(Monster a, Monster b)575         private void AreEqual(Monster a, Monster b)
576         {
577             Assert.AreEqual(a.Hp, b.Hp);
578             Assert.AreEqual(a.Mana, b.Mana);
579             Assert.AreEqual(a.Name, b.Name);
580 
581             var posA = a.Pos;
582             var posB = b.Pos;
583             if (posA != null)
584             {
585                 Assert.AreEqual(posA.Value.X, posB.Value.X);
586                 Assert.AreEqual(posA.Value.Y, posB.Value.Y);
587                 Assert.AreEqual(posA.Value.Z, posB.Value.Z);
588 
589                 Assert.AreEqual(posA.Value.Test1, posB.Value.Test1);
590                 Assert.AreEqual(posA.Value.Test2, posB.Value.Test2);
591                 var tA = posA.Value.Test3;
592                 var tB = posB.Value.Test3;
593                 Assert.AreEqual(tA.A, tB.A);
594                 Assert.AreEqual(tA.B, tB.B);
595             }
596 
597             Assert.AreEqual(a.TestType, b.TestType);
598             if (a.TestType == Any.Monster)
599             {
600                 var monster2A = a.Test<Monster>().Value;
601                 var monster2B = b.Test<Monster>().Value;
602                 Assert.AreEqual(monster2A.Name, monster2B.Name);
603             }
604 
605             Assert.AreEqual(a.InventoryLength, b.InventoryLength);
606             for (var i = 0; i < a.InventoryLength; ++i)
607             {
608                 Assert.AreEqual(a.Inventory(i), b.Inventory(i));
609             }
610 
611             var inventoryArrayA = a.GetInventoryArray();
612             var inventoryArrayALength = inventoryArrayA == null ? 0 : inventoryArrayA.Length;
613             var inventoryArrayB = b.GetInventoryArray();
614             var inventoryArrayBLength = inventoryArrayB == null ? 0 : inventoryArrayB.Length;
615             Assert.AreEqual(inventoryArrayALength, inventoryArrayBLength);
616             for (var i = 0; i < inventoryArrayALength; ++i)
617             {
618                 Assert.AreEqual(inventoryArrayA[i], inventoryArrayB[i]);
619             }
620 
621             Assert.AreEqual(a.Test4Length, b.Test4Length);
622             for (var i = 0; i < a.Test4Length; ++i)
623             {
624                 var t4A = a.Test4(i);
625                 var t4B = b.Test4(i);
626                 Assert.AreEqual(t4A.Value.A, t4B.Value.A);
627                 Assert.AreEqual(t4A.Value.B, t4B.Value.B);
628             }
629 
630             Assert.AreEqual(a.TestarrayofstringLength, b.TestarrayofstringLength);
631             for (var i = 0; i < a.TestarrayofstringLength; ++i)
632             {
633                 Assert.AreEqual(a.Testarrayofstring(i), b.Testarrayofstring(i));
634             }
635 
636             Assert.AreEqual(a.Testbool, b.Testbool);
637 
638             Assert.AreEqual(a.TestarrayofboolsLength, b.TestarrayofboolsLength);
639             for (var i = 0; i < a.TestarrayofboolsLength; ++i)
640             {
641                 Assert.AreEqual(a.Testarrayofbools(i), b.Testarrayofbools(i));
642             }
643 
644             Assert.AreEqual(a.VectorOfLongsLength, b.VectorOfLongsLength);
645             for (var i = 0; i < a.VectorOfLongsLength; ++i)
646             {
647                 Assert.AreEqual(a.VectorOfLongs(i), b.VectorOfLongs(i));
648             }
649 
650             Assert.AreEqual(a.VectorOfDoublesLength, b.VectorOfDoublesLength);
651             for (var i = 0; i < a.VectorOfDoublesLength; ++i)
652             {
653                 Assert.AreEqual(a.VectorOfDoubles(i), b.VectorOfDoubles(i));
654             }
655 
656             Assert.AreEqual(a.VectorOfEnumsLength, b.VectorOfEnumsLength);
657             for (var i = 0; i < a.VectorOfEnumsLength; ++i)
658             {
659                 Assert.AreEqual(a.VectorOfEnums(i), b.VectorOfEnums(i));
660             }
661         }
662 
TestObjectAPI(Monster a)663         private void TestObjectAPI(Monster a)
664         {
665             var b = a.UnPack();
666             AreEqual(a, b);
667 
668             var fbb = new FlatBufferBuilder(1);
669             fbb.Finish(Monster.Pack(fbb, b).Value);
670             var c = Monster.GetRootAsMonster(fbb.DataBuffer);
671             AreEqual(a, c);
672 
673             var jsonText = b.SerializeToJson();
674             var d = MonsterT.DeserializeFromJson(jsonText);
675             AreEqual(a, d);
676 
677             var fbBuffer = b.SerializeToBinary();
678             var e = MonsterT.DeserializeFromBinary(fbBuffer);
679             AreEqual(a, e);
680         }
681 
AreEqual(ArrayTable a, ArrayTableT b)682         private void AreEqual(ArrayTable a, ArrayTableT b)
683         {
684             Assert.AreEqual(a.A.Value.A, b.A.A);
685 
686             for (int i = 0; i < 15; ++i)
687             {
688                 Assert.AreEqual(a.A.Value.B(i), b.A.B[i]);
689             }
690 
691             Assert.AreEqual(a.A.Value.C, b.A.C);
692 
693             for (int i = 0; i < 2; ++i)
694             {
695                 var ad = a.A.Value.D(i);
696                 var bd = b.A.D[i];
697 
698                 for (int j = 0; j < 2; ++j)
699                 {
700                     Assert.AreEqual(ad.A(j), bd.A[j]);
701                 }
702 
703                 Assert.AreEqual(ad.B, bd.B);
704 
705                 for (int j = 0; j < 2; ++j)
706                 {
707                     Assert.AreEqual(ad.C(j), bd.C[j]);
708                 }
709 
710                 for (int j = 0; j < 2; ++j)
711                 {
712                     Assert.AreEqual(ad.D(j), bd.D[j]);
713                 }
714             }
715 
716             Assert.AreEqual(a.A.Value.E, b.A.E);
717 
718             for (int i = 0; i < 2; ++i)
719             {
720                 Assert.AreEqual(a.A.Value.F(i), b.A.F[i]);
721             }
722         }
723 
AreEqual(ArrayTable a, ArrayTable b)724         private void AreEqual(ArrayTable a, ArrayTable b)
725         {
726             Assert.AreEqual(a.A.Value.A, b.A.Value.A);
727 
728             for (int i = 0; i < 15; ++i)
729             {
730                 Assert.AreEqual(a.A.Value.B(i), b.A.Value.B(i));
731             }
732 
733             Assert.AreEqual(a.A.Value.C, b.A.Value.C);
734 
735             for (int i = 0; i < 2; ++i)
736             {
737                 var ad = a.A.Value.D(i);
738                 var bd = b.A.Value.D(i);
739 
740                 for (int j = 0; j < 2; ++j)
741                 {
742                     Assert.AreEqual(ad.A(j), bd.A(j));
743                 }
744 
745                 Assert.AreEqual(ad.B, bd.B);
746 
747                 for (int j = 0; j < 2; ++j)
748                 {
749                     Assert.AreEqual(ad.C(j), bd.C(j));
750                 }
751 
752                 for (int j = 0; j < 2; ++j)
753                 {
754                     Assert.AreEqual(ad.D(j), bd.D(j));
755                 }
756             }
757 
758             Assert.AreEqual(a.A.Value.E, b.A.Value.E);
759 
760             for (int i = 0; i < 2; ++i)
761             {
762                 Assert.AreEqual(a.A.Value.F(i), b.A.Value.F(i));
763             }
764         }
765 
TestObjectAPI(ArrayTable a)766         private void TestObjectAPI(ArrayTable a)
767         {
768             var b = a.UnPack();
769             AreEqual(a, b);
770 
771             var fbb = new FlatBufferBuilder(1);
772             fbb.Finish(ArrayTable.Pack(fbb, b).Value);
773             var c = ArrayTable.GetRootAsArrayTable(fbb.DataBuffer);
774             AreEqual(a, c);
775 
776             var jsonText = b.SerializeToJson();
777             var d = ArrayTableT.DeserializeFromJson(jsonText);
778             AreEqual(a, d);
779 
780             var fbBuffer = b.SerializeToBinary();
781             var e = ArrayTableT.DeserializeFromBinary(fbBuffer);
782             AreEqual(a, e);
783         }
784 
AreEqual(Movie a, MovieT b)785         private void AreEqual(Movie a, MovieT b)
786         {
787             Assert.AreEqual(a.MainCharacterType, b.MainCharacter.Type);
788             Assert.AreEqual(a.MainCharacter<Rapunzel>().Value.HairLength, b.MainCharacter.AsRapunzel().HairLength);
789 
790             Assert.AreEqual(a.CharactersLength, b.Characters.Count);
791             Assert.AreEqual(a.CharactersType(0), b.Characters[0].Type);
792             Assert.AreEqual(a.Characters<Attacker>(0).Value.SwordAttackDamage, b.Characters[0].AsMuLan().SwordAttackDamage);
793             Assert.AreEqual(a.CharactersType(1), b.Characters[1].Type);
794             Assert.AreEqual(a.Characters<BookReader>(1).Value.BooksRead, b.Characters[1].AsBelle().BooksRead);
795             Assert.AreEqual(a.CharactersType(2), b.Characters[2].Type);
796             Assert.AreEqual(a.CharactersAsString(2), b.Characters[2].AsOther());
797         }
798 
AreEqual(Movie a, Movie b)799         private void AreEqual(Movie a, Movie b)
800         {
801             Assert.AreEqual(a.MainCharacterType, b.MainCharacterType);
802             Assert.AreEqual(a.MainCharacter<Rapunzel>().Value.HairLength, b.MainCharacter<Rapunzel>().Value.HairLength);
803 
804             Assert.AreEqual(a.CharactersLength, b.CharactersLength);
805             Assert.AreEqual(a.CharactersType(0), b.CharactersType(0));
806             Assert.AreEqual(a.Characters<Attacker>(0).Value.SwordAttackDamage, b.Characters<Attacker>(0).Value.SwordAttackDamage);
807             Assert.AreEqual(a.CharactersType(1), b.CharactersType(1));
808             Assert.AreEqual(a.Characters<BookReader>(1).Value.BooksRead, b.Characters<BookReader>(1).Value.BooksRead);
809             Assert.AreEqual(a.CharactersType(2), b.CharactersType(2));
810             Assert.AreEqual(a.CharactersAsString(2), b.CharactersAsString(2));
811         }
812 
TestObjectAPI(Movie a)813         private void TestObjectAPI(Movie a)
814         {
815             var b = a.UnPack();
816             AreEqual(a, b);
817 
818             var fbb = new FlatBufferBuilder(1);
819             fbb.Finish(Movie.Pack(fbb, b).Value);
820             var c = Movie.GetRootAsMovie(fbb.DataBuffer);
821             AreEqual(a, c);
822 
823             var jsonText = b.SerializeToJson();
824             var d = MovieT.DeserializeFromJson(jsonText);
825             AreEqual(a, d);
826 
827             var fbBuffer = b.SerializeToBinary();
828             var e = MovieT.DeserializeFromBinary(fbBuffer);
829             AreEqual(a, e);
830         }
831     }
832 }
833