1# coding=utf-8
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
16import os.path
17import sys
18import imp
19PY_VERSION = sys.version_info[:2]
20
21import ctypes
22from collections import defaultdict
23import math
24import random
25import timeit
26import unittest
27
28from flatbuffers import compat
29from flatbuffers import util
30from flatbuffers.compat import range_func as compat_range
31from flatbuffers.compat import NumpyRequiredForThisFeature
32
33import flatbuffers
34from flatbuffers import number_types as N
35
36import MyGame  # refers to generated code
37import MyGame.Example  # refers to generated code
38import MyGame.Example.Any  # refers to generated code
39import MyGame.Example.Color  # refers to generated code
40import MyGame.Example.Monster  # refers to generated code
41import MyGame.Example.Test  # refers to generated code
42import MyGame.Example.Stat  # refers to generated code
43import MyGame.Example.Vec3  # refers to generated code
44import MyGame.MonsterExtra  # refers to generated code
45import MyGame.InParentNamespace # refers to generated code
46import MyGame.Example.ArrayTable  # refers to generated code
47import MyGame.Example.ArrayStruct  # refers to generated code
48import MyGame.Example.NestedStruct  # refers to generated code
49import MyGame.Example.TestEnum  # refers to generated code
50
51def assertRaises(test_case, fn, exception_class):
52    ''' Backwards-compatible assertion for exceptions raised. '''
53
54    exc = None
55    try:
56        fn()
57    except Exception as e:
58        exc = e
59    test_case.assertTrue(exc is not None)
60    test_case.assertTrue(isinstance(exc, exception_class))
61
62
63class TestWireFormat(unittest.TestCase):
64    def test_wire_format(self):
65        # Verify that using the generated Python code builds a buffer without
66        # returning errors, and is interpreted correctly, for size prefixed
67        # representation and regular:
68        for sizePrefix in [True, False]:
69            for file_identifier in [None, b"MONS"]:
70                gen_buf, gen_off = make_monster_from_generated_code(sizePrefix=sizePrefix, file_identifier=file_identifier)
71                CheckReadBuffer(gen_buf, gen_off, sizePrefix=sizePrefix, file_identifier=file_identifier)
72
73        # Verify that the canonical flatbuffer file is readable by the
74        # generated Python code. Note that context managers are not part of
75        # Python 2.5, so we use the simpler open/close methods here:
76        f = open('monsterdata_test.mon', 'rb')
77        canonicalWireData = f.read()
78        f.close()
79        CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
80
81        # Write the generated buffer out to a file:
82        f = open('monsterdata_python_wire.mon', 'wb')
83        f.write(gen_buf[gen_off:])
84        f.close()
85
86
87class TestObjectBasedAPI(unittest.TestCase):
88    ''' Tests the generated object based API.'''
89
90    def test_consistenty_with_repeated_pack_and_unpack(self):
91        ''' Checks the serialization and deserialization between a buffer and
92        its python object. It tests in the same way as the C++ object API test,
93        ObjectFlatBuffersTest in test.cpp. '''
94
95        buf, off = make_monster_from_generated_code()
96
97        # Turns a buffer into Python object (T class).
98        monster1 = MyGame.Example.Monster.Monster.GetRootAs(buf, off)
99        monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
100
101        for sizePrefix in [True, False]:
102            # Re-serialize the data into a buffer.
103            b1 = flatbuffers.Builder(0)
104            if sizePrefix:
105                b1.FinishSizePrefixed(monsterT1.Pack(b1))
106            else:
107                b1.Finish(monsterT1.Pack(b1))
108            CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
109
110        # Deserializes the buffer into Python object again.
111        monster2 = MyGame.Example.Monster.Monster.GetRootAs(b1.Bytes,
112                                                                   b1.Head())
113        # Re-serializes the data into a buffer for one more time.
114        monsterT2 = MyGame.Example.Monster.MonsterT.InitFromObj(monster2)
115        for sizePrefix in [True, False]:
116            # Re-serializes the data into a buffer
117            b2 = flatbuffers.Builder(0)
118            if sizePrefix:
119                b2.FinishSizePrefixed(monsterT2.Pack(b2))
120            else:
121                b2.Finish(monsterT2.Pack(b2))
122            CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
123
124    def test_default_values_with_pack_and_unpack(self):
125        ''' Serializes and deserializes between a buffer with default values (no
126        specific values are filled when the buffer is created) and its python
127        object. '''
128        # Creates a flatbuffer with default values.
129        b1 = flatbuffers.Builder(0)
130        MyGame.Example.Monster.Start(b1)
131        gen_mon = MyGame.Example.Monster.End(b1)
132        b1.Finish(gen_mon)
133
134        # Converts the flatbuffer into the object class.
135        monster1 = MyGame.Example.Monster.Monster.GetRootAs(b1.Bytes,
136                                                                   b1.Head())
137        monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
138
139        # Packs the object class into another flatbuffer.
140        b2 = flatbuffers.Builder(0)
141        b2.Finish(monsterT1.Pack(b2))
142        monster2 = MyGame.Example.Monster.Monster.GetRootAs(b2.Bytes,
143                                                                   b2.Head())
144        # Checks the default values.
145        self.assertTrue(monster2.Pos() is None)
146        self.assertEqual(monster2.Mana(),150)
147        self.assertEqual(monster2.Hp(), 100)
148        self.assertTrue(monster2.Name() is None)
149        self.assertEqual(monster2.Inventory(0), 0)
150        self.assertEqual(monster2.InventoryAsNumpy(), 0)
151        self.assertEqual(monster2.InventoryLength(), 0)
152        self.assertTrue(monster2.InventoryIsNone())
153        self.assertTrue(monster2.Color() is 8)
154        self.assertEqual(monster2.TestType(), 0)
155        self.assertTrue(monster2.Test() is None)
156        self.assertTrue(monster2.Test4(0) is None)
157        self.assertEqual(monster2.Test4Length(), 0)
158        self.assertTrue(monster2.Test4IsNone())
159        self.assertTrue(monster2.Testarrayofstring(0) is "")
160        self.assertEqual(monster2.TestarrayofstringLength(), 0)
161        self.assertTrue(monster2.TestarrayofstringIsNone())
162        self.assertTrue(monster2.Testarrayoftables(0) is None)
163        self.assertEqual(monster2.TestarrayoftablesLength(), 0)
164        self.assertTrue(monster2.TestarrayoftablesIsNone())
165        self.assertTrue(monster2.Enemy() is None)
166        self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
167        self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
168        self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
169        self.assertTrue(monster2.TestnestedflatbufferIsNone())
170        self.assertTrue(monster2.Testempty() is None)
171        self.assertTrue(monster2.Testbool() is False)
172        self.assertEqual(monster2.Testhashs32Fnv1(), 0)
173        self.assertEqual(monster2.Testhashu32Fnv1(), 0)
174        self.assertEqual(monster2.Testhashs64Fnv1(), 0)
175        self.assertEqual(monster2.Testhashu64Fnv1(), 0)
176        self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
177        self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
178        self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
179        self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
180        self.assertEqual(monster2.Testarrayofbools(0), 0)
181        self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
182        self.assertEqual(monster2.TestarrayofboolsLength(), 0)
183        self.assertTrue(monster2.TestarrayofboolsIsNone())
184        self.assertEqual(monster2.Testf(), 3.14159)
185        self.assertEqual(monster2.Testf2(), 3.0)
186        self.assertEqual(monster2.Testf3(), 0.0)
187        self.assertTrue(monster2.Testarrayofstring2(0) is "")
188        self.assertEqual(monster2.Testarrayofstring2Length(), 0)
189        self.assertTrue(monster2.Testarrayofstring2IsNone())
190        self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
191        self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
192        self.assertTrue(monster2.TestarrayofsortedstructIsNone())
193        self.assertEqual(monster2.Flex(0), 0)
194        self.assertEqual(monster2.FlexAsNumpy(), 0)
195        self.assertEqual(monster2.FlexLength(), 0)
196        self.assertTrue(monster2.FlexIsNone())
197        self.assertTrue(monster2.Test5(0) is None)
198        self.assertEqual(monster2.Test5Length(), 0)
199        self.assertTrue(monster2.Test5IsNone())
200        self.assertEqual(monster2.VectorOfLongs(0), 0)
201        self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
202        self.assertEqual(monster2.VectorOfLongsLength(), 0)
203        self.assertTrue(monster2.VectorOfLongsIsNone())
204        self.assertEqual(monster2.VectorOfDoubles(0), 0)
205        self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
206        self.assertEqual(monster2.VectorOfDoublesLength(), 0)
207        self.assertTrue(monster2.VectorOfDoublesIsNone())
208        self.assertTrue(monster2.ParentNamespaceTest() is None)
209        self.assertTrue(monster2.VectorOfReferrables(0) is None)
210        self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
211        self.assertTrue(monster2.VectorOfReferrablesIsNone())
212        self.assertEqual(monster2.SingleWeakReference(), 0)
213        self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
214        self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
215        self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
216        self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
217        self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
218        self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
219        self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
220        self.assertEqual(monster2.CoOwningReference(), 0)
221        self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
222        self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
223        self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
224        self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
225        self.assertEqual(monster2.NonOwningReference(), 0)
226        self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
227        self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
228        self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
229        self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
230        self.assertEqual(monster2.AnyUniqueType(), 0)
231        self.assertTrue(monster2.AnyUnique() is None)
232        self.assertEqual(monster2.AnyAmbiguousType(), 0)
233        self.assertTrue(monster2.AnyAmbiguous() is None)
234        self.assertEqual(monster2.VectorOfEnums(0), 0)
235        self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
236        self.assertEqual(monster2.VectorOfEnumsLength(), 0)
237        self.assertTrue(monster2.VectorOfEnumsIsNone())
238
239
240class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
241    ''' Tests the object API generated for monster_test.fbs for mutation
242        purposes. In each test, the default values will be changed through the
243        object API. We'll then pack the object class into the buf class and read
244        the updated values out from it to validate if the values are mutated as
245        expected.'''
246
247    def setUp(self, *args, **kwargs):
248        super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args,
249                                                                  **kwargs)
250        # Creates an empty monster flatbuffer, and loads it into the object
251        # class for future tests.
252        b = flatbuffers.Builder(0)
253        MyGame.Example.Monster.Start(b)
254        self.monsterT = self._create_and_load_object_class(b)
255
256    def _pack_and_load_buf_class(self, monsterT):
257        ''' Packs the object class into a flatbuffer and loads it into a buf
258        class.'''
259        b = flatbuffers.Builder(0)
260        b.Finish(monsterT.Pack(b))
261        monster = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
262                                                                  b.Head())
263        return monster
264
265    def _create_and_load_object_class(self, b):
266        ''' Finishs the creation of a monster flatbuffer and loads it into an
267        object class.'''
268        gen_mon = MyGame.Example.Monster.End(b)
269        b.Finish(gen_mon)
270        monster = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
271                                                                  b.Head())
272        monsterT = MyGame.Example.Monster.MonsterT()
273        monsterT.InitFromObj(monster)
274        return monsterT
275
276    def test_mutate_pos(self):
277        posT = MyGame.Example.Vec3.Vec3T()
278        posT.x = 4.0
279        posT.y = 5.0
280        posT.z = 6.0
281        posT.test1 = 6.0
282        posT.test2 = 7
283        test3T = MyGame.Example.Test.TestT()
284        test3T.a = 8
285        test3T.b = 9
286        posT.test3 = test3T
287        self.monsterT.pos = posT
288
289        # Packs the updated values.
290        monster = self._pack_and_load_buf_class(self.monsterT)
291
292        # Checks if values are loaded correctly into the object class.
293        pos = monster.Pos()
294
295        # Verifies the properties of the Vec3.
296        self.assertEqual(pos.X(), 4.0)
297        self.assertEqual(pos.Y(), 5.0)
298        self.assertEqual(pos.Z(), 6.0)
299        self.assertEqual(pos.Test1(), 6.0)
300        self.assertEqual(pos.Test2(), 7)
301        t3 = MyGame.Example.Test.Test()
302        t3 = pos.Test3(t3)
303        self.assertEqual(t3.A(), 8)
304        self.assertEqual(t3.B(), 9)
305
306    def test_mutate_mana(self):
307        self.monsterT.mana = 200
308        monster = self._pack_and_load_buf_class(self.monsterT)
309        self.assertEqual(monster.Mana(), 200)
310
311    def test_mutate_hp(self):
312        self.monsterT.hp = 200
313        monster = self._pack_and_load_buf_class(self.monsterT)
314        self.assertEqual(monster.Hp(), 200)
315
316    def test_mutate_name(self):
317        self.monsterT.name = "MyMonster"
318        monster = self._pack_and_load_buf_class(self.monsterT)
319        self.assertEqual(monster.Name(), b"MyMonster")
320
321    def test_mutate_inventory(self):
322        self.monsterT.inventory = [1, 7, 8]
323        monster = self._pack_and_load_buf_class(self.monsterT)
324        self.assertEqual(monster.Inventory(0), 1)
325        self.assertEqual(monster.Inventory(1), 7)
326        self.assertEqual(monster.Inventory(2), 8)
327
328    def test_empty_inventory(self):
329        self.monsterT.inventory = []
330        monster = self._pack_and_load_buf_class(self.monsterT)
331        self.assertFalse(monster.InventoryIsNone())
332
333    def test_mutate_color(self):
334        self.monsterT.color = MyGame.Example.Color.Color.Red
335        monster = self._pack_and_load_buf_class(self.monsterT)
336        self.assertEqual(monster.Color(), MyGame.Example.Color.Color.Red)
337
338    def test_mutate_testtype(self):
339        self.monsterT.testType = MyGame.Example.Any.Any.Monster
340        monster = self._pack_and_load_buf_class(self.monsterT)
341        self.assertEqual(monster.TestType(), MyGame.Example.Any.Any.Monster)
342
343    def test_mutate_test(self):
344        testT = MyGame.Example.Monster.MonsterT()
345        testT.hp = 200
346        self.monsterT.test = testT
347        monster = self._pack_and_load_buf_class(self.monsterT)
348        # Initializes a Table from a union field Test(...).
349        table = monster.Test()
350
351        # Initializes a Monster from the Table from the union.
352        test_monster = MyGame.Example.Monster.Monster()
353        test_monster.Init(table.Bytes, table.Pos)
354        self.assertEqual(test_monster.Hp(), 200)
355
356    def test_mutate_test4(self):
357        test0T = MyGame.Example.Test.TestT()
358        test0T.a = 10
359        test0T.b = 20
360        test1T = MyGame.Example.Test.TestT()
361        test1T.a = 30
362        test1T.b = 40
363        self.monsterT.test4 = [test0T, test1T]
364
365        monster = self._pack_and_load_buf_class(self.monsterT)
366        test0 = monster.Test4(0)
367        self.assertEqual(test0.A(), 10)
368        self.assertEqual(test0.B(), 20)
369        test1 = monster.Test4(1)
370        self.assertEqual(test1.A(), 30)
371        self.assertEqual(test1.B(), 40)
372
373    def test_empty_test4(self):
374        self.monsterT.test4 = []
375        monster = self._pack_and_load_buf_class(self.monsterT)
376        self.assertFalse(monster.Test4IsNone())
377
378    def test_mutate_testarrayofstring(self):
379        self.monsterT.testarrayofstring = []
380        self.monsterT.testarrayofstring.append("test1")
381        self.monsterT.testarrayofstring.append("test2")
382        monster = self._pack_and_load_buf_class(self.monsterT)
383        self.assertEqual(monster.Testarrayofstring(0), b"test1")
384        self.assertEqual(monster.Testarrayofstring(1), b"test2")
385
386    def test_empty_testarrayofstring(self):
387        self.monsterT.testarrayofstring = []
388        monster = self._pack_and_load_buf_class(self.monsterT)
389        self.assertFalse(monster.TestarrayofstringIsNone())
390
391    def test_mutate_testarrayoftables(self):
392        monsterT0 = MyGame.Example.Monster.MonsterT()
393        monsterT0.hp = 200
394        monsterT1 = MyGame.Example.Monster.MonsterT()
395        monsterT1.hp = 400
396        self.monsterT.testarrayoftables = []
397        self.monsterT.testarrayoftables.append(monsterT0)
398        self.monsterT.testarrayoftables.append(monsterT1)
399        monster = self._pack_and_load_buf_class(self.monsterT)
400        self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
401        self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
402
403    def test_empty_testarrayoftables(self):
404        self.monsterT.testarrayoftables = []
405        monster = self._pack_and_load_buf_class(self.monsterT)
406        self.assertFalse(monster.TestarrayoftablesIsNone())
407
408    def test_mutate_enemy(self):
409        monsterT = MyGame.Example.Monster.MonsterT()
410        monsterT.hp = 200
411        self.monsterT.enemy = monsterT
412        monster = self._pack_and_load_buf_class(self.monsterT)
413        self.assertEqual(monster.Enemy().Hp(), 200)
414
415    def test_mutate_testnestedflatbuffer(self):
416        self.monsterT.testnestedflatbuffer = [8, 2, 4]
417        monster = self._pack_and_load_buf_class(self.monsterT)
418        self.assertEqual(monster.Testnestedflatbuffer(0), 8)
419        self.assertEqual(monster.Testnestedflatbuffer(1), 2)
420        self.assertEqual(monster.Testnestedflatbuffer(2), 4)
421
422    def test_empty_testnestedflatbuffer(self):
423        self.monsterT.testnestedflatbuffer = []
424        monster = self._pack_and_load_buf_class(self.monsterT)
425        self.assertFalse(monster.TestnestedflatbufferIsNone())
426
427    def test_mutate_testbool(self):
428        self.monsterT.testbool = True
429        monster = self._pack_and_load_buf_class(self.monsterT)
430        self.assertTrue(monster.Testbool())
431
432    def test_mutate_testhashes(self):
433        self.monsterT.testhashs32Fnv1 = 1
434        self.monsterT.testhashu32Fnv1 = 2
435        self.monsterT.testhashs64Fnv1 = 3
436        self.monsterT.testhashu64Fnv1 = 4
437        self.monsterT.testhashs32Fnv1a = 5
438        self.monsterT.testhashu32Fnv1a = 6
439        self.monsterT.testhashs64Fnv1a = 7
440        self.monsterT.testhashu64Fnv1a = 8
441        monster = self._pack_and_load_buf_class(self.monsterT)
442        self.assertEqual(monster.Testhashs32Fnv1(), 1)
443        self.assertEqual(monster.Testhashu32Fnv1(), 2)
444        self.assertEqual(monster.Testhashs64Fnv1(), 3)
445        self.assertEqual(monster.Testhashu64Fnv1(), 4)
446        self.assertEqual(monster.Testhashs32Fnv1a(), 5)
447        self.assertEqual(monster.Testhashu32Fnv1a(), 6)
448        self.assertEqual(monster.Testhashs64Fnv1a(), 7)
449        self.assertEqual(monster.Testhashu64Fnv1a(), 8)
450
451    def test_mutate_testarrayofbools(self):
452        self.monsterT.testarrayofbools = []
453        self.monsterT.testarrayofbools.append(True)
454        self.monsterT.testarrayofbools.append(True)
455        self.monsterT.testarrayofbools.append(False)
456        monster = self._pack_and_load_buf_class(self.monsterT)
457        self.assertEqual(monster.Testarrayofbools(0), True)
458        self.assertEqual(monster.Testarrayofbools(1), True)
459        self.assertEqual(monster.Testarrayofbools(2), False)
460
461    def test_empty_testarrayofbools(self):
462        self.monsterT.testarrayofbools = []
463        monster = self._pack_and_load_buf_class(self.monsterT)
464        self.assertFalse(monster.TestarrayofboolsIsNone())
465
466    def test_mutate_testf(self):
467        self.monsterT.testf = 2.0
468        monster = self._pack_and_load_buf_class(self.monsterT)
469        self.assertEqual(monster.Testf(), 2.0)
470
471    def test_mutate_vectoroflongs(self):
472        self.monsterT.vectorOfLongs = []
473        self.monsterT.vectorOfLongs.append(1)
474        self.monsterT.vectorOfLongs.append(100)
475        self.monsterT.vectorOfLongs.append(10000)
476        self.monsterT.vectorOfLongs.append(1000000)
477        self.monsterT.vectorOfLongs.append(100000000)
478        monster = self._pack_and_load_buf_class(self.monsterT)
479        self.assertEqual(monster.VectorOfLongs(0), 1)
480        self.assertEqual(monster.VectorOfLongs(1), 100)
481        self.assertEqual(monster.VectorOfLongs(2), 10000)
482        self.assertEqual(monster.VectorOfLongs(3), 1000000)
483        self.assertEqual(monster.VectorOfLongs(4), 100000000)
484
485    def test_empty_vectoroflongs(self):
486        self.monsterT.vectorOfLongs = []
487        monster = self._pack_and_load_buf_class(self.monsterT)
488        self.assertFalse(monster.VectorOfLongsIsNone())
489
490    def test_mutate_vectorofdoubles(self):
491        self.monsterT.vectorOfDoubles = []
492        self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
493        self.monsterT.vectorOfDoubles.append(0)
494        self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
495        monster = self._pack_and_load_buf_class(self.monsterT)
496        self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
497        self.assertEqual(monster.VectorOfDoubles(1), 0)
498        self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
499
500    def test_empty_vectorofdoubles(self):
501        self.monsterT.vectorOfDoubles = []
502        monster = self._pack_and_load_buf_class(self.monsterT)
503        self.assertFalse(monster.VectorOfDoublesIsNone())
504
505    def test_mutate_parentnamespacetest(self):
506        self.monsterT.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT()
507        monster = self._pack_and_load_buf_class(self.monsterT)
508        self.assertTrue(isinstance(monster.ParentNamespaceTest(),
509                                   MyGame.InParentNamespace.InParentNamespace))
510
511    def test_mutate_vectorofEnums(self):
512        self.monsterT.vectorOfEnums = []
513        self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
514        self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Blue)
515        self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
516        monster = self._pack_and_load_buf_class(self.monsterT)
517        self.assertEqual(monster.VectorOfEnums(0),
518                         MyGame.Example.Color.Color.Red)
519        self.assertEqual(monster.VectorOfEnums(1),
520                         MyGame.Example.Color.Color.Blue)
521        self.assertEqual(monster.VectorOfEnums(2),
522                         MyGame.Example.Color.Color.Red)
523
524    def test_empty_vectorofEnums(self):
525        self.monsterT.vectorOfEnums = []
526        monster = self._pack_and_load_buf_class(self.monsterT)
527        self.assertFalse(monster.VectorOfEnumsIsNone())
528
529
530def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
531    ''' CheckReadBuffer checks that the given buffer is evaluated correctly
532        as the example Monster. '''
533
534    def asserter(stmt):
535        ''' An assertion helper that is separated from TestCase classes. '''
536        if not stmt:
537            raise AssertionError('CheckReadBuffer case failed')
538    if file_identifier:
539        # test prior to removal of size_prefix
540        asserter(util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) == file_identifier)
541        asserter(util.BufferHasIdentifier(buf, offset, file_identifier=file_identifier, size_prefixed=sizePrefix))
542        asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset, size_prefixed=sizePrefix))
543    if sizePrefix:
544        size = util.GetSizePrefix(buf, offset)
545        asserter(size == len(buf[offset:])-4)
546        buf, offset = util.RemoveSizePrefix(buf, offset)
547    if file_identifier:
548        asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
549    else:
550        asserter(not MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
551    monster = MyGame.Example.Monster.Monster.GetRootAs(buf, offset)
552
553    asserter(monster.Hp() == 80)
554    asserter(monster.Mana() == 150)
555    asserter(monster.Name() == b'MyMonster')
556
557    # initialize a Vec3 from Pos()
558    vec = monster.Pos()
559    asserter(vec is not None)
560
561    # verify the properties of the Vec3
562    asserter(vec.X() == 1.0)
563    asserter(vec.Y() == 2.0)
564    asserter(vec.Z() == 3.0)
565    asserter(vec.Test1() == 3.0)
566    asserter(vec.Test2() == 2)
567
568    # initialize a Test from Test3(...)
569    t = MyGame.Example.Test.Test()
570    t = vec.Test3(t)
571    asserter(t is not None)
572
573    # verify the properties of the Test
574    asserter(t.A() == 5)
575    asserter(t.B() == 6)
576
577    # verify that the enum code matches the enum declaration:
578    union_type = MyGame.Example.Any.Any
579    asserter(monster.TestType() == union_type.Monster)
580
581    # initialize a Table from a union field Test(...)
582    table2 = monster.Test()
583    asserter(type(table2) is flatbuffers.table.Table)
584
585    # initialize a Monster from the Table from the union
586    monster2 = MyGame.Example.Monster.Monster()
587    monster2.Init(table2.Bytes, table2.Pos)
588
589    asserter(monster2.Name() == b"Fred")
590
591    # iterate through the first monster's inventory:
592    asserter(monster.InventoryLength() == 5)
593    asserter(not monster.InventoryIsNone())
594
595    invsum = 0
596    for i in compat_range(monster.InventoryLength()):
597        v = monster.Inventory(i)
598        invsum += int(v)
599    asserter(invsum == 10)
600
601    for i in range(5):
602        asserter(monster.VectorOfLongs(i) == 10 ** (i * 2))
603
604    asserter(not monster.VectorOfDoublesIsNone())
605    asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308]
606              == [monster.VectorOfDoubles(i)
607                  for i in range(monster.VectorOfDoublesLength())]))
608
609    try:
610        imp.find_module('numpy')
611        # if numpy exists, then we should be able to get the
612        # vector as a numpy array
613        import numpy as np
614
615        asserter(monster.InventoryAsNumpy().sum() == 10)
616        asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
617
618        VectorOfLongs = monster.VectorOfLongsAsNumpy()
619        asserter(VectorOfLongs.dtype == np.dtype('int64'))
620        for i in range(5):
621            asserter(VectorOfLongs[i] == 10 ** (i * 2))
622
623        VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
624        asserter(VectorOfDoubles.dtype == np.dtype('float64'))
625        asserter(VectorOfDoubles[0] == np.finfo('float64').min)
626        asserter(VectorOfDoubles[1] == 0.0)
627        asserter(VectorOfDoubles[2] == np.finfo('float64').max)
628
629    except ImportError:
630        # If numpy does not exist, trying to get vector as numpy
631        # array should raise NumpyRequiredForThisFeature. The way
632        # assertRaises has been implemented prevents us from
633        # asserting this error is raised outside of a test case.
634        pass
635
636    asserter(monster.Test4Length() == 2)
637    asserter(not monster.Test4IsNone())
638
639    # create a 'Test' object and populate it:
640    test0 = monster.Test4(0)
641    asserter(type(test0) is MyGame.Example.Test.Test)
642
643    test1 = monster.Test4(1)
644    asserter(type(test1) is MyGame.Example.Test.Test)
645
646    # the position of test0 and test1 are swapped in monsterdata_java_wire
647    # and monsterdata_test_wire, so ignore ordering
648    v0 = test0.A()
649    v1 = test0.B()
650    v2 = test1.A()
651    v3 = test1.B()
652    sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
653
654    asserter(sumtest12 == 100)
655
656    asserter(not monster.TestarrayofstringIsNone())
657    asserter(monster.TestarrayofstringLength() == 2)
658    asserter(monster.Testarrayofstring(0) == b"test1")
659    asserter(monster.Testarrayofstring(1) == b"test2")
660
661    asserter(monster.TestarrayoftablesIsNone())
662    asserter(monster.TestarrayoftablesLength() == 0)
663    asserter(monster.TestnestedflatbufferIsNone())
664    asserter(monster.TestnestedflatbufferLength() == 0)
665    asserter(monster.Testempty() is None)
666
667
668class TestFuzz(unittest.TestCase):
669    ''' Low level stress/fuzz test: serialize/deserialize a variety of
670        different kinds of data in different combinations '''
671
672    binary_type = compat.binary_types[0] # this will always exist
673    ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
674    ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44,
675                                0x44, 0x44, 0x44, 0x44])
676    overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
677                                                 ofInt32Bytes, 0)
678    overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
679                                                 ofInt64Bytes, 0)
680
681    # Values we're testing against: chosen to ensure no bits get chopped
682    # off anywhere, and also be different from eachother.
683    boolVal = True
684    int8Val = N.Int8Flags.py_type(-127) # 0x81
685    uint8Val = N.Uint8Flags.py_type(0xFF)
686    int16Val = N.Int16Flags.py_type(-32222) # 0x8222
687    uint16Val = N.Uint16Flags.py_type(0xFEEE)
688    int32Val = N.Int32Flags.py_type(overflowingInt32Val)
689    uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
690    int64Val = N.Int64Flags.py_type(overflowingInt64Val)
691    uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
692    # Python uses doubles, so force it here
693    float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
694    float64Val = N.Float64Flags.py_type(3.14159265359)
695
696    def test_fuzz(self):
697        return self.check_once(11, 100)
698
699    def check_once(self, fuzzFields, fuzzObjects):
700        testValuesMax = 11 # hardcoded to the number of scalar types
701
702        builder = flatbuffers.Builder(0)
703        l = LCG()
704
705        objects = [0 for _ in compat_range(fuzzObjects)]
706
707        # Generate fuzzObjects random objects each consisting of
708        # fuzzFields fields, each of a random type.
709        for i in compat_range(fuzzObjects):
710            builder.StartObject(fuzzFields)
711
712            for j in compat_range(fuzzFields):
713                choice = int(l.Next()) % testValuesMax
714                if choice == 0:
715                    builder.PrependBoolSlot(int(j), self.boolVal, False)
716                elif choice == 1:
717                    builder.PrependInt8Slot(int(j), self.int8Val, 0)
718                elif choice == 2:
719                    builder.PrependUint8Slot(int(j), self.uint8Val, 0)
720                elif choice == 3:
721                    builder.PrependInt16Slot(int(j), self.int16Val, 0)
722                elif choice == 4:
723                    builder.PrependUint16Slot(int(j), self.uint16Val, 0)
724                elif choice == 5:
725                    builder.PrependInt32Slot(int(j), self.int32Val, 0)
726                elif choice == 6:
727                    builder.PrependUint32Slot(int(j), self.uint32Val, 0)
728                elif choice == 7:
729                    builder.PrependInt64Slot(int(j), self.int64Val, 0)
730                elif choice == 8:
731                    builder.PrependUint64Slot(int(j), self.uint64Val, 0)
732                elif choice == 9:
733                    builder.PrependFloat32Slot(int(j), self.float32Val, 0)
734                elif choice == 10:
735                    builder.PrependFloat64Slot(int(j), self.float64Val, 0)
736                else:
737                    raise RuntimeError('unreachable')
738
739            off = builder.EndObject()
740
741            # store the offset from the end of the builder buffer,
742            # since it will keep growing:
743            objects[i] = off
744
745        # Do some bookkeeping to generate stats on fuzzes:
746        stats = defaultdict(int)
747        def check(table, desc, want, got):
748            stats[desc] += 1
749            self.assertEqual(want, got, "%s != %s, %s" % (want, got, desc))
750
751        l = LCG()  # Reset.
752
753        # Test that all objects we generated are readable and return the
754        # expected values. We generate random objects in the same order
755        # so this is deterministic.
756        for i in compat_range(fuzzObjects):
757
758            table = flatbuffers.table.Table(builder.Bytes,
759                                            len(builder.Bytes) - objects[i])
760
761            for j in compat_range(fuzzFields):
762                field_count = flatbuffers.builder.VtableMetadataFields + j
763                f = N.VOffsetTFlags.py_type(field_count *
764                                            N.VOffsetTFlags.bytewidth)
765                choice = int(l.Next()) % testValuesMax
766
767                if choice == 0:
768                    check(table, "bool", self.boolVal,
769                          table.GetSlot(f, False, N.BoolFlags))
770                elif choice == 1:
771                    check(table, "int8", self.int8Val,
772                          table.GetSlot(f, 0, N.Int8Flags))
773                elif choice == 2:
774                    check(table, "uint8", self.uint8Val,
775                          table.GetSlot(f, 0, N.Uint8Flags))
776                elif choice == 3:
777                    check(table, "int16", self.int16Val,
778                          table.GetSlot(f, 0, N.Int16Flags))
779                elif choice == 4:
780                    check(table, "uint16", self.uint16Val,
781                          table.GetSlot(f, 0, N.Uint16Flags))
782                elif choice == 5:
783                    check(table, "int32", self.int32Val,
784                          table.GetSlot(f, 0, N.Int32Flags))
785                elif choice == 6:
786                    check(table, "uint32", self.uint32Val,
787                          table.GetSlot(f, 0, N.Uint32Flags))
788                elif choice == 7:
789                    check(table, "int64", self.int64Val,
790                          table.GetSlot(f, 0, N.Int64Flags))
791                elif choice == 8:
792                    check(table, "uint64", self.uint64Val,
793                          table.GetSlot(f, 0, N.Uint64Flags))
794                elif choice == 9:
795                    check(table, "float32", self.float32Val,
796                          table.GetSlot(f, 0, N.Float32Flags))
797                elif choice == 10:
798                    check(table, "float64", self.float64Val,
799                          table.GetSlot(f, 0, N.Float64Flags))
800                else:
801                    raise RuntimeError('unreachable')
802
803        # If enough checks were made, verify that all scalar types were used:
804        self.assertEqual(testValuesMax, len(stats),
805                "fuzzing failed to test all scalar types: %s" % stats)
806
807
808class TestByteLayout(unittest.TestCase):
809    ''' TestByteLayout checks the bytes of a Builder in various scenarios. '''
810
811    def assertBuilderEquals(self, builder, want_chars_or_ints):
812        def integerize(x):
813            if isinstance(x, compat.string_types):
814                return ord(x)
815            return x
816
817        want_ints = list(map(integerize, want_chars_or_ints))
818        want = bytearray(want_ints)
819        got = builder.Bytes[builder.Head():] # use the buffer directly
820        self.assertEqual(want, got)
821
822    def test_numbers(self):
823        b = flatbuffers.Builder(0)
824        self.assertBuilderEquals(b, [])
825        b.PrependBool(True)
826        self.assertBuilderEquals(b, [1])
827        b.PrependInt8(-127)
828        self.assertBuilderEquals(b, [129, 1])
829        b.PrependUint8(255)
830        self.assertBuilderEquals(b, [255, 129, 1])
831        b.PrependInt16(-32222)
832        self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1]) # first pad
833        b.PrependUint16(0xFEEE)
834        # no pad this time:
835        self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
836        b.PrependInt32(-53687092)
837        self.assertBuilderEquals(b, [204, 204, 204, 252, 0xEE, 0xFE,
838                                     0x22, 0x82, 0, 255, 129, 1])
839        b.PrependUint32(0x98765432)
840        self.assertBuilderEquals(b, [0x32, 0x54, 0x76, 0x98,
841                                     204, 204, 204, 252,
842                                     0xEE, 0xFE, 0x22, 0x82,
843                                     0, 255, 129, 1])
844
845    def test_numbers64(self):
846        b = flatbuffers.Builder(0)
847        b.PrependUint64(0x1122334455667788)
848        self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
849                                     0x44, 0x33, 0x22, 0x11])
850
851        b = flatbuffers.Builder(0)
852        b.PrependInt64(0x1122334455667788)
853        self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
854                                     0x44, 0x33, 0x22, 0x11])
855
856    def test_1xbyte_vector(self):
857        b = flatbuffers.Builder(0)
858        self.assertBuilderEquals(b, [])
859        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
860        self.assertBuilderEquals(b, [0, 0, 0]) # align to 4bytes
861        b.PrependByte(1)
862        self.assertBuilderEquals(b, [1, 0, 0, 0])
863        b.EndVector()
864        self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
865
866    def test_2xbyte_vector(self):
867        b = flatbuffers.Builder(0)
868        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
869        self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
870        b.PrependByte(1)
871        self.assertBuilderEquals(b, [1, 0, 0])
872        b.PrependByte(2)
873        self.assertBuilderEquals(b, [2, 1, 0, 0])
874        b.EndVector()
875        self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0]) # padding
876
877    def test_1xuint16_vector(self):
878        b = flatbuffers.Builder(0)
879        b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
880        self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
881        b.PrependUint16(1)
882        self.assertBuilderEquals(b, [1, 0, 0, 0])
883        b.EndVector()
884        self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
885
886    def test_2xuint16_vector(self):
887        b = flatbuffers.Builder(0)
888        b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
889        self.assertBuilderEquals(b, []) # align to 4bytes
890        b.PrependUint16(0xABCD)
891        self.assertBuilderEquals(b, [0xCD, 0xAB])
892        b.PrependUint16(0xDCBA)
893        self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
894        b.EndVector()
895        self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
896
897    def test_create_ascii_string(self):
898        b = flatbuffers.Builder(0)
899        b.CreateString(u"foo", encoding='ascii')
900
901        # 0-terminated, no pad:
902        self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
903        b.CreateString(u"moop", encoding='ascii')
904        # 0-terminated, 3-byte pad:
905        self.assertBuilderEquals(b, [4, 0, 0, 0, 'm', 'o', 'o', 'p',
906                                     0, 0, 0, 0,
907                                     3, 0, 0, 0, 'f', 'o', 'o', 0])
908
909    def test_create_utf8_string(self):
910        b = flatbuffers.Builder(0)
911        b.CreateString(u"Цлїςσδε")
912        self.assertBuilderEquals(b, "\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
913            "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
914
915        b.CreateString(u"フムアムカモケモ")
916        self.assertBuilderEquals(b, "\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91" \
917            "\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef" \
918            "\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
919            "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
920
921    def test_create_arbitrary_string(self):
922        b = flatbuffers.Builder(0)
923        s = "\x01\x02\x03"
924        b.CreateString(s) # Default encoding is utf-8.
925        # 0-terminated, no pad:
926        self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
927        s2 = "\x04\x05\x06\x07"
928        b.CreateString(s2) # Default encoding is utf-8.
929        # 0-terminated, 3-byte pad:
930        self.assertBuilderEquals(b, [4, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0,
931                                     3, 0, 0, 0, 1, 2, 3, 0])
932
933    def test_create_byte_vector(self):
934        b = flatbuffers.Builder(0)
935        b.CreateByteVector(b"")
936        # 0-byte pad:
937        self.assertBuilderEquals(b, [0, 0, 0, 0])
938
939        b = flatbuffers.Builder(0)
940        b.CreateByteVector(b"\x01\x02\x03")
941        # 1-byte pad:
942        self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
943
944    def test_create_numpy_vector_int8(self):
945        try:
946            imp.find_module('numpy')
947            # if numpy exists, then we should be able to get the
948            # vector as a numpy array
949            import numpy as np
950
951            # Systems endian:
952            b = flatbuffers.Builder(0)
953            x = np.array([1, 2, -3], dtype=np.int8)
954            b.CreateNumpyVector(x)
955            self.assertBuilderEquals(b, [
956                3, 0, 0, 0,  # vector length
957                1, 2, 256 - 3, 0   # vector value + padding
958            ])
959
960            # Reverse endian:
961            b = flatbuffers.Builder(0)
962            x_other_endian = x.byteswap().newbyteorder()
963            b.CreateNumpyVector(x_other_endian)
964            self.assertBuilderEquals(b, [
965                3, 0, 0, 0,  # vector length
966                1, 2, 256 - 3, 0   # vector value + padding
967            ])
968        except ImportError:
969            b = flatbuffers.Builder(0)
970            x = 0
971            assertRaises(
972                self,
973                lambda: b.CreateNumpyVector(x),
974                NumpyRequiredForThisFeature)
975
976    def test_create_numpy_vector_uint16(self):
977        try:
978            imp.find_module('numpy')
979            # if numpy exists, then we should be able to get the
980            # vector as a numpy array
981            import numpy as np
982
983            # Systems endian:
984            b = flatbuffers.Builder(0)
985            x = np.array([1, 2, 312], dtype=np.uint16)
986            b.CreateNumpyVector(x)
987            self.assertBuilderEquals(b, [
988                3, 0, 0, 0,     # vector length
989                1, 0,           # 1
990                2, 0,           # 2
991                312 - 256, 1,   # 312
992                0, 0            # padding
993            ])
994
995            # Reverse endian:
996            b = flatbuffers.Builder(0)
997            x_other_endian = x.byteswap().newbyteorder()
998            b.CreateNumpyVector(x_other_endian)
999            self.assertBuilderEquals(b, [
1000                3, 0, 0, 0,     # vector length
1001                1, 0,           # 1
1002                2, 0,           # 2
1003                312 - 256, 1,   # 312
1004                0, 0            # padding
1005            ])
1006        except ImportError:
1007            b = flatbuffers.Builder(0)
1008            x = 0
1009            assertRaises(
1010                self,
1011                lambda: b.CreateNumpyVector(x),
1012                NumpyRequiredForThisFeature)
1013
1014    def test_create_numpy_vector_int64(self):
1015        try:
1016            imp.find_module('numpy')
1017            # if numpy exists, then we should be able to get the
1018            # vector as a numpy array
1019            import numpy as np
1020
1021            # Systems endian:
1022            b = flatbuffers.Builder(0)
1023            x = np.array([1, 2, -12], dtype=np.int64)
1024            b.CreateNumpyVector(x)
1025            self.assertBuilderEquals(b, [
1026                3, 0, 0, 0,                     # vector length
1027                1, 0, 0, 0, 0, 0, 0, 0,         # 1
1028                2, 0, 0, 0, 0, 0, 0, 0,         # 2
1029                256 - 12, 255, 255, 255, 255, 255, 255, 255   # -12
1030            ])
1031
1032            # Reverse endian:
1033            b = flatbuffers.Builder(0)
1034            x_other_endian = x.byteswap().newbyteorder()
1035            b.CreateNumpyVector(x_other_endian)
1036            self.assertBuilderEquals(b, [
1037                3, 0, 0, 0,                     # vector length
1038                1, 0, 0, 0, 0, 0, 0, 0,         # 1
1039                2, 0, 0, 0, 0, 0, 0, 0,         # 2
1040                256 - 12, 255, 255, 255, 255, 255, 255, 255   # -12
1041            ])
1042
1043        except ImportError:
1044            b = flatbuffers.Builder(0)
1045            x = 0
1046            assertRaises(
1047                self,
1048                lambda: b.CreateNumpyVector(x),
1049                NumpyRequiredForThisFeature)
1050
1051    def test_create_numpy_vector_float32(self):
1052        try:
1053            imp.find_module('numpy')
1054            # if numpy exists, then we should be able to get the
1055            # vector as a numpy array
1056            import numpy as np
1057
1058            # Systems endian:
1059            b = flatbuffers.Builder(0)
1060            x = np.array([1, 2, -12], dtype=np.float32)
1061            b.CreateNumpyVector(x)
1062            self.assertBuilderEquals(b, [
1063                3, 0, 0, 0,                     # vector length
1064                0, 0, 128, 63,                  # 1
1065                0, 0, 0, 64,                    # 2
1066                0, 0, 64, 193                   # -12
1067            ])
1068
1069            # Reverse endian:
1070            b = flatbuffers.Builder(0)
1071            x_other_endian = x.byteswap().newbyteorder()
1072            b.CreateNumpyVector(x_other_endian)
1073            self.assertBuilderEquals(b, [
1074                3, 0, 0, 0,                     # vector length
1075                0, 0, 128, 63,                  # 1
1076                0, 0, 0, 64,                    # 2
1077                0, 0, 64, 193                   # -12
1078            ])
1079
1080        except ImportError:
1081            b = flatbuffers.Builder(0)
1082            x = 0
1083            assertRaises(
1084                self,
1085                lambda: b.CreateNumpyVector(x),
1086                NumpyRequiredForThisFeature)
1087
1088    def test_create_numpy_vector_float64(self):
1089        try:
1090            imp.find_module('numpy')
1091            # if numpy exists, then we should be able to get the
1092            # vector as a numpy array
1093            import numpy as np
1094
1095            # Systems endian:
1096            b = flatbuffers.Builder(0)
1097            x = np.array([1, 2, -12], dtype=np.float64)
1098            b.CreateNumpyVector(x)
1099            self.assertBuilderEquals(b, [
1100                3, 0, 0, 0,                     # vector length
1101                0, 0, 0, 0, 0, 0, 240, 63,                  # 1
1102                0, 0, 0, 0, 0, 0, 0, 64,                    # 2
1103                0, 0, 0, 0, 0, 0, 40, 192                   # -12
1104            ])
1105
1106            # Reverse endian:
1107            b = flatbuffers.Builder(0)
1108            x_other_endian = x.byteswap().newbyteorder()
1109            b.CreateNumpyVector(x_other_endian)
1110            self.assertBuilderEquals(b, [
1111                3, 0, 0, 0,                     # vector length
1112                0, 0, 0, 0, 0, 0, 240, 63,                  # 1
1113                0, 0, 0, 0, 0, 0, 0, 64,                    # 2
1114                0, 0, 0, 0, 0, 0, 40, 192                   # -12
1115            ])
1116
1117        except ImportError:
1118            b = flatbuffers.Builder(0)
1119            x = 0
1120            assertRaises(
1121                self,
1122                lambda: b.CreateNumpyVector(x),
1123                NumpyRequiredForThisFeature)
1124
1125    def test_create_numpy_vector_bool(self):
1126        try:
1127            imp.find_module('numpy')
1128            # if numpy exists, then we should be able to get the
1129            # vector as a numpy array
1130            import numpy as np
1131
1132            # Systems endian:
1133            b = flatbuffers.Builder(0)
1134            x = np.array([True, False, True], dtype=np.bool)
1135            b.CreateNumpyVector(x)
1136            self.assertBuilderEquals(b, [
1137                3, 0, 0, 0, # vector length
1138                1, 0, 1, 0  # vector values + padding
1139            ])
1140
1141            # Reverse endian:
1142            b = flatbuffers.Builder(0)
1143            x_other_endian = x.byteswap().newbyteorder()
1144            b.CreateNumpyVector(x_other_endian)
1145            self.assertBuilderEquals(b, [
1146                3, 0, 0, 0, # vector length
1147                1, 0, 1, 0  # vector values + padding
1148            ])
1149
1150        except ImportError:
1151            b = flatbuffers.Builder(0)
1152            x = 0
1153            assertRaises(
1154                self,
1155                lambda: b.CreateNumpyVector(x),
1156                NumpyRequiredForThisFeature)
1157
1158    def test_create_numpy_vector_reject_strings(self):
1159        try:
1160            imp.find_module('numpy')
1161            # if numpy exists, then we should be able to get the
1162            # vector as a numpy array
1163            import numpy as np
1164
1165            # Create String array
1166            b = flatbuffers.Builder(0)
1167            x = np.array(["hello", "fb", "testing"])
1168            assertRaises(
1169                self,
1170                lambda: b.CreateNumpyVector(x),
1171                TypeError)
1172
1173        except ImportError:
1174            b = flatbuffers.Builder(0)
1175            x = 0
1176            assertRaises(
1177                self,
1178                lambda: b.CreateNumpyVector(x),
1179                NumpyRequiredForThisFeature)
1180
1181    def test_create_numpy_vector_reject_object(self):
1182        try:
1183            imp.find_module('numpy')
1184            # if numpy exists, then we should be able to get the
1185            # vector as a numpy array
1186            import numpy as np
1187
1188            # Create String array
1189            b = flatbuffers.Builder(0)
1190            x = np.array([{"m": 0}, {"as": -2.1, 'c': 'c'}])
1191            assertRaises(
1192                self,
1193                lambda: b.CreateNumpyVector(x),
1194                TypeError)
1195
1196        except ImportError:
1197            b = flatbuffers.Builder(0)
1198            x = 0
1199            assertRaises(
1200                self,
1201                lambda: b.CreateNumpyVector(x),
1202                NumpyRequiredForThisFeature)
1203
1204    def test_empty_vtable(self):
1205        b = flatbuffers.Builder(0)
1206        b.StartObject(0)
1207        self.assertBuilderEquals(b, [])
1208        b.EndObject()
1209        self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
1210
1211    def test_vtable_with_one_true_bool(self):
1212        b = flatbuffers.Builder(0)
1213        self.assertBuilderEquals(b, [])
1214        b.StartObject(1)
1215        self.assertBuilderEquals(b, [])
1216        b.PrependBoolSlot(0, True, False)
1217        b.EndObject()
1218        self.assertBuilderEquals(b, [
1219            6, 0,  # vtable bytes
1220            8, 0,  # length of object including vtable offset
1221            7, 0,  # start of bool value
1222            6, 0, 0, 0,  # offset for start of vtable (int32)
1223            0, 0, 0,  # padded to 4 bytes
1224            1,  # bool value
1225        ])
1226
1227    def test_vtable_with_one_default_bool(self):
1228        b = flatbuffers.Builder(0)
1229        self.assertBuilderEquals(b, [])
1230        b.StartObject(1)
1231        self.assertBuilderEquals(b, [])
1232        b.PrependBoolSlot(0, False, False)
1233        b.EndObject()
1234        self.assertBuilderEquals(b, [
1235            4, 0,  # vtable bytes
1236            4, 0,  # end of object from here
1237            # entry 1 is zero and not stored
1238            4, 0, 0, 0,  # offset for start of vtable (int32)
1239        ])
1240
1241    def test_vtable_with_one_int16(self):
1242        b = flatbuffers.Builder(0)
1243        b.StartObject(1)
1244        b.PrependInt16Slot(0, 0x789A, 0)
1245        b.EndObject()
1246        self.assertBuilderEquals(b, [
1247            6, 0,  # vtable bytes
1248            8, 0,  # end of object from here
1249            6, 0,  # offset to value
1250            6, 0, 0, 0,  # offset for start of vtable (int32)
1251            0, 0,  # padding to 4 bytes
1252            0x9A, 0x78,
1253        ])
1254
1255    def test_vtable_with_two_int16(self):
1256        b = flatbuffers.Builder(0)
1257        b.StartObject(2)
1258        b.PrependInt16Slot(0, 0x3456, 0)
1259        b.PrependInt16Slot(1, 0x789A, 0)
1260        b.EndObject()
1261        self.assertBuilderEquals(b, [
1262            8, 0,  # vtable bytes
1263            8, 0,  # end of object from here
1264            6, 0,  # offset to value 0
1265            4, 0,  # offset to value 1
1266            8, 0, 0, 0,  # offset for start of vtable (int32)
1267            0x9A, 0x78,  # value 1
1268            0x56, 0x34,  # value 0
1269        ])
1270
1271    def test_vtable_with_int16_and_bool(self):
1272        b = flatbuffers.Builder(0)
1273        b.StartObject(2)
1274        b.PrependInt16Slot(0, 0x3456, 0)
1275        b.PrependBoolSlot(1, True, False)
1276        b.EndObject()
1277        self.assertBuilderEquals(b, [
1278            8, 0,  # vtable bytes
1279            8, 0,  # end of object from here
1280            6, 0,  # offset to value 0
1281            5, 0,  # offset to value 1
1282            8, 0, 0, 0,  # offset for start of vtable (int32)
1283            0,          # padding
1284            1,          # value 1
1285            0x56, 0x34,  # value 0
1286        ])
1287
1288    def test_vtable_with_empty_vector(self):
1289        b = flatbuffers.Builder(0)
1290        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1291        vecend = b.EndVector()
1292        b.StartObject(1)
1293        b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1294        b.EndObject()
1295        self.assertBuilderEquals(b, [
1296            6, 0,  # vtable bytes
1297            8, 0,
1298            4, 0,  # offset to vector offset
1299            6, 0, 0, 0,  # offset for start of vtable (int32)
1300            4, 0, 0, 0,
1301            0, 0, 0, 0,  # length of vector (not in struct)
1302        ])
1303
1304    def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
1305        b = flatbuffers.Builder(0)
1306        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1307        vecend = b.EndVector()
1308        b.StartObject(2)
1309        b.PrependInt16Slot(0, 55, 0)
1310        b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1311        b.EndObject()
1312        self.assertBuilderEquals(b, [
1313            8, 0,  # vtable bytes
1314            12, 0,
1315            10, 0,  # offset to value 0
1316            4, 0,  # offset to vector offset
1317            8, 0, 0, 0,  # vtable loc
1318            8, 0, 0, 0,  # value 1
1319            0, 0, 55, 0,  # value 0
1320
1321            0, 0, 0, 0,  # length of vector (not in struct)
1322        ])
1323
1324    def test_vtable_with_1_int16_and_2vector_of_int16(self):
1325        b = flatbuffers.Builder(0)
1326        b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
1327        b.PrependInt16(0x1234)
1328        b.PrependInt16(0x5678)
1329        vecend = b.EndVector()
1330        b.StartObject(2)
1331        b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1332        b.PrependInt16Slot(0, 55, 0)
1333        b.EndObject()
1334        self.assertBuilderEquals(b, [
1335            8, 0,  # vtable bytes
1336            12, 0,  # length of object
1337            6, 0,  # start of value 0 from end of vtable
1338            8, 0,  # start of value 1 from end of buffer
1339            8, 0, 0, 0,  # offset for start of vtable (int32)
1340            0, 0,  # padding
1341            55, 0,  # value 0
1342            4, 0, 0, 0,  # vector position from here
1343            2, 0, 0, 0,  # length of vector (uint32)
1344            0x78, 0x56,  # vector value 1
1345            0x34, 0x12,  # vector value 0
1346        ])
1347
1348    def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
1349        b = flatbuffers.Builder(0)
1350        b.StartObject(1)
1351        b.Prep(4+4+4, 0)
1352        b.PrependInt8(55)
1353        b.Pad(3)
1354        b.PrependInt16(0x1234)
1355        b.Pad(2)
1356        b.PrependInt32(0x12345678)
1357        structStart = b.Offset()
1358        b.PrependStructSlot(0, structStart, 0)
1359        b.EndObject()
1360        self.assertBuilderEquals(b, [
1361            6, 0,  # vtable bytes
1362            16, 0,  # end of object from here
1363            4, 0,  # start of struct from here
1364            6, 0, 0, 0,  # offset for start of vtable (int32)
1365            0x78, 0x56, 0x34, 0x12,  # value 2
1366            0, 0,  # padding
1367            0x34, 0x12,  # value 1
1368            0, 0, 0,  # padding
1369            55,  # value 0
1370        ])
1371
1372    def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
1373        b = flatbuffers.Builder(0)
1374        b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth*2, 2, 1)
1375        b.PrependInt8(33)
1376        b.PrependInt8(44)
1377        b.PrependInt8(55)
1378        b.PrependInt8(66)
1379        vecend = b.EndVector()
1380        b.StartObject(1)
1381        b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1382        b.EndObject()
1383        self.assertBuilderEquals(b, [
1384            6, 0,  # vtable bytes
1385            8, 0,
1386            4, 0,  # offset of vector offset
1387            6, 0, 0, 0,  # offset for start of vtable (int32)
1388            4, 0, 0, 0,  # vector start offset
1389
1390            2, 0, 0, 0,  # vector length
1391            66,  # vector value 1,1
1392            55,  # vector value 1,0
1393            44,  # vector value 0,1
1394            33,  # vector value 0,0
1395        ])
1396
1397    def test_table_with_some_elements(self):
1398        b = flatbuffers.Builder(0)
1399        b.StartObject(2)
1400        b.PrependInt8Slot(0, 33, 0)
1401        b.PrependInt16Slot(1, 66, 0)
1402        off = b.EndObject()
1403        b.Finish(off)
1404
1405        self.assertBuilderEquals(b, [
1406            12, 0, 0, 0,  # root of table: points to vtable offset
1407
1408            8, 0,  # vtable bytes
1409            8, 0,  # end of object from here
1410            7, 0,  # start of value 0
1411            4, 0,  # start of value 1
1412
1413            8, 0, 0, 0,  # offset for start of vtable (int32)
1414
1415            66, 0,  # value 1
1416            0,  # padding
1417            33,  # value 0
1418        ])
1419
1420    def test__one_unfinished_table_and_one_finished_table(self):
1421        b = flatbuffers.Builder(0)
1422        b.StartObject(2)
1423        b.PrependInt8Slot(0, 33, 0)
1424        b.PrependInt8Slot(1, 44, 0)
1425        off = b.EndObject()
1426        b.Finish(off)
1427
1428        b.StartObject(3)
1429        b.PrependInt8Slot(0, 55, 0)
1430        b.PrependInt8Slot(1, 66, 0)
1431        b.PrependInt8Slot(2, 77, 0)
1432        off = b.EndObject()
1433        b.Finish(off)
1434
1435        self.assertBuilderEquals(b, [
1436            16, 0, 0, 0,  # root of table: points to object
1437            0, 0,  # padding
1438
1439            10, 0,  # vtable bytes
1440            8, 0,  # size of object
1441            7, 0,  # start of value 0
1442            6, 0,  # start of value 1
1443            5, 0,  # start of value 2
1444            10, 0, 0, 0,  # offset for start of vtable (int32)
1445            0,  # padding
1446            77,  # value 2
1447            66,  # value 1
1448            55,  # value 0
1449
1450            12, 0, 0, 0,  # root of table: points to object
1451
1452            8, 0,  # vtable bytes
1453            8, 0,  # size of object
1454            7, 0,  # start of value 0
1455            6, 0,  # start of value 1
1456            8, 0, 0, 0,  # offset for start of vtable (int32)
1457            0, 0,  # padding
1458            44,  # value 1
1459            33,  # value 0
1460        ])
1461
1462    def test_a_bunch_of_bools(self):
1463        b = flatbuffers.Builder(0)
1464        b.StartObject(8)
1465        b.PrependBoolSlot(0, True, False)
1466        b.PrependBoolSlot(1, True, False)
1467        b.PrependBoolSlot(2, True, False)
1468        b.PrependBoolSlot(3, True, False)
1469        b.PrependBoolSlot(4, True, False)
1470        b.PrependBoolSlot(5, True, False)
1471        b.PrependBoolSlot(6, True, False)
1472        b.PrependBoolSlot(7, True, False)
1473        off = b.EndObject()
1474        b.Finish(off)
1475
1476        self.assertBuilderEquals(b, [
1477            24, 0, 0, 0,  # root of table: points to vtable offset
1478
1479            20, 0,  # vtable bytes
1480            12, 0,  # size of object
1481            11, 0,  # start of value 0
1482            10, 0,  # start of value 1
1483            9, 0,  # start of value 2
1484            8, 0,  # start of value 3
1485            7, 0,  # start of value 4
1486            6, 0,  # start of value 5
1487            5, 0,  # start of value 6
1488            4, 0,  # start of value 7
1489            20, 0, 0, 0,  # vtable offset
1490
1491            1,  # value 7
1492            1,  # value 6
1493            1,  # value 5
1494            1,  # value 4
1495            1,  # value 3
1496            1,  # value 2
1497            1,  # value 1
1498            1,  # value 0
1499        ])
1500
1501    def test_three_bools(self):
1502        b = flatbuffers.Builder(0)
1503        b.StartObject(3)
1504        b.PrependBoolSlot(0, True, False)
1505        b.PrependBoolSlot(1, True, False)
1506        b.PrependBoolSlot(2, True, False)
1507        off = b.EndObject()
1508        b.Finish(off)
1509
1510        self.assertBuilderEquals(b, [
1511            16, 0, 0, 0,  # root of table: points to vtable offset
1512
1513            0, 0,  # padding
1514
1515            10, 0,  # vtable bytes
1516            8, 0,  # size of object
1517            7, 0,  # start of value 0
1518            6, 0,  # start of value 1
1519            5, 0,  # start of value 2
1520            10, 0, 0, 0,  # vtable offset from here
1521
1522            0,  # padding
1523            1,  # value 2
1524            1,  # value 1
1525            1,  # value 0
1526        ])
1527
1528    def test_some_floats(self):
1529        b = flatbuffers.Builder(0)
1530        b.StartObject(1)
1531        b.PrependFloat32Slot(0, 1.0, 0.0)
1532        off = b.EndObject()
1533
1534        self.assertBuilderEquals(b, [
1535            6, 0,  # vtable bytes
1536            8, 0,  # size of object
1537            4, 0,  # start of value 0
1538            6, 0, 0, 0,  # vtable offset
1539
1540            0, 0, 128, 63,  # value 0
1541        ])
1542
1543
1544def make_monster_from_generated_code(sizePrefix = False, file_identifier=None):
1545    ''' Use generated code to build the example Monster. '''
1546
1547    b = flatbuffers.Builder(0)
1548    string = b.CreateString("MyMonster")
1549    test1 = b.CreateString("test1")
1550    test2 = b.CreateString("test2")
1551    fred = b.CreateString("Fred")
1552
1553    MyGame.Example.Monster.StartInventoryVector(b, 5)
1554    b.PrependByte(4)
1555    b.PrependByte(3)
1556    b.PrependByte(2)
1557    b.PrependByte(1)
1558    b.PrependByte(0)
1559    inv = b.EndVector()
1560
1561    MyGame.Example.Monster.Start(b)
1562    MyGame.Example.Monster.AddName(b, fred)
1563    mon2 = MyGame.Example.Monster.End(b)
1564
1565    MyGame.Example.Monster.StartTest4Vector(b, 2)
1566    MyGame.Example.Test.CreateTest(b, 10, 20)
1567    MyGame.Example.Test.CreateTest(b, 30, 40)
1568    test4 = b.EndVector()
1569
1570    MyGame.Example.Monster.StartTestarrayofstringVector(b, 2)
1571    b.PrependUOffsetTRelative(test2)
1572    b.PrependUOffsetTRelative(test1)
1573    testArrayOfString = b.EndVector()
1574
1575    MyGame.Example.Monster.StartVectorOfLongsVector(b, 5)
1576    b.PrependInt64(100000000)
1577    b.PrependInt64(1000000)
1578    b.PrependInt64(10000)
1579    b.PrependInt64(100)
1580    b.PrependInt64(1)
1581    VectorOfLongs = b.EndVector()
1582
1583    MyGame.Example.Monster.StartVectorOfDoublesVector(b, 3)
1584    b.PrependFloat64(1.7976931348623157e+308)
1585    b.PrependFloat64(0)
1586    b.PrependFloat64(-1.7976931348623157e+308)
1587    VectorOfDoubles = b.EndVector()
1588
1589    MyGame.Example.Monster.Start(b)
1590
1591    pos = MyGame.Example.Vec3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
1592    MyGame.Example.Monster.AddPos(b, pos)
1593
1594    MyGame.Example.Monster.AddHp(b, 80)
1595    MyGame.Example.Monster.AddName(b, string)
1596    MyGame.Example.Monster.AddInventory(b, inv)
1597    MyGame.Example.Monster.AddTestType(b, 1)
1598    MyGame.Example.Monster.AddTest(b, mon2)
1599    MyGame.Example.Monster.AddTest4(b, test4)
1600    MyGame.Example.Monster.AddTestarrayofstring(b, testArrayOfString)
1601    MyGame.Example.Monster.AddVectorOfLongs(b, VectorOfLongs)
1602    MyGame.Example.Monster.AddVectorOfDoubles(b, VectorOfDoubles)
1603    mon = MyGame.Example.Monster.End(b)
1604
1605    if sizePrefix:
1606        b.FinishSizePrefixed(mon, file_identifier)
1607    else:
1608        b.Finish(mon, file_identifier)
1609
1610    return b.Bytes, b.Head()
1611
1612
1613class TestBuilderForceDefaults(unittest.TestCase):
1614    """Verify that the builder adds default values when forced."""
1615
1616    test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
1617                  N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
1618                  N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
1619                  N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
1620    def test_default_force_defaults(self):
1621        for flag in self.test_flags:
1622            b = flatbuffers.Builder(0)
1623            b.StartObject(1)
1624            stored_offset = b.Offset()
1625            if flag != N.UOffsetTFlags():
1626                b.PrependSlot(flag, 0, 0, 0)
1627            else:
1628                b.PrependUOffsetTRelativeSlot(0, 0, 0)
1629            end_offset = b.Offset()
1630            b.EndObject()
1631            self.assertEqual(0, end_offset - stored_offset)
1632
1633    def test_force_defaults_true(self):
1634        for flag in self.test_flags:
1635            b = flatbuffers.Builder(0)
1636            b.ForceDefaults(True)
1637            b.StartObject(1)
1638            stored_offset = b.Offset()
1639            if flag != N.UOffsetTFlags():
1640                b.PrependSlot(flag, 0, 0, 0)
1641            else:
1642                b.PrependUOffsetTRelativeSlot(0, 0, 0)
1643            end_offset = b.Offset()
1644            b.EndObject()
1645            self.assertEqual(flag.bytewidth, end_offset - stored_offset)
1646
1647
1648class TestAllCodePathsOfExampleSchema(unittest.TestCase):
1649    def setUp(self, *args, **kwargs):
1650        super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
1651
1652        b = flatbuffers.Builder(0)
1653        MyGame.Example.Monster.Start(b)
1654        gen_mon = MyGame.Example.Monster.End(b)
1655        b.Finish(gen_mon)
1656
1657        self.mon = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1658                                                                   b.Head())
1659
1660    def test_default_monster_pos(self):
1661        self.assertTrue(self.mon.Pos() is None)
1662
1663    def test_nondefault_monster_mana(self):
1664        b = flatbuffers.Builder(0)
1665        MyGame.Example.Monster.Start(b)
1666        MyGame.Example.Monster.AddMana(b, 50)
1667        mon = MyGame.Example.Monster.End(b)
1668        b.Finish(mon)
1669
1670        got_mon = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1671                                                                  b.Head())
1672        self.assertEqual(50, got_mon.Mana())
1673
1674    def test_default_monster_hp(self):
1675        self.assertEqual(100, self.mon.Hp())
1676
1677    def test_default_monster_name(self):
1678        self.assertEqual(None, self.mon.Name())
1679
1680    def test_default_monster_inventory_item(self):
1681        self.assertEqual(0, self.mon.Inventory(0))
1682
1683    def test_default_monster_inventory_length(self):
1684        self.assertEqual(0, self.mon.InventoryLength())
1685        self.assertTrue(self.mon.InventoryIsNone())
1686
1687    def test_empty_monster_inventory_vector(self):
1688        b = flatbuffers.Builder(0)
1689        MyGame.Example.Monster.StartInventoryVector(b, 0)
1690        inv = b.EndVector()
1691        MyGame.Example.Monster.Start(b)
1692        MyGame.Example.Monster.AddInventory(b, inv)
1693        mon = MyGame.Example.Monster.End(b)
1694        b.Finish(mon)
1695        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1696                                                               b.Head())
1697        self.assertFalse(mon2.InventoryIsNone())
1698
1699    def test_default_monster_color(self):
1700        self.assertEqual(MyGame.Example.Color.Color.Blue, self.mon.Color())
1701
1702    def test_nondefault_monster_color(self):
1703        b = flatbuffers.Builder(0)
1704        color = MyGame.Example.Color.Color.Red
1705        MyGame.Example.Monster.Start(b)
1706        MyGame.Example.Monster.AddColor(b, color)
1707        mon = MyGame.Example.Monster.End(b)
1708        b.Finish(mon)
1709
1710        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1711                                                               b.Head())
1712        self.assertEqual(MyGame.Example.Color.Color.Red, mon2.Color())
1713
1714    def test_default_monster_testtype(self):
1715        self.assertEqual(0, self.mon.TestType())
1716
1717    def test_default_monster_test_field(self):
1718        self.assertEqual(None, self.mon.Test())
1719
1720    def test_default_monster_test4_item(self):
1721        self.assertEqual(None, self.mon.Test4(0))
1722
1723    def test_default_monster_test4_length(self):
1724        self.assertEqual(0, self.mon.Test4Length())
1725        self.assertTrue(self.mon.Test4IsNone())
1726
1727    def test_empty_monster_test4_vector(self):
1728        b = flatbuffers.Builder(0)
1729        MyGame.Example.Monster.StartTest4Vector(b, 0)
1730        test4 = b.EndVector()
1731        MyGame.Example.Monster.Start(b)
1732        MyGame.Example.Monster.AddTest4(b, test4)
1733        mon = MyGame.Example.Monster.End(b)
1734        b.Finish(mon)
1735        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1736                                                               b.Head())
1737        self.assertFalse(mon2.Test4IsNone())
1738
1739    def test_default_monster_testarrayofstring(self):
1740        self.assertEqual("", self.mon.Testarrayofstring(0))
1741
1742    def test_default_monster_testarrayofstring_length(self):
1743        self.assertEqual(0, self.mon.TestarrayofstringLength())
1744        self.assertTrue(self.mon.TestarrayofstringIsNone())
1745
1746    def test_empty_monster_testarrayofstring_vector(self):
1747        b = flatbuffers.Builder(0)
1748        MyGame.Example.Monster.StartTestarrayofstringVector(b, 0)
1749        testarrayofstring = b.EndVector()
1750        MyGame.Example.Monster.Start(b)
1751        MyGame.Example.Monster.AddTestarrayofstring(b, testarrayofstring)
1752        mon = MyGame.Example.Monster.End(b)
1753        b.Finish(mon)
1754        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1755                                                               b.Head())
1756        self.assertFalse(mon2.TestarrayofstringIsNone())
1757
1758    def test_default_monster_testarrayoftables(self):
1759        self.assertEqual(None, self.mon.Testarrayoftables(0))
1760
1761    def test_nondefault_monster_testarrayoftables(self):
1762        b = flatbuffers.Builder(0)
1763
1764        # make a child Monster within a vector of Monsters:
1765        MyGame.Example.Monster.Start(b)
1766        MyGame.Example.Monster.AddHp(b, 99)
1767        sub_monster = MyGame.Example.Monster.End(b)
1768
1769        # build the vector:
1770        MyGame.Example.Monster.StartTestarrayoftablesVector(b, 1)
1771        b.PrependUOffsetTRelative(sub_monster)
1772        vec = b.EndVector()
1773
1774        # make the parent monster and include the vector of Monster:
1775        MyGame.Example.Monster.Start(b)
1776        MyGame.Example.Monster.AddTestarrayoftables(b, vec)
1777        mon = MyGame.Example.Monster.End(b)
1778        b.Finish(mon)
1779
1780        # inspect the resulting data:
1781        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Output(), 0)
1782        self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
1783        self.assertEqual(1, mon2.TestarrayoftablesLength())
1784        self.assertFalse(mon2.TestarrayoftablesIsNone())
1785
1786    def test_default_monster_testarrayoftables_length(self):
1787        self.assertEqual(0, self.mon.TestarrayoftablesLength())
1788        self.assertTrue(self.mon.TestarrayoftablesIsNone())
1789
1790    def test_empty_monster_testarrayoftables_vector(self):
1791        b = flatbuffers.Builder(0)
1792        MyGame.Example.Monster.StartTestarrayoftablesVector(b, 0)
1793        testarrayoftables = b.EndVector()
1794        MyGame.Example.Monster.Start(b)
1795        MyGame.Example.Monster.AddTestarrayoftables(b, testarrayoftables)
1796        mon = MyGame.Example.Monster.End(b)
1797        b.Finish(mon)
1798        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1799                                                               b.Head())
1800        self.assertFalse(mon2.TestarrayoftablesIsNone())
1801
1802    def test_default_monster_testarrayoftables_length(self):
1803        self.assertEqual(0, self.mon.TestarrayoftablesLength())
1804
1805    def test_nondefault_monster_enemy(self):
1806        b = flatbuffers.Builder(0)
1807
1808        # make an Enemy object:
1809        MyGame.Example.Monster.Start(b)
1810        MyGame.Example.Monster.AddHp(b, 88)
1811        enemy = MyGame.Example.Monster.End(b)
1812        b.Finish(enemy)
1813
1814        # make the parent monster and include the vector of Monster:
1815        MyGame.Example.Monster.Start(b)
1816        MyGame.Example.Monster.AddEnemy(b, enemy)
1817        mon = MyGame.Example.Monster.End(b)
1818        b.Finish(mon)
1819
1820        # inspect the resulting data:
1821        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1822                                                               b.Head())
1823        self.assertEqual(88, mon2.Enemy().Hp())
1824
1825    def test_default_monster_testnestedflatbuffer(self):
1826        self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
1827
1828    def test_default_monster_testnestedflatbuffer_length(self):
1829        self.assertEqual(0, self.mon.TestnestedflatbufferLength())
1830        self.assertTrue(self.mon.TestnestedflatbufferIsNone())
1831
1832    def test_empty_monster_testnestedflatbuffer_vector(self):
1833        b = flatbuffers.Builder(0)
1834        MyGame.Example.Monster.StartTestnestedflatbufferVector(b, 0)
1835        testnestedflatbuffer = b.EndVector()
1836        MyGame.Example.Monster.Start(b)
1837        MyGame.Example.Monster.AddTestnestedflatbuffer(b, testnestedflatbuffer)
1838        mon = MyGame.Example.Monster.End(b)
1839        b.Finish(mon)
1840        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1841                                                               b.Head())
1842        self.assertFalse(mon2.TestnestedflatbufferIsNone())
1843
1844    def test_nondefault_monster_testnestedflatbuffer(self):
1845        b = flatbuffers.Builder(0)
1846
1847        MyGame.Example.Monster.StartTestnestedflatbufferVector(b, 3)
1848        b.PrependByte(4)
1849        b.PrependByte(2)
1850        b.PrependByte(0)
1851        sub_buf = b.EndVector()
1852
1853        # make the parent monster and include the vector of Monster:
1854        MyGame.Example.Monster.Start(b)
1855        MyGame.Example.Monster.AddTestnestedflatbuffer(b, sub_buf)
1856        mon = MyGame.Example.Monster.End(b)
1857        b.Finish(mon)
1858
1859        # inspect the resulting data:
1860        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1861                                                               b.Head())
1862        self.assertEqual(3, mon2.TestnestedflatbufferLength())
1863        self.assertFalse(mon2.TestnestedflatbufferIsNone())
1864        self.assertEqual(0, mon2.Testnestedflatbuffer(0))
1865        self.assertEqual(2, mon2.Testnestedflatbuffer(1))
1866        self.assertEqual(4, mon2.Testnestedflatbuffer(2))
1867        try:
1868            imp.find_module('numpy')
1869            # if numpy exists, then we should be able to get the
1870            # vector as a numpy array
1871            self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
1872        except ImportError:
1873            assertRaises(self,
1874                         lambda: mon2.TestnestedflatbufferAsNumpy(),
1875                         NumpyRequiredForThisFeature)
1876
1877    def test_nested_monster_testnestedflatbuffer(self):
1878        b = flatbuffers.Builder(0)
1879
1880        # build another monster to nest inside testnestedflatbuffer
1881        nestedB = flatbuffers.Builder(0)
1882        nameStr = nestedB.CreateString("Nested Monster")
1883        MyGame.Example.Monster.Start(nestedB)
1884        MyGame.Example.Monster.AddHp(nestedB, 30)
1885        MyGame.Example.Monster.AddName(nestedB, nameStr)
1886        nestedMon = MyGame.Example.Monster.End(nestedB)
1887        nestedB.Finish(nestedMon)
1888
1889        # write the nested FB bytes
1890        sub_buf = MyGame.Example.Monster.MakeTestnestedflatbufferVectorFromBytes(
1891            b, nestedB.Output())
1892
1893        # make the parent monster and include the bytes of the nested monster
1894        MyGame.Example.Monster.Start(b)
1895        MyGame.Example.Monster.AddTestnestedflatbuffer(b, sub_buf)
1896        mon = MyGame.Example.Monster.End(b)
1897        b.Finish(mon)
1898
1899        # inspect the resulting data:
1900        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1901                                                               b.Head())
1902        nestedMon2 = mon2.TestnestedflatbufferNestedRoot()
1903        self.assertEqual(b"Nested Monster", nestedMon2.Name())
1904        self.assertEqual(30, nestedMon2.Hp())
1905
1906    def test_nondefault_monster_testempty(self):
1907        b = flatbuffers.Builder(0)
1908
1909        # make a Stat object:
1910        MyGame.Example.Stat.Start(b)
1911        MyGame.Example.Stat.AddVal(b, 123)
1912        my_stat = MyGame.Example.Stat.End(b)
1913        b.Finish(my_stat)
1914
1915        # include the stat object in a monster:
1916        MyGame.Example.Monster.Start(b)
1917        MyGame.Example.Monster.AddTestempty(b, my_stat)
1918        mon = MyGame.Example.Monster.End(b)
1919        b.Finish(mon)
1920
1921        # inspect the resulting data:
1922        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1923                                                               b.Head())
1924        self.assertEqual(123, mon2.Testempty().Val())
1925
1926    def test_default_monster_testbool(self):
1927        self.assertFalse(self.mon.Testbool())
1928
1929    def test_nondefault_monster_testbool(self):
1930        b = flatbuffers.Builder(0)
1931        MyGame.Example.Monster.Start(b)
1932        MyGame.Example.Monster.AddTestbool(b, True)
1933        mon = MyGame.Example.Monster.End(b)
1934        b.Finish(mon)
1935
1936        # inspect the resulting data:
1937        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1938                                                               b.Head())
1939        self.assertTrue(mon2.Testbool())
1940
1941    def test_default_monster_testhashes(self):
1942        self.assertEqual(0, self.mon.Testhashs32Fnv1())
1943        self.assertEqual(0, self.mon.Testhashu32Fnv1())
1944        self.assertEqual(0, self.mon.Testhashs64Fnv1())
1945        self.assertEqual(0, self.mon.Testhashu64Fnv1())
1946        self.assertEqual(0, self.mon.Testhashs32Fnv1a())
1947        self.assertEqual(0, self.mon.Testhashu32Fnv1a())
1948        self.assertEqual(0, self.mon.Testhashs64Fnv1a())
1949        self.assertEqual(0, self.mon.Testhashu64Fnv1a())
1950
1951    def test_nondefault_monster_testhashes(self):
1952        b = flatbuffers.Builder(0)
1953        MyGame.Example.Monster.Start(b)
1954        MyGame.Example.Monster.AddTesthashs32Fnv1(b, 1)
1955        MyGame.Example.Monster.AddTesthashu32Fnv1(b, 2)
1956        MyGame.Example.Monster.AddTesthashs64Fnv1(b, 3)
1957        MyGame.Example.Monster.AddTesthashu64Fnv1(b, 4)
1958        MyGame.Example.Monster.AddTesthashs32Fnv1a(b, 5)
1959        MyGame.Example.Monster.AddTesthashu32Fnv1a(b, 6)
1960        MyGame.Example.Monster.AddTesthashs64Fnv1a(b, 7)
1961        MyGame.Example.Monster.AddTesthashu64Fnv1a(b, 8)
1962        mon = MyGame.Example.Monster.End(b)
1963        b.Finish(mon)
1964
1965        # inspect the resulting data:
1966        mon2 = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1967                                                               b.Head())
1968        self.assertEqual(1, mon2.Testhashs32Fnv1())
1969        self.assertEqual(2, mon2.Testhashu32Fnv1())
1970        self.assertEqual(3, mon2.Testhashs64Fnv1())
1971        self.assertEqual(4, mon2.Testhashu64Fnv1())
1972        self.assertEqual(5, mon2.Testhashs32Fnv1a())
1973        self.assertEqual(6, mon2.Testhashu32Fnv1a())
1974        self.assertEqual(7, mon2.Testhashs64Fnv1a())
1975        self.assertEqual(8, mon2.Testhashu64Fnv1a())
1976
1977    def test_default_monster_parent_namespace_test(self):
1978        self.assertEqual(None, self.mon.ParentNamespaceTest())
1979
1980    def test_nondefault_monster_parent_namespace_test(self):
1981        b = flatbuffers.Builder(0)
1982        MyGame.InParentNamespace.Start(b)
1983        parent = MyGame.InParentNamespace.End(b)
1984        MyGame.Example.Monster.Start(b)
1985        MyGame.Example.Monster.AddParentNamespaceTest(b, parent)
1986        mon = MyGame.Example.Monster.End(b)
1987        b.Finish(mon)
1988
1989        # Inspect the resulting data.
1990        monster = MyGame.Example.Monster.Monster.GetRootAs(b.Bytes,
1991                                                                  b.Head())
1992        self.assertTrue(isinstance(monster.ParentNamespaceTest(),
1993                                   MyGame.InParentNamespace.InParentNamespace))
1994
1995    def test_getrootas_for_nonroot_table(self):
1996        b = flatbuffers.Builder(0)
1997        string = b.CreateString("MyStat")
1998
1999        MyGame.Example.Stat.Start(b)
2000        MyGame.Example.Stat.AddId(b, string)
2001        MyGame.Example.Stat.AddVal(b, 12345678)
2002        MyGame.Example.Stat.AddCount(b, 12345)
2003        stat = MyGame.Example.Stat.End(b)
2004        b.Finish(stat)
2005
2006        stat2 = MyGame.Example.Stat.Stat.GetRootAs(b.Bytes, b.Head())
2007
2008        self.assertEqual(b"MyStat", stat2.Id())
2009        self.assertEqual(12345678, stat2.Val())
2010        self.assertEqual(12345, stat2.Count())
2011
2012
2013class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
2014    def setUp(self, *args, **kwargs):
2015        super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
2016
2017        b = flatbuffers.Builder(0)
2018        MyGame.MonsterExtra.Start(b)
2019        gen_mon = MyGame.MonsterExtra.End(b)
2020        b.Finish(gen_mon)
2021
2022        self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAs(b.Bytes, b.Head())
2023
2024    def test_default_nan_inf(self):
2025        self.assertTrue(math.isnan(self.mon.F1()))
2026        self.assertEqual(self.mon.F2(), float("inf"))
2027        self.assertEqual(self.mon.F3(), float("-inf"))
2028
2029        self.assertTrue(math.isnan(self.mon.D1()))
2030        self.assertEqual(self.mon.D2(), float("inf"))
2031        self.assertEqual(self.mon.D3(), float("-inf"))
2032
2033
2034class TestVtableDeduplication(unittest.TestCase):
2035    ''' TestVtableDeduplication verifies that vtables are deduplicated. '''
2036
2037    def test_vtable_deduplication(self):
2038        b = flatbuffers.Builder(0)
2039
2040        b.StartObject(4)
2041        b.PrependByteSlot(0, 0, 0)
2042        b.PrependByteSlot(1, 11, 0)
2043        b.PrependByteSlot(2, 22, 0)
2044        b.PrependInt16Slot(3, 33, 0)
2045        obj0 = b.EndObject()
2046
2047        b.StartObject(4)
2048        b.PrependByteSlot(0, 0, 0)
2049        b.PrependByteSlot(1, 44, 0)
2050        b.PrependByteSlot(2, 55, 0)
2051        b.PrependInt16Slot(3, 66, 0)
2052        obj1 = b.EndObject()
2053
2054        b.StartObject(4)
2055        b.PrependByteSlot(0, 0, 0)
2056        b.PrependByteSlot(1, 77, 0)
2057        b.PrependByteSlot(2, 88, 0)
2058        b.PrependInt16Slot(3, 99, 0)
2059        obj2 = b.EndObject()
2060
2061        got = b.Bytes[b.Head():]
2062
2063        want = bytearray([
2064            240, 255, 255, 255,  # == -12. offset to dedupped vtable.
2065            99, 0,
2066            88,
2067            77,
2068            248, 255, 255, 255,  # == -8. offset to dedupped vtable.
2069            66, 0,
2070            55,
2071            44,
2072            12, 0,
2073            8, 0,
2074            0, 0,
2075            7, 0,
2076            6, 0,
2077            4, 0,
2078            12, 0, 0, 0,
2079            33, 0,
2080            22,
2081            11,
2082        ])
2083
2084        self.assertEqual((len(want), want), (len(got), got))
2085
2086        table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
2087        table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
2088        table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
2089
2090        def _checkTable(tab, voffsett_value, b, c, d):
2091            # vtable size
2092            got = tab.GetVOffsetTSlot(0, 0)
2093            self.assertEqual(12, got, 'case 0, 0')
2094
2095            # object size
2096            got = tab.GetVOffsetTSlot(2, 0)
2097            self.assertEqual(8, got, 'case 2, 0')
2098
2099            # default value
2100            got = tab.GetVOffsetTSlot(4, 0)
2101            self.assertEqual(voffsett_value, got, 'case 4, 0')
2102
2103            got = tab.GetSlot(6, 0, N.Uint8Flags)
2104            self.assertEqual(b, got, 'case 6, 0')
2105
2106            val = tab.GetSlot(8, 0, N.Uint8Flags)
2107            self.assertEqual(c, val, 'failed 8, 0')
2108
2109            got = tab.GetSlot(10, 0, N.Uint8Flags)
2110            self.assertEqual(d, got, 'failed 10, 0')
2111
2112        _checkTable(table0, 0, 11, 22, 33)
2113        _checkTable(table1, 0, 44, 55, 66)
2114        _checkTable(table2, 0, 77, 88, 99)
2115
2116
2117class TestExceptions(unittest.TestCase):
2118    def test_object_is_nested_error(self):
2119        b = flatbuffers.Builder(0)
2120        b.StartObject(0)
2121        assertRaises(self, lambda: b.StartObject(0),
2122                     flatbuffers.builder.IsNestedError)
2123
2124    def test_object_is_not_nested_error(self):
2125        b = flatbuffers.Builder(0)
2126        assertRaises(self, lambda: b.EndObject(),
2127                     flatbuffers.builder.IsNotNestedError)
2128
2129    def test_struct_is_not_inline_error(self):
2130        b = flatbuffers.Builder(0)
2131        b.StartObject(0)
2132        assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
2133                     flatbuffers.builder.StructIsNotInlineError)
2134
2135    def test_unreachable_error(self):
2136        b = flatbuffers.Builder(0)
2137        assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
2138                     flatbuffers.builder.OffsetArithmeticError)
2139
2140    def test_create_string_is_nested_error(self):
2141        b = flatbuffers.Builder(0)
2142        b.StartObject(0)
2143        s = 'test1'
2144        assertRaises(self, lambda: b.CreateString(s),
2145                     flatbuffers.builder.IsNestedError)
2146
2147    def test_create_byte_vector_is_nested_error(self):
2148        b = flatbuffers.Builder(0)
2149        b.StartObject(0)
2150        s = b'test1'
2151        assertRaises(self, lambda: b.CreateByteVector(s),
2152                     flatbuffers.builder.IsNestedError)
2153
2154    def test_finished_bytes_error(self):
2155        b = flatbuffers.Builder(0)
2156        assertRaises(self, lambda: b.Output(),
2157                     flatbuffers.builder.BuilderNotFinishedError)
2158
2159
2160class TestFixedLengthArrays(unittest.TestCase):
2161    def test_fixed_length_array(self):
2162        builder = flatbuffers.Builder(0)
2163
2164        a = 0.5
2165        b = range(0, 15)
2166        c = 1
2167        d_a = [[1, 2], [3, 4]]
2168        d_b = [MyGame.Example.TestEnum.TestEnum.B, \
2169                MyGame.Example.TestEnum.TestEnum.C]
2170        d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
2171                MyGame.Example.TestEnum.TestEnum.B], \
2172                [MyGame.Example.TestEnum.TestEnum.C, \
2173                 MyGame.Example.TestEnum.TestEnum.B]]
2174        d_d = [[-1, 1], [-2, 2]]
2175        e = 2
2176        f = [-1, 1]
2177
2178        arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
2179            a, b, c, d_a, d_b, d_c, d_d, e, f)
2180
2181        # Create a table with the ArrayStruct.
2182        MyGame.Example.ArrayTable.Start(builder)
2183        MyGame.Example.ArrayTable.AddA(builder, arrayOffset)
2184        tableOffset = MyGame.Example.ArrayTable.End(builder)
2185
2186        builder.Finish(tableOffset)
2187
2188        buf = builder.Output()
2189
2190        table = MyGame.Example.ArrayTable.ArrayTable.GetRootAs(buf)
2191
2192        # Verify structure.
2193        nested = MyGame.Example.NestedStruct.NestedStruct()
2194        self.assertEqual(table.A().A(), 0.5)
2195        self.assertEqual(table.A().B(), \
2196            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
2197        self.assertEqual(table.A().C(), 1)
2198        self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
2199        self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
2200        self.assertEqual(table.A().D(nested, 0).B(), \
2201            MyGame.Example.TestEnum.TestEnum.B)
2202        self.assertEqual(table.A().D(nested, 1).B(), \
2203            MyGame.Example.TestEnum.TestEnum.C)
2204        self.assertEqual(table.A().D(nested, 0).C(), \
2205            [MyGame.Example.TestEnum.TestEnum.A, \
2206             MyGame.Example.TestEnum.TestEnum.B])
2207        self.assertEqual(table.A().D(nested, 1).C(), \
2208            [MyGame.Example.TestEnum.TestEnum.C, \
2209             MyGame.Example.TestEnum.TestEnum.B])
2210        self.assertEqual(table.A().D(nested, 0).D(), [-1, 1])
2211        self.assertEqual(table.A().D(nested, 1).D(), [-2, 2])
2212        self.assertEqual(table.A().E(), 2)
2213        self.assertEqual(table.A().F(), [-1, 1])
2214
2215
2216def CheckAgainstGoldDataGo():
2217    try:
2218        gen_buf, gen_off = make_monster_from_generated_code()
2219        fn = 'monsterdata_go_wire.mon'
2220        if not os.path.exists(fn):
2221            print('Go-generated data does not exist, failed.')
2222            return False
2223
2224        # would like to use a context manager here, but it's less
2225        # backwards-compatible:
2226        f = open(fn, 'rb')
2227        go_wire_data = f.read()
2228        f.close()
2229
2230        CheckReadBuffer(bytearray(go_wire_data), 0)
2231        if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
2232            raise AssertionError('CheckAgainstGoldDataGo failed')
2233    except:
2234        print('Failed to test against Go-generated test data.')
2235        return False
2236
2237    print('Can read Go-generated test data, and Python generates bytewise identical data.')
2238    return True
2239
2240
2241def CheckAgainstGoldDataJava():
2242    try:
2243        gen_buf, gen_off = make_monster_from_generated_code()
2244        fn = 'monsterdata_java_wire.mon'
2245        if not os.path.exists(fn):
2246            print('Java-generated data does not exist, failed.')
2247            return False
2248        f = open(fn, 'rb')
2249        java_wire_data = f.read()
2250        f.close()
2251
2252        CheckReadBuffer(bytearray(java_wire_data), 0)
2253    except:
2254        print('Failed to read Java-generated test data.')
2255        return False
2256
2257    print('Can read Java-generated test data.')
2258    return True
2259
2260
2261class LCG(object):
2262    ''' Include simple random number generator to ensure results will be the
2263        same cross platform.
2264        http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator '''
2265
2266    __slots__ = ['n']
2267
2268    InitialLCGSeed = 48271
2269
2270    def __init__(self):
2271        self.n = self.InitialLCGSeed
2272
2273    def Reset(self):
2274        self.n = self.InitialLCGSeed
2275
2276    def Next(self):
2277        self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
2278        return self.n
2279
2280
2281def BenchmarkVtableDeduplication(count):
2282    '''
2283    BenchmarkVtableDeduplication measures the speed of vtable deduplication
2284    by creating `prePop` vtables, then populating `count` objects with a
2285    different single vtable.
2286
2287    When count is large (as in long benchmarks), memory usage may be high.
2288    '''
2289
2290    for prePop in (1, 10, 100, 1000):
2291        builder = flatbuffers.Builder(0)
2292        n = 1 + int(math.log(prePop, 1.5))
2293
2294        # generate some layouts:
2295        layouts = set()
2296        r = list(compat_range(n))
2297        while len(layouts) < prePop:
2298            layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
2299
2300        layouts = list(layouts)
2301
2302        # pre-populate vtables:
2303        for layout in layouts:
2304            builder.StartObject(n)
2305            for j in layout:
2306                builder.PrependInt16Slot(j, j, 0)
2307            builder.EndObject()
2308
2309        # benchmark deduplication of a new vtable:
2310        def f():
2311            layout = random.choice(layouts)
2312            builder.StartObject(n)
2313            for j in layout:
2314                builder.PrependInt16Slot(j, j, 0)
2315            builder.EndObject()
2316
2317        duration = timeit.timeit(stmt=f, number=count)
2318        rate = float(count) / duration
2319        print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' % (
2320            prePop,
2321            len(builder.vtables),
2322            rate))
2323        )
2324
2325
2326def BenchmarkCheckReadBuffer(count, buf, off):
2327    '''
2328    BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
2329    by re-using the CheckReadBuffer function with the gold data.
2330    '''
2331
2332    def f():
2333        CheckReadBuffer(buf, off)
2334
2335    duration = timeit.timeit(stmt=f, number=count)
2336    rate = float(count) / duration
2337    data = float(len(buf) * count) / float(1024 * 1024)
2338    data_rate = data / float(duration)
2339
2340    print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec')
2341          % (count, len(buf), duration, rate, data_rate))
2342
2343
2344def BenchmarkMakeMonsterFromGeneratedCode(count, length):
2345    '''
2346    BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
2347    creation by re-using the make_monster_from_generated_code function for
2348    generating gold data examples.
2349    '''
2350
2351    duration = timeit.timeit(stmt=make_monster_from_generated_code,
2352                             number=count)
2353    rate = float(count) / duration
2354    data = float(length * count) / float(1024 * 1024)
2355    data_rate = data / float(duration)
2356
2357    print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
2358           (count, length, duration, rate, data_rate)))
2359
2360
2361def backward_compatible_run_tests(**kwargs):
2362    if PY_VERSION < (2, 6):
2363        sys.stderr.write("Python version less than 2.6 are not supported")
2364        sys.stderr.flush()
2365        return False
2366
2367    # python2.6 has a reduced-functionality unittest.main function:
2368    if PY_VERSION == (2, 6):
2369        try:
2370            unittest.main(**kwargs)
2371        except SystemExit as e:
2372            if not e.code == 0:
2373                return False
2374        return True
2375
2376    # python2.7 and above let us not exit once unittest.main is run:
2377    kwargs['exit'] = False
2378    kwargs['verbosity'] = 0
2379    ret = unittest.main(**kwargs)
2380    if ret.result.errors or ret.result.failures:
2381        return False
2382
2383    return True
2384
2385def main():
2386    import os
2387    import sys
2388    if not len(sys.argv) == 4:
2389       sys.stderr.write('Usage: %s <benchmark vtable count>'
2390                        '<benchmark read count> <benchmark build count>\n'
2391                        % sys.argv[0])
2392       sys.stderr.write('       Provide COMPARE_GENERATED_TO_GO=1   to check'
2393                        'for bytewise comparison to Go data.\n')
2394       sys.stderr.write('       Provide COMPARE_GENERATED_TO_JAVA=1 to check'
2395                        'for bytewise comparison to Java data.\n')
2396       sys.stderr.flush()
2397       sys.exit(1)
2398
2399    kwargs = dict(argv=sys.argv[:-3])
2400
2401    # show whether numpy is present, as it changes the test logic:
2402    try:
2403        import numpy
2404        print('numpy available')
2405    except ImportError:
2406        print('numpy not available')
2407
2408    # run tests, and run some language comparison checks if needed:
2409    success = backward_compatible_run_tests(**kwargs)
2410    if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == "1":
2411        success = success and CheckAgainstGoldDataGo()
2412    if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == "1":
2413        success = success and CheckAgainstGoldDataJava()
2414
2415    if not success:
2416        sys.stderr.write('Tests failed, skipping benchmarks.\n')
2417        sys.stderr.flush()
2418        sys.exit(1)
2419
2420    # run benchmarks (if 0, they will be a noop):
2421    bench_vtable = int(sys.argv[1])
2422    bench_traverse = int(sys.argv[2])
2423    bench_build = int(sys.argv[3])
2424    if bench_vtable:
2425        BenchmarkVtableDeduplication(bench_vtable)
2426    if bench_traverse:
2427        buf, off = make_monster_from_generated_code()
2428        BenchmarkCheckReadBuffer(bench_traverse, buf, off)
2429    if bench_build:
2430        buf, off = make_monster_from_generated_code()
2431        BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
2432
2433if __name__ == '__main__':
2434    main()
2435