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