xref: /aosp_15_r20/external/flatbuffers/tests/py_flexbuffers_test.py (revision 890232f25432b36107d06881e0a25aaa6b473652)
1*890232f2SAndroid Build Coastguard Worker# Lint as: python3
2*890232f2SAndroid Build Coastguard Worker# Copyright 2020 Google Inc. All rights reserved.
3*890232f2SAndroid Build Coastguard Worker#
4*890232f2SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*890232f2SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*890232f2SAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*890232f2SAndroid Build Coastguard Worker#
8*890232f2SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
9*890232f2SAndroid Build Coastguard Worker#
10*890232f2SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*890232f2SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
12*890232f2SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*890232f2SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*890232f2SAndroid Build Coastguard Worker# limitations under the License.
15*890232f2SAndroid Build Coastguard Worker"""Unit tests for flexbuffers.py."""
16*890232f2SAndroid Build Coastguard Worker
17*890232f2SAndroid Build Coastguard Workerimport array
18*890232f2SAndroid Build Coastguard Workerimport os.path
19*890232f2SAndroid Build Coastguard Workerimport struct
20*890232f2SAndroid Build Coastguard Workerimport unittest
21*890232f2SAndroid Build Coastguard Worker
22*890232f2SAndroid Build Coastguard Workerfrom flatbuffers import flexbuffers
23*890232f2SAndroid Build Coastguard Worker
24*890232f2SAndroid Build Coastguard WorkerType = flexbuffers.Type
25*890232f2SAndroid Build Coastguard Worker
26*890232f2SAndroid Build Coastguard WorkerLOG2 = {1: 0, 2: 1, 4: 2, 8: 3}
27*890232f2SAndroid Build Coastguard Worker
28*890232f2SAndroid Build Coastguard WorkerGOLD_FLEXBUFFER_OBJ = {
29*890232f2SAndroid Build Coastguard Worker    'bar': [1, 2, 3],
30*890232f2SAndroid Build Coastguard Worker    'bar3': [1, 2, 3],
31*890232f2SAndroid Build Coastguard Worker    'bool': True,
32*890232f2SAndroid Build Coastguard Worker    'bools': [True, False, True, False],
33*890232f2SAndroid Build Coastguard Worker    'foo': 100.0,
34*890232f2SAndroid Build Coastguard Worker    'mymap': {'foo': 'Fred'},
35*890232f2SAndroid Build Coastguard Worker    'vec': [-100, 'Fred', 4.0, b'M', False, 4.0]
36*890232f2SAndroid Build Coastguard Worker}
37*890232f2SAndroid Build Coastguard Worker
38*890232f2SAndroid Build Coastguard WorkerGOLD_FLEXBUFFER_FILE = 'gold_flexbuffer_example.bin'
39*890232f2SAndroid Build Coastguard Worker
40*890232f2SAndroid Build Coastguard Worker
41*890232f2SAndroid Build Coastguard Workerdef read_test_file(name):
42*890232f2SAndroid Build Coastguard Worker  with open(os.path.join(os.path.dirname(__file__), name), 'rb') as f:
43*890232f2SAndroid Build Coastguard Worker    return f.read()
44*890232f2SAndroid Build Coastguard Worker
45*890232f2SAndroid Build Coastguard Worker
46*890232f2SAndroid Build Coastguard Workerdef packed_type(type_, i):
47*890232f2SAndroid Build Coastguard Worker  return (type_ << 2) | LOG2[i]
48*890232f2SAndroid Build Coastguard Worker
49*890232f2SAndroid Build Coastguard Worker
50*890232f2SAndroid Build Coastguard Workerdef uint_size(value):
51*890232f2SAndroid Build Coastguard Worker  """Returns number of bytes (power of two) to represent unsigned value."""
52*890232f2SAndroid Build Coastguard Worker  assert value >= 0
53*890232f2SAndroid Build Coastguard Worker
54*890232f2SAndroid Build Coastguard Worker  n = 8
55*890232f2SAndroid Build Coastguard Worker  while not value < (1 << n):
56*890232f2SAndroid Build Coastguard Worker    n *= 2
57*890232f2SAndroid Build Coastguard Worker  return n // 8
58*890232f2SAndroid Build Coastguard Worker
59*890232f2SAndroid Build Coastguard Worker
60*890232f2SAndroid Build Coastguard Workerdef int_size(value):
61*890232f2SAndroid Build Coastguard Worker  """Returns number of bytes (power of two) to represent signed value."""
62*890232f2SAndroid Build Coastguard Worker  n = 8
63*890232f2SAndroid Build Coastguard Worker  while not -(1 << (n - 1)) <= value < (1 << (n - 1)):
64*890232f2SAndroid Build Coastguard Worker    n *= 2
65*890232f2SAndroid Build Coastguard Worker  return n // 8
66*890232f2SAndroid Build Coastguard Worker
67*890232f2SAndroid Build Coastguard Worker
68*890232f2SAndroid Build Coastguard Workerdef uint_sizes(value):
69*890232f2SAndroid Build Coastguard Worker  return tuple(1 << i for i in range(LOG2[uint_size(value)], 4))
70*890232f2SAndroid Build Coastguard Worker
71*890232f2SAndroid Build Coastguard Worker
72*890232f2SAndroid Build Coastguard Workerdef int_sizes(value):
73*890232f2SAndroid Build Coastguard Worker  return tuple(1 << i for i in range(LOG2[int_size(value)], 4))
74*890232f2SAndroid Build Coastguard Worker
75*890232f2SAndroid Build Coastguard Worker
76*890232f2SAndroid Build Coastguard Workerdef int_bytes(value, byte_width):
77*890232f2SAndroid Build Coastguard Worker  return struct.pack({1: 'b', 2: 'h', 4: 'i', 8: 'q'}[byte_width], value)
78*890232f2SAndroid Build Coastguard Worker
79*890232f2SAndroid Build Coastguard Worker
80*890232f2SAndroid Build Coastguard Workerdef uint_bytes(value, byte_width):
81*890232f2SAndroid Build Coastguard Worker  return struct.pack({1: 'B', 2: 'H', 4: 'I', 8: 'Q'}[byte_width], value)
82*890232f2SAndroid Build Coastguard Worker
83*890232f2SAndroid Build Coastguard Worker
84*890232f2SAndroid Build Coastguard Workerdef float_bytes(value, byte_width):
85*890232f2SAndroid Build Coastguard Worker  return struct.pack({4: 'f', 8: 'd'}[byte_width], value)
86*890232f2SAndroid Build Coastguard Worker
87*890232f2SAndroid Build Coastguard Worker
88*890232f2SAndroid Build Coastguard Workerdef min_value(type_, byte_width):
89*890232f2SAndroid Build Coastguard Worker  assert byte_width > 0
90*890232f2SAndroid Build Coastguard Worker
91*890232f2SAndroid Build Coastguard Worker  if type_ in (Type.INT, Type.INDIRECT_INT):
92*890232f2SAndroid Build Coastguard Worker    return -(1 << (8 * byte_width - 1))
93*890232f2SAndroid Build Coastguard Worker  elif type_ in (Type.UINT, Type.INDIRECT_UINT):
94*890232f2SAndroid Build Coastguard Worker    return 0
95*890232f2SAndroid Build Coastguard Worker  else:
96*890232f2SAndroid Build Coastguard Worker    raise ValueError('Unsupported type %s' % type_)
97*890232f2SAndroid Build Coastguard Worker
98*890232f2SAndroid Build Coastguard Worker
99*890232f2SAndroid Build Coastguard Workerdef max_value(type_, byte_width):
100*890232f2SAndroid Build Coastguard Worker  assert byte_width > 0
101*890232f2SAndroid Build Coastguard Worker
102*890232f2SAndroid Build Coastguard Worker  if type_ in (Type.INT, Type.INDIRECT_INT):
103*890232f2SAndroid Build Coastguard Worker    return (1 << (8 * byte_width - 1)) - 1
104*890232f2SAndroid Build Coastguard Worker  elif type_ in (Type.UINT, Type.INDIRECT_UINT):
105*890232f2SAndroid Build Coastguard Worker    return (1 << 8 * byte_width) - 1
106*890232f2SAndroid Build Coastguard Worker  else:
107*890232f2SAndroid Build Coastguard Worker    raise ValueError('Unsupported type %s' % type_)
108*890232f2SAndroid Build Coastguard Worker
109*890232f2SAndroid Build Coastguard Worker
110*890232f2SAndroid Build Coastguard Workerdef str_bytes(value, byte_width):
111*890232f2SAndroid Build Coastguard Worker  value_bytes = value.encode('utf-8')
112*890232f2SAndroid Build Coastguard Worker  return [*uint_bytes(len(value_bytes), byte_width), *value_bytes, 0]
113*890232f2SAndroid Build Coastguard Worker
114*890232f2SAndroid Build Coastguard Worker
115*890232f2SAndroid Build Coastguard Workerdef key_bytes(value):
116*890232f2SAndroid Build Coastguard Worker  return [*value.encode('ascii'), 0]
117*890232f2SAndroid Build Coastguard Worker
118*890232f2SAndroid Build Coastguard Worker
119*890232f2SAndroid Build Coastguard Workerdef encode_type(type_, value, byte_width=None):
120*890232f2SAndroid Build Coastguard Worker  fbb = flexbuffers.Builder()
121*890232f2SAndroid Build Coastguard Worker  add = fbb.Adder(type_)
122*890232f2SAndroid Build Coastguard Worker  if byte_width:
123*890232f2SAndroid Build Coastguard Worker    add(value, byte_width)
124*890232f2SAndroid Build Coastguard Worker  else:
125*890232f2SAndroid Build Coastguard Worker    add(value)
126*890232f2SAndroid Build Coastguard Worker  return fbb.Finish()
127*890232f2SAndroid Build Coastguard Worker
128*890232f2SAndroid Build Coastguard Worker
129*890232f2SAndroid Build Coastguard WorkerINT_MIN_MAX_VALUES = (min_value(Type.INT, 1), max_value(Type.INT, 1),
130*890232f2SAndroid Build Coastguard Worker                      min_value(Type.INT, 2), max_value(Type.INT, 2),
131*890232f2SAndroid Build Coastguard Worker                      min_value(Type.INT, 4), max_value(Type.INT, 4),
132*890232f2SAndroid Build Coastguard Worker                      min_value(Type.INT, 8), max_value(Type.INT, 8))
133*890232f2SAndroid Build Coastguard Worker
134*890232f2SAndroid Build Coastguard WorkerUINT_MIN_MAX_VALUES = (0, max_value(Type.UINT, 1), max_value(Type.UINT, 2),
135*890232f2SAndroid Build Coastguard Worker                       max_value(Type.UINT, 4), max_value(Type.UINT, 8))
136*890232f2SAndroid Build Coastguard Worker
137*890232f2SAndroid Build Coastguard Worker
138*890232f2SAndroid Build Coastguard Workerclass UtilTest(unittest.TestCase):
139*890232f2SAndroid Build Coastguard Worker  """Tests to check FlexBuffer utility functions."""
140*890232f2SAndroid Build Coastguard Worker
141*890232f2SAndroid Build Coastguard Worker  def _test_type_predicate(self, pred, types):
142*890232f2SAndroid Build Coastguard Worker    for type_ in types:
143*890232f2SAndroid Build Coastguard Worker      with self.subTest(type=type_, pred=pred):
144*890232f2SAndroid Build Coastguard Worker        self.assertTrue(pred(type_))
145*890232f2SAndroid Build Coastguard Worker
146*890232f2SAndroid Build Coastguard Worker    for type_ in set(Type).difference(types):
147*890232f2SAndroid Build Coastguard Worker      with self.subTest(type=type_, pred=pred):
148*890232f2SAndroid Build Coastguard Worker        self.assertFalse(pred(type_))
149*890232f2SAndroid Build Coastguard Worker
150*890232f2SAndroid Build Coastguard Worker  def test_inline_types(self):
151*890232f2SAndroid Build Coastguard Worker    self._test_type_predicate(
152*890232f2SAndroid Build Coastguard Worker        Type.IsInline, (Type.NULL, Type.INT, Type.UINT, Type.FLOAT, Type.BOOL))
153*890232f2SAndroid Build Coastguard Worker
154*890232f2SAndroid Build Coastguard Worker  def test_typed_vector(self):
155*890232f2SAndroid Build Coastguard Worker    self._test_type_predicate(
156*890232f2SAndroid Build Coastguard Worker        Type.IsTypedVector,
157*890232f2SAndroid Build Coastguard Worker        (Type.VECTOR_INT, Type.VECTOR_UINT, Type.VECTOR_FLOAT, Type.VECTOR_KEY,
158*890232f2SAndroid Build Coastguard Worker         Type.VECTOR_STRING_DEPRECATED, Type.VECTOR_BOOL))
159*890232f2SAndroid Build Coastguard Worker
160*890232f2SAndroid Build Coastguard Worker    self._test_type_predicate(
161*890232f2SAndroid Build Coastguard Worker        Type.IsTypedVectorElementType,
162*890232f2SAndroid Build Coastguard Worker        (Type.INT, Type.UINT, Type.FLOAT, Type.KEY, Type.STRING, Type.BOOL))
163*890232f2SAndroid Build Coastguard Worker
164*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(ValueError):
165*890232f2SAndroid Build Coastguard Worker      Type.ToTypedVectorElementType(Type.VECTOR)
166*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVectorElementType(Type.VECTOR_INT), Type.INT)
167*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVectorElementType(Type.VECTOR_UINT), Type.UINT)
168*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVectorElementType(Type.VECTOR_FLOAT), Type.FLOAT)
169*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVectorElementType(Type.VECTOR_KEY), Type.KEY)
170*890232f2SAndroid Build Coastguard Worker    self.assertIs(
171*890232f2SAndroid Build Coastguard Worker        Type.ToTypedVectorElementType(Type.VECTOR_STRING_DEPRECATED),
172*890232f2SAndroid Build Coastguard Worker        Type.STRING)
173*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVectorElementType(Type.VECTOR_BOOL), Type.BOOL)
174*890232f2SAndroid Build Coastguard Worker
175*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(ValueError):
176*890232f2SAndroid Build Coastguard Worker      Type.ToTypedVector(Type.VECTOR)
177*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.INT), Type.VECTOR_INT)
178*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.UINT), Type.VECTOR_UINT)
179*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.FLOAT), Type.VECTOR_FLOAT)
180*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.KEY), Type.VECTOR_KEY)
181*890232f2SAndroid Build Coastguard Worker    self.assertIs(
182*890232f2SAndroid Build Coastguard Worker        Type.ToTypedVector(Type.STRING), Type.VECTOR_STRING_DEPRECATED)
183*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.BOOL), Type.VECTOR_BOOL)
184*890232f2SAndroid Build Coastguard Worker
185*890232f2SAndroid Build Coastguard Worker  def test_fixed_typed_vector(self):
186*890232f2SAndroid Build Coastguard Worker    self._test_type_predicate(
187*890232f2SAndroid Build Coastguard Worker        Type.IsFixedTypedVector,
188*890232f2SAndroid Build Coastguard Worker        (Type.VECTOR_INT2, Type.VECTOR_UINT2, Type.VECTOR_FLOAT2,
189*890232f2SAndroid Build Coastguard Worker         Type.VECTOR_INT3, Type.VECTOR_UINT3, Type.VECTOR_FLOAT3,
190*890232f2SAndroid Build Coastguard Worker         Type.VECTOR_INT4, Type.VECTOR_UINT4, Type.VECTOR_FLOAT4))
191*890232f2SAndroid Build Coastguard Worker
192*890232f2SAndroid Build Coastguard Worker    self._test_type_predicate(Type.IsFixedTypedVectorElementType,
193*890232f2SAndroid Build Coastguard Worker                              (Type.INT, Type.UINT, Type.FLOAT))
194*890232f2SAndroid Build Coastguard Worker
195*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
196*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_INT2), (Type.INT, 2))
197*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
198*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_UINT2), (Type.UINT, 2))
199*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
200*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_FLOAT2), (Type.FLOAT, 2))
201*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
202*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_INT3), (Type.INT, 3))
203*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
204*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_UINT3), (Type.UINT, 3))
205*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
206*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_FLOAT3), (Type.FLOAT, 3))
207*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
208*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_INT4), (Type.INT, 4))
209*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
210*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_UINT4), (Type.UINT, 4))
211*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
212*890232f2SAndroid Build Coastguard Worker        Type.ToFixedTypedVectorElementType(Type.VECTOR_FLOAT4), (Type.FLOAT, 4))
213*890232f2SAndroid Build Coastguard Worker
214*890232f2SAndroid Build Coastguard Worker    # Invalid size
215*890232f2SAndroid Build Coastguard Worker    for type_ in Type.INT, Type.UINT, Type.FLOAT:
216*890232f2SAndroid Build Coastguard Worker      with self.assertRaises(ValueError):
217*890232f2SAndroid Build Coastguard Worker        Type.ToTypedVector(type_, 1)
218*890232f2SAndroid Build Coastguard Worker      with self.assertRaises(ValueError):
219*890232f2SAndroid Build Coastguard Worker        Type.ToTypedVector(type_, 5)
220*890232f2SAndroid Build Coastguard Worker
221*890232f2SAndroid Build Coastguard Worker    # Invalid element type
222*890232f2SAndroid Build Coastguard Worker    for length in 1, 2, 3, 4, 5:
223*890232f2SAndroid Build Coastguard Worker      with self.assertRaises(ValueError):
224*890232f2SAndroid Build Coastguard Worker        Type.ToTypedVector(Type.STRING, length)
225*890232f2SAndroid Build Coastguard Worker
226*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.INT, 2), Type.VECTOR_INT2)
227*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.INT, 3), Type.VECTOR_INT3)
228*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.INT, 4), Type.VECTOR_INT4)
229*890232f2SAndroid Build Coastguard Worker
230*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.UINT, 2), Type.VECTOR_UINT2)
231*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.UINT, 3), Type.VECTOR_UINT3)
232*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.UINT, 4), Type.VECTOR_UINT4)
233*890232f2SAndroid Build Coastguard Worker
234*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.FLOAT, 2), Type.VECTOR_FLOAT2)
235*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.FLOAT, 3), Type.VECTOR_FLOAT3)
236*890232f2SAndroid Build Coastguard Worker    self.assertIs(Type.ToTypedVector(Type.FLOAT, 4), Type.VECTOR_FLOAT4)
237*890232f2SAndroid Build Coastguard Worker
238*890232f2SAndroid Build Coastguard Worker  def test_width(self):
239*890232f2SAndroid Build Coastguard Worker    for x in range(1 << 10):
240*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.BitWidth.U(x), LOG2[uint_size(x)])
241*890232f2SAndroid Build Coastguard Worker
242*890232f2SAndroid Build Coastguard Worker    for x in range(-(1 << 10), 1 << 10):
243*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.BitWidth.I(x), LOG2[int_size(x)])
244*890232f2SAndroid Build Coastguard Worker
245*890232f2SAndroid Build Coastguard Worker  def test_padding(self):
246*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers._PaddingBytes(0, 4), 0)
247*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers._PaddingBytes(0, 8), 0)
248*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers._PaddingBytes(0, 16), 0)
249*890232f2SAndroid Build Coastguard Worker
250*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers._PaddingBytes(1, 8), 7)
251*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers._PaddingBytes(17, 8), 7)
252*890232f2SAndroid Build Coastguard Worker
253*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers._PaddingBytes(42, 2), 0)
254*890232f2SAndroid Build Coastguard Worker
255*890232f2SAndroid Build Coastguard Worker
256*890232f2SAndroid Build Coastguard Workerclass DecoderTest(unittest.TestCase):
257*890232f2SAndroid Build Coastguard Worker  """Tests to check FlexBuffer decoding functions.
258*890232f2SAndroid Build Coastguard Worker
259*890232f2SAndroid Build Coastguard Worker  Common variable names used in the tests for compactness:
260*890232f2SAndroid Build Coastguard Worker    bw: byte_width
261*890232f2SAndroid Build Coastguard Worker    ebw: element_byte_width
262*890232f2SAndroid Build Coastguard Worker    kbw: key_byte_width
263*890232f2SAndroid Build Coastguard Worker    vbw: value_byte_width
264*890232f2SAndroid Build Coastguard Worker    tbw: type_byte_width
265*890232f2SAndroid Build Coastguard Worker
266*890232f2SAndroid Build Coastguard Worker  Having '_ignored' suffix means that variable doesn't affect the constructed
267*890232f2SAndroid Build Coastguard Worker  byte buffer size.
268*890232f2SAndroid Build Coastguard Worker  """
269*890232f2SAndroid Build Coastguard Worker
270*890232f2SAndroid Build Coastguard Worker  def test_null(self):
271*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
272*890232f2SAndroid Build Coastguard Worker      for ebw_ignored in 1, 2, 4, 8:
273*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, ebw_ignored=ebw_ignored):
274*890232f2SAndroid Build Coastguard Worker          data = bytes([
275*890232f2SAndroid Build Coastguard Worker              *uint_bytes(0, bw),
276*890232f2SAndroid Build Coastguard Worker              packed_type(Type.NULL, ebw_ignored),
277*890232f2SAndroid Build Coastguard Worker              bw,
278*890232f2SAndroid Build Coastguard Worker          ])
279*890232f2SAndroid Build Coastguard Worker
280*890232f2SAndroid Build Coastguard Worker          root = flexbuffers.GetRoot(data)
281*890232f2SAndroid Build Coastguard Worker          self.assertTrue(root.IsNull)
282*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.AsBool, False)
283*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.AsInt, 0)
284*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.AsFloat, 0.0)
285*890232f2SAndroid Build Coastguard Worker
286*890232f2SAndroid Build Coastguard Worker          for prop in (type(root).AsKey, type(root).AsString, type(root).AsBlob,
287*890232f2SAndroid Build Coastguard Worker                       type(root).AsVector, type(root).AsTypedVector,
288*890232f2SAndroid Build Coastguard Worker                       type(root).AsFixedTypedVector, type(root).AsMap):
289*890232f2SAndroid Build Coastguard Worker            with self.assertRaises(TypeError):
290*890232f2SAndroid Build Coastguard Worker              prop.fget(root)
291*890232f2SAndroid Build Coastguard Worker
292*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.Value, None)
293*890232f2SAndroid Build Coastguard Worker
294*890232f2SAndroid Build Coastguard Worker          self.assertIsNone(flexbuffers.Loads(data))
295*890232f2SAndroid Build Coastguard Worker
296*890232f2SAndroid Build Coastguard Worker  def test_bool(self):
297*890232f2SAndroid Build Coastguard Worker    for value in False, True:
298*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
299*890232f2SAndroid Build Coastguard Worker        for ebw_ignored in 1, 2, 4, 8:
300*890232f2SAndroid Build Coastguard Worker          with self.subTest(bw=bw, ebw_ignored=ebw_ignored):
301*890232f2SAndroid Build Coastguard Worker            data = bytes([
302*890232f2SAndroid Build Coastguard Worker                *uint_bytes(int(value), bw),
303*890232f2SAndroid Build Coastguard Worker                packed_type(Type.BOOL, ebw_ignored),
304*890232f2SAndroid Build Coastguard Worker                bw,
305*890232f2SAndroid Build Coastguard Worker            ])
306*890232f2SAndroid Build Coastguard Worker
307*890232f2SAndroid Build Coastguard Worker            root = flexbuffers.GetRoot(data)
308*890232f2SAndroid Build Coastguard Worker            self.assertTrue(root.IsBool)
309*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsBool, value)
310*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsInt, int(value))
311*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsFloat, float(value))
312*890232f2SAndroid Build Coastguard Worker
313*890232f2SAndroid Build Coastguard Worker            for prop in (type(root).AsKey, type(root).AsString,
314*890232f2SAndroid Build Coastguard Worker                         type(root).AsBlob,
315*890232f2SAndroid Build Coastguard Worker                         type(root).AsVector, type(root).AsTypedVector,
316*890232f2SAndroid Build Coastguard Worker                         type(root).AsFixedTypedVector, type(root).AsMap):
317*890232f2SAndroid Build Coastguard Worker              with self.assertRaises(TypeError):
318*890232f2SAndroid Build Coastguard Worker                prop.fget(root)
319*890232f2SAndroid Build Coastguard Worker
320*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.Value, value)
321*890232f2SAndroid Build Coastguard Worker
322*890232f2SAndroid Build Coastguard Worker            self.assertEqual(flexbuffers.Loads(data), value)
323*890232f2SAndroid Build Coastguard Worker
324*890232f2SAndroid Build Coastguard Worker  def test_mutate_bool(self):
325*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(flexbuffers.Dumps(True))
326*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsBool)
327*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.AsBool)
328*890232f2SAndroid Build Coastguard Worker
329*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.MutateBool(False))
330*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsBool)
331*890232f2SAndroid Build Coastguard Worker    self.assertFalse(root.AsBool)
332*890232f2SAndroid Build Coastguard Worker
333*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.MutateBool(True))
334*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsBool)
335*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.AsBool)
336*890232f2SAndroid Build Coastguard Worker
337*890232f2SAndroid Build Coastguard Worker  def _check_int(self, data, value):
338*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(data)
339*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsInt)
340*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsInt, value)
341*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsBool, bool(value))
342*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsFloat, float(value))
343*890232f2SAndroid Build Coastguard Worker
344*890232f2SAndroid Build Coastguard Worker    for prop in (type(root).AsKey, type(root).AsString, type(root).AsBlob,
345*890232f2SAndroid Build Coastguard Worker                 type(root).AsVector, type(root).AsTypedVector,
346*890232f2SAndroid Build Coastguard Worker                 type(root).AsFixedTypedVector, type(root).AsMap):
347*890232f2SAndroid Build Coastguard Worker      with self.assertRaises(TypeError):
348*890232f2SAndroid Build Coastguard Worker        prop.fget(root)
349*890232f2SAndroid Build Coastguard Worker
350*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.Value, value)
351*890232f2SAndroid Build Coastguard Worker
352*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), value)
353*890232f2SAndroid Build Coastguard Worker
354*890232f2SAndroid Build Coastguard Worker  def test_int(self):
355*890232f2SAndroid Build Coastguard Worker    for value in (0, 1, -1, 15, -17, *INT_MIN_MAX_VALUES):
356*890232f2SAndroid Build Coastguard Worker      for bw in int_sizes(value):
357*890232f2SAndroid Build Coastguard Worker        for ebw_ignored in 1, 2, 4, 8:
358*890232f2SAndroid Build Coastguard Worker          with self.subTest(value=value, bw=bw, ebw_ignored=ebw_ignored):
359*890232f2SAndroid Build Coastguard Worker            data = bytes([
360*890232f2SAndroid Build Coastguard Worker                *int_bytes(value, bw),
361*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INT, ebw_ignored),
362*890232f2SAndroid Build Coastguard Worker                bw,
363*890232f2SAndroid Build Coastguard Worker            ])
364*890232f2SAndroid Build Coastguard Worker
365*890232f2SAndroid Build Coastguard Worker            self._check_int(data, value)
366*890232f2SAndroid Build Coastguard Worker
367*890232f2SAndroid Build Coastguard Worker  def test_indirect_int(self):
368*890232f2SAndroid Build Coastguard Worker    for value in (0, 1, -1, 15, -17, *INT_MIN_MAX_VALUES):
369*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
370*890232f2SAndroid Build Coastguard Worker        for ebw in int_sizes(value):
371*890232f2SAndroid Build Coastguard Worker          with self.subTest(value=value, bw=bw, ebw=ebw):
372*890232f2SAndroid Build Coastguard Worker            data = bytes([
373*890232f2SAndroid Build Coastguard Worker                # Int
374*890232f2SAndroid Build Coastguard Worker                *int_bytes(value, ebw),
375*890232f2SAndroid Build Coastguard Worker                # Root
376*890232f2SAndroid Build Coastguard Worker                *uint_bytes(ebw, bw),
377*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INDIRECT_INT, ebw),
378*890232f2SAndroid Build Coastguard Worker                bw,
379*890232f2SAndroid Build Coastguard Worker            ])
380*890232f2SAndroid Build Coastguard Worker            self._check_int(data, value)
381*890232f2SAndroid Build Coastguard Worker
382*890232f2SAndroid Build Coastguard Worker  def test_uint(self):
383*890232f2SAndroid Build Coastguard Worker    for value in (1, *UINT_MIN_MAX_VALUES):
384*890232f2SAndroid Build Coastguard Worker      for bw in uint_sizes(value):
385*890232f2SAndroid Build Coastguard Worker        for ebw_ignored in 1, 2, 4, 8:
386*890232f2SAndroid Build Coastguard Worker          with self.subTest(value=value, bw=bw, ebw_ignored=ebw_ignored):
387*890232f2SAndroid Build Coastguard Worker            data = bytes([
388*890232f2SAndroid Build Coastguard Worker                *uint_bytes(value, bw),
389*890232f2SAndroid Build Coastguard Worker                packed_type(Type.UINT, ebw_ignored),
390*890232f2SAndroid Build Coastguard Worker                bw,
391*890232f2SAndroid Build Coastguard Worker            ])
392*890232f2SAndroid Build Coastguard Worker
393*890232f2SAndroid Build Coastguard Worker            self._check_int(data, value)
394*890232f2SAndroid Build Coastguard Worker
395*890232f2SAndroid Build Coastguard Worker  def test_inidirect_uint(self):
396*890232f2SAndroid Build Coastguard Worker    for value in (1, *UINT_MIN_MAX_VALUES):
397*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
398*890232f2SAndroid Build Coastguard Worker        for ebw in uint_sizes(value):
399*890232f2SAndroid Build Coastguard Worker          with self.subTest(value=value, bw=bw, ebw=ebw):
400*890232f2SAndroid Build Coastguard Worker            data = bytes([
401*890232f2SAndroid Build Coastguard Worker                # UInt
402*890232f2SAndroid Build Coastguard Worker                *uint_bytes(value, ebw),
403*890232f2SAndroid Build Coastguard Worker                # Root
404*890232f2SAndroid Build Coastguard Worker                *uint_bytes(ebw, bw),
405*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INDIRECT_UINT, ebw),
406*890232f2SAndroid Build Coastguard Worker                bw,
407*890232f2SAndroid Build Coastguard Worker            ])
408*890232f2SAndroid Build Coastguard Worker
409*890232f2SAndroid Build Coastguard Worker            self._check_int(data, value)
410*890232f2SAndroid Build Coastguard Worker
411*890232f2SAndroid Build Coastguard Worker  def test_mutate_ints(self):
412*890232f2SAndroid Build Coastguard Worker    # Signed
413*890232f2SAndroid Build Coastguard Worker    for type_ in Type.INT, Type.INDIRECT_INT:
414*890232f2SAndroid Build Coastguard Worker      with self.subTest(type=type_):
415*890232f2SAndroid Build Coastguard Worker        root = flexbuffers.GetRoot(encode_type(type_, 56))
416*890232f2SAndroid Build Coastguard Worker        self.assertEqual(root.AsInt, 56)
417*890232f2SAndroid Build Coastguard Worker
418*890232f2SAndroid Build Coastguard Worker        for new_value in 0, 1, -1, -128, 127:
419*890232f2SAndroid Build Coastguard Worker          self.assertTrue(root.MutateInt(new_value))
420*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.AsInt, new_value)
421*890232f2SAndroid Build Coastguard Worker
422*890232f2SAndroid Build Coastguard Worker        for new_value in -129, 128:
423*890232f2SAndroid Build Coastguard Worker          self.assertFalse(root.MutateInt(new_value))
424*890232f2SAndroid Build Coastguard Worker
425*890232f2SAndroid Build Coastguard Worker    # Unsigned
426*890232f2SAndroid Build Coastguard Worker    for type_ in Type.UINT, Type.INDIRECT_UINT:
427*890232f2SAndroid Build Coastguard Worker      with self.subTest(type=type_):
428*890232f2SAndroid Build Coastguard Worker        root = flexbuffers.GetRoot(encode_type(type_, 1))
429*890232f2SAndroid Build Coastguard Worker        self.assertEqual(root.AsInt, 1)
430*890232f2SAndroid Build Coastguard Worker
431*890232f2SAndroid Build Coastguard Worker        for new_value in 0, 1, 255:
432*890232f2SAndroid Build Coastguard Worker          self.assertTrue(root.MutateInt(new_value))
433*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.AsInt, new_value)
434*890232f2SAndroid Build Coastguard Worker
435*890232f2SAndroid Build Coastguard Worker        self.assertFalse(root.MutateInt(256))
436*890232f2SAndroid Build Coastguard Worker
437*890232f2SAndroid Build Coastguard Worker    # Inside vector
438*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
439*890232f2SAndroid Build Coastguard Worker    fbb.VectorFromElements([13, 0, -15])
440*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
441*890232f2SAndroid Build Coastguard Worker
442*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), [13, 0, -15])
443*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsVector[0].MutateInt(0))
444*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsVector[1].MutateInt(-7))
445*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsVector[2].MutateInt(45))
446*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), [0, -7, 45])
447*890232f2SAndroid Build Coastguard Worker
448*890232f2SAndroid Build Coastguard Worker    # Inside map
449*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
450*890232f2SAndroid Build Coastguard Worker    fbb.MapFromElements({'x': -7, 'y': 46})
451*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
452*890232f2SAndroid Build Coastguard Worker
453*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), {'x': -7, 'y': 46})
454*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsMap['x'].MutateInt(14))
455*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsMap['y'].MutateInt(-1))
456*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), {'x': 14, 'y': -1})
457*890232f2SAndroid Build Coastguard Worker
458*890232f2SAndroid Build Coastguard Worker  def _check_float(self, data, value):
459*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(data)
460*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsFloat)
461*890232f2SAndroid Build Coastguard Worker    self.assertAlmostEqual(root.AsFloat, value)
462*890232f2SAndroid Build Coastguard Worker
463*890232f2SAndroid Build Coastguard Worker    for prop in (type(root).AsKey, type(root).AsString, type(root).AsBlob,
464*890232f2SAndroid Build Coastguard Worker                 type(root).AsVector, type(root).AsTypedVector,
465*890232f2SAndroid Build Coastguard Worker                 type(root).AsFixedTypedVector, type(root).AsMap):
466*890232f2SAndroid Build Coastguard Worker      with self.assertRaises(TypeError):
467*890232f2SAndroid Build Coastguard Worker        prop.fget(root)
468*890232f2SAndroid Build Coastguard Worker
469*890232f2SAndroid Build Coastguard Worker    self.assertAlmostEqual(root.Value, value)
470*890232f2SAndroid Build Coastguard Worker
471*890232f2SAndroid Build Coastguard Worker    self.assertAlmostEqual(flexbuffers.Loads(data), value)
472*890232f2SAndroid Build Coastguard Worker
473*890232f2SAndroid Build Coastguard Worker  def test_float(self):
474*890232f2SAndroid Build Coastguard Worker    for value in -1.0, 0.0, 1.0, 3.141592, 1.5e6:
475*890232f2SAndroid Build Coastguard Worker      for bw in 4, 8:
476*890232f2SAndroid Build Coastguard Worker        for ebw_ignored in 1, 2, 4, 8:
477*890232f2SAndroid Build Coastguard Worker          with self.subTest(value=value, bw=bw, ebw_ignored=ebw_ignored):
478*890232f2SAndroid Build Coastguard Worker            data = bytes([
479*890232f2SAndroid Build Coastguard Worker                *float_bytes(value, bw),
480*890232f2SAndroid Build Coastguard Worker                packed_type(Type.FLOAT, ebw_ignored),
481*890232f2SAndroid Build Coastguard Worker                bw,
482*890232f2SAndroid Build Coastguard Worker            ])
483*890232f2SAndroid Build Coastguard Worker
484*890232f2SAndroid Build Coastguard Worker            self._check_float(data, value)
485*890232f2SAndroid Build Coastguard Worker
486*890232f2SAndroid Build Coastguard Worker  def test_indirect_float(self):
487*890232f2SAndroid Build Coastguard Worker    for value in -1.0, 0.0, 1.0, 3.141592, 1.5e6:
488*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
489*890232f2SAndroid Build Coastguard Worker        for ebw in 4, 8:
490*890232f2SAndroid Build Coastguard Worker          with self.subTest(value=value, bw=bw, ebw=ebw):
491*890232f2SAndroid Build Coastguard Worker            data = bytes([
492*890232f2SAndroid Build Coastguard Worker                # Float
493*890232f2SAndroid Build Coastguard Worker                *float_bytes(value, ebw),
494*890232f2SAndroid Build Coastguard Worker                # Root
495*890232f2SAndroid Build Coastguard Worker                *uint_bytes(ebw, bw),
496*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INDIRECT_FLOAT, ebw),
497*890232f2SAndroid Build Coastguard Worker                bw,
498*890232f2SAndroid Build Coastguard Worker            ])
499*890232f2SAndroid Build Coastguard Worker
500*890232f2SAndroid Build Coastguard Worker            self._check_float(data, value)
501*890232f2SAndroid Build Coastguard Worker
502*890232f2SAndroid Build Coastguard Worker  def test_mutate_float(self):
503*890232f2SAndroid Build Coastguard Worker    for type_ in Type.FLOAT, Type.INDIRECT_FLOAT:
504*890232f2SAndroid Build Coastguard Worker      for bw in 4, 8:
505*890232f2SAndroid Build Coastguard Worker        value = 3.141592
506*890232f2SAndroid Build Coastguard Worker        root = flexbuffers.GetRoot(encode_type(type_, value, bw))
507*890232f2SAndroid Build Coastguard Worker        self.assertAlmostEqual(root.AsFloat, value)
508*890232f2SAndroid Build Coastguard Worker
509*890232f2SAndroid Build Coastguard Worker        value = 2.71828
510*890232f2SAndroid Build Coastguard Worker        self.assertTrue(root.MutateFloat(value))
511*890232f2SAndroid Build Coastguard Worker        self.assertAlmostEqual(root.AsFloat, value, places=5)
512*890232f2SAndroid Build Coastguard Worker
513*890232f2SAndroid Build Coastguard Worker    # Inside vector
514*890232f2SAndroid Build Coastguard Worker    data = flexbuffers.Dumps([2.4, 1.5, -7.2])
515*890232f2SAndroid Build Coastguard Worker
516*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsVector[0].MutateFloat(0.0))
517*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsVector[1].MutateFloat(15.2))
518*890232f2SAndroid Build Coastguard Worker    self.assertTrue(flexbuffers.GetRoot(data).AsVector[2].MutateFloat(-5.1))
519*890232f2SAndroid Build Coastguard Worker
520*890232f2SAndroid Build Coastguard Worker    for a, b in zip(flexbuffers.Loads(data), [0.0, 15.2, -5.1]):
521*890232f2SAndroid Build Coastguard Worker      self.assertAlmostEqual(a, b)
522*890232f2SAndroid Build Coastguard Worker
523*890232f2SAndroid Build Coastguard Worker  def test_string(self):
524*890232f2SAndroid Build Coastguard Worker    for value in 'red', 'green', 'blue', 'flatbuffers + flexbuffers':
525*890232f2SAndroid Build Coastguard Worker      value_bytes = value.encode('utf-8')
526*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
527*890232f2SAndroid Build Coastguard Worker        for lbw in 1, 2, 4, 8:
528*890232f2SAndroid Build Coastguard Worker          with self.subTest(bw=bw, lbw=lbw):
529*890232f2SAndroid Build Coastguard Worker            data = bytes([
530*890232f2SAndroid Build Coastguard Worker                # String
531*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(value_bytes), lbw),
532*890232f2SAndroid Build Coastguard Worker                *value_bytes,
533*890232f2SAndroid Build Coastguard Worker                0,
534*890232f2SAndroid Build Coastguard Worker                # Root
535*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(value_bytes) + 1, bw),  # offset
536*890232f2SAndroid Build Coastguard Worker                packed_type(Type.STRING, lbw),
537*890232f2SAndroid Build Coastguard Worker                bw,
538*890232f2SAndroid Build Coastguard Worker            ])
539*890232f2SAndroid Build Coastguard Worker
540*890232f2SAndroid Build Coastguard Worker            root = flexbuffers.GetRoot(data)
541*890232f2SAndroid Build Coastguard Worker            self.assertTrue(root.IsString)
542*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsString, value)
543*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.Value, value)
544*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsInt, len(value))
545*890232f2SAndroid Build Coastguard Worker
546*890232f2SAndroid Build Coastguard Worker            self.assertEqual(flexbuffers.Loads(data), value)
547*890232f2SAndroid Build Coastguard Worker
548*890232f2SAndroid Build Coastguard Worker  def test_mutate_string(self):
549*890232f2SAndroid Build Coastguard Worker    data = encode_type(Type.STRING, '12345')
550*890232f2SAndroid Build Coastguard Worker
551*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(data)
552*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsString)
553*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsString, '12345')
554*890232f2SAndroid Build Coastguard Worker
555*890232f2SAndroid Build Coastguard Worker    self.assertFalse(root.MutateString('543210'))
556*890232f2SAndroid Build Coastguard Worker
557*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.MutateString('54321'))
558*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsString)
559*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsString, '54321')
560*890232f2SAndroid Build Coastguard Worker
561*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.MutateString('543'))
562*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsString)
563*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsString, '543')
564*890232f2SAndroid Build Coastguard Worker
565*890232f2SAndroid Build Coastguard Worker    self.assertFalse(root.MutateString('54321'))
566*890232f2SAndroid Build Coastguard Worker
567*890232f2SAndroid Build Coastguard Worker  def test_empty_blob(self):
568*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
569*890232f2SAndroid Build Coastguard Worker      for lbw in 1, 2, 4, 8:
570*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, lbw=lbw):
571*890232f2SAndroid Build Coastguard Worker          data = bytes([
572*890232f2SAndroid Build Coastguard Worker              # Blob
573*890232f2SAndroid Build Coastguard Worker              *uint_bytes(0, lbw),
574*890232f2SAndroid Build Coastguard Worker              # Root
575*890232f2SAndroid Build Coastguard Worker              *uint_bytes(0, bw),
576*890232f2SAndroid Build Coastguard Worker              packed_type(Type.BLOB, lbw),
577*890232f2SAndroid Build Coastguard Worker              bw,
578*890232f2SAndroid Build Coastguard Worker          ])
579*890232f2SAndroid Build Coastguard Worker
580*890232f2SAndroid Build Coastguard Worker          root = flexbuffers.GetRoot(data)
581*890232f2SAndroid Build Coastguard Worker          self.assertTrue(root.IsBlob)
582*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.AsBlob, bytes())
583*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.Value, bytes())
584*890232f2SAndroid Build Coastguard Worker          self.assertEqual(flexbuffers.Loads(data), bytes())
585*890232f2SAndroid Build Coastguard Worker
586*890232f2SAndroid Build Coastguard Worker  def test_blob(self):
587*890232f2SAndroid Build Coastguard Worker    for blob in [], [215], [23, 75, 124, 0, 45, 15], 255 * [0]:
588*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
589*890232f2SAndroid Build Coastguard Worker        for lbw in 1, 2, 4, 8:
590*890232f2SAndroid Build Coastguard Worker          with self.subTest(blob=blob, bw=bw, lbw=lbw):
591*890232f2SAndroid Build Coastguard Worker            data = bytes([
592*890232f2SAndroid Build Coastguard Worker                # Blob
593*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(blob), lbw),
594*890232f2SAndroid Build Coastguard Worker                *blob,
595*890232f2SAndroid Build Coastguard Worker                # Root
596*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(blob), bw),
597*890232f2SAndroid Build Coastguard Worker                packed_type(Type.BLOB, lbw),
598*890232f2SAndroid Build Coastguard Worker                bw,
599*890232f2SAndroid Build Coastguard Worker            ])
600*890232f2SAndroid Build Coastguard Worker
601*890232f2SAndroid Build Coastguard Worker            root = flexbuffers.GetRoot(data)
602*890232f2SAndroid Build Coastguard Worker            self.assertTrue(root.IsBlob)
603*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsBlob, bytes(blob))
604*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.Value, bytes(blob))
605*890232f2SAndroid Build Coastguard Worker            self.assertEqual(flexbuffers.Loads(data), bytes(blob))
606*890232f2SAndroid Build Coastguard Worker
607*890232f2SAndroid Build Coastguard Worker  def test_key(self):
608*890232f2SAndroid Build Coastguard Worker    for value in '', 'x', 'color':
609*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
610*890232f2SAndroid Build Coastguard Worker        with self.subTest(value=value, bw=bw):
611*890232f2SAndroid Build Coastguard Worker          value_bytes = value.encode('ascii')
612*890232f2SAndroid Build Coastguard Worker          data = bytes([
613*890232f2SAndroid Build Coastguard Worker              # Key
614*890232f2SAndroid Build Coastguard Worker              *value_bytes,
615*890232f2SAndroid Build Coastguard Worker              0,
616*890232f2SAndroid Build Coastguard Worker              # Root
617*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(value_bytes) + 1, bw),
618*890232f2SAndroid Build Coastguard Worker              packed_type(Type.KEY, 1),
619*890232f2SAndroid Build Coastguard Worker              bw,
620*890232f2SAndroid Build Coastguard Worker          ])
621*890232f2SAndroid Build Coastguard Worker
622*890232f2SAndroid Build Coastguard Worker          root = flexbuffers.GetRoot(data)
623*890232f2SAndroid Build Coastguard Worker          self.assertTrue(root.IsKey)
624*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.AsKey, value)
625*890232f2SAndroid Build Coastguard Worker          self.assertEqual(root.Value, value)
626*890232f2SAndroid Build Coastguard Worker          self.assertEqual(flexbuffers.Loads(data), value)
627*890232f2SAndroid Build Coastguard Worker
628*890232f2SAndroid Build Coastguard Worker  def _check_fixed_typed_vector(self, data, vector, type_):
629*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), vector)
630*890232f2SAndroid Build Coastguard Worker
631*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(data)
632*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsFixedTypedVector)
633*890232f2SAndroid Build Coastguard Worker
634*890232f2SAndroid Build Coastguard Worker    v = root.AsFixedTypedVector
635*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(v), len(vector))
636*890232f2SAndroid Build Coastguard Worker    self.assertIs(v.ElementType, type_)
637*890232f2SAndroid Build Coastguard Worker    self.assertEqual([e.Value for e in v], vector)
638*890232f2SAndroid Build Coastguard Worker    self.assertSequenceEqual(v.Value, vector)
639*890232f2SAndroid Build Coastguard Worker
640*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsInt, len(vector))
641*890232f2SAndroid Build Coastguard Worker
642*890232f2SAndroid Build Coastguard Worker  def test_fixed_typed_vector_float(self):
643*890232f2SAndroid Build Coastguard Worker    for type_, vector in ((Type.VECTOR_FLOAT2, [-75.0, 34.89]),
644*890232f2SAndroid Build Coastguard Worker                          (Type.VECTOR_FLOAT3, [-75.0, 34.89, 12.0]),
645*890232f2SAndroid Build Coastguard Worker                          (Type.VECTOR_FLOAT4, [-75.0, 34.89, -1.0, 1.0])):
646*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
647*890232f2SAndroid Build Coastguard Worker        for ebw in 4, 8:
648*890232f2SAndroid Build Coastguard Worker          with self.subTest(type=type_, vector=vector, bw=bw, ebw=ebw):
649*890232f2SAndroid Build Coastguard Worker            data = bytes([
650*890232f2SAndroid Build Coastguard Worker                # FixedTypedVector
651*890232f2SAndroid Build Coastguard Worker                *b''.join(float_bytes(e, ebw) for e in vector),
652*890232f2SAndroid Build Coastguard Worker                # Root
653*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(vector) * ebw, bw),
654*890232f2SAndroid Build Coastguard Worker                packed_type(type_, ebw),
655*890232f2SAndroid Build Coastguard Worker                bw,
656*890232f2SAndroid Build Coastguard Worker            ])
657*890232f2SAndroid Build Coastguard Worker
658*890232f2SAndroid Build Coastguard Worker            for a, b in zip(flexbuffers.Loads(data), vector):
659*890232f2SAndroid Build Coastguard Worker              self.assertAlmostEqual(a, b, places=2)
660*890232f2SAndroid Build Coastguard Worker
661*890232f2SAndroid Build Coastguard Worker  def test_fixed_typed_vector_int(self):
662*890232f2SAndroid Build Coastguard Worker    for type_, vector in ((Type.VECTOR_INT2, [0, -13]), (Type.VECTOR_INT3,
663*890232f2SAndroid Build Coastguard Worker                                                         [127, 0, -13]),
664*890232f2SAndroid Build Coastguard Worker                          (Type.VECTOR_INT4, [127, 0, -13, 0])):
665*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
666*890232f2SAndroid Build Coastguard Worker        for ebw in 1, 2, 4, 8:
667*890232f2SAndroid Build Coastguard Worker          with self.subTest(type=type_, vector=vector, bw=bw, ebw=ebw):
668*890232f2SAndroid Build Coastguard Worker            data = bytes([
669*890232f2SAndroid Build Coastguard Worker                # FixedTypeVector
670*890232f2SAndroid Build Coastguard Worker                *b''.join(int_bytes(e, ebw) for e in vector),
671*890232f2SAndroid Build Coastguard Worker                # Root
672*890232f2SAndroid Build Coastguard Worker                *uint_bytes(ebw * len(vector), bw),
673*890232f2SAndroid Build Coastguard Worker                packed_type(type_, ebw),
674*890232f2SAndroid Build Coastguard Worker                bw,
675*890232f2SAndroid Build Coastguard Worker            ])
676*890232f2SAndroid Build Coastguard Worker
677*890232f2SAndroid Build Coastguard Worker            self._check_fixed_typed_vector(data, vector, Type.INT)
678*890232f2SAndroid Build Coastguard Worker
679*890232f2SAndroid Build Coastguard Worker  def test_fixed_typed_vector_uint(self):
680*890232f2SAndroid Build Coastguard Worker    for type_, vector in ((Type.VECTOR_UINT2, [0, 13]),
681*890232f2SAndroid Build Coastguard Worker                          (Type.VECTOR_UINT3, [127, 0, 13]), (Type.VECTOR_UINT4,
682*890232f2SAndroid Build Coastguard Worker                                                              [127, 0, 13, 0])):
683*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
684*890232f2SAndroid Build Coastguard Worker        for ebw in 1, 2, 4, 8:
685*890232f2SAndroid Build Coastguard Worker          with self.subTest(type=type_, vector=vector, bw=bw, ebw=ebw):
686*890232f2SAndroid Build Coastguard Worker            data = bytes([
687*890232f2SAndroid Build Coastguard Worker                # FixedTypeVector
688*890232f2SAndroid Build Coastguard Worker                *b''.join(uint_bytes(e, ebw) for e in vector),
689*890232f2SAndroid Build Coastguard Worker                # Root
690*890232f2SAndroid Build Coastguard Worker                *uint_bytes(ebw * len(vector), bw),
691*890232f2SAndroid Build Coastguard Worker                packed_type(type_, ebw),
692*890232f2SAndroid Build Coastguard Worker                bw,
693*890232f2SAndroid Build Coastguard Worker            ])
694*890232f2SAndroid Build Coastguard Worker
695*890232f2SAndroid Build Coastguard Worker            self._check_fixed_typed_vector(data, vector, Type.UINT)
696*890232f2SAndroid Build Coastguard Worker
697*890232f2SAndroid Build Coastguard Worker  def _check_typed_vector(self, data, vector, type_):
698*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), vector)
699*890232f2SAndroid Build Coastguard Worker
700*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(data)
701*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsTypedVector)
702*890232f2SAndroid Build Coastguard Worker
703*890232f2SAndroid Build Coastguard Worker    v = root.AsTypedVector
704*890232f2SAndroid Build Coastguard Worker    self.assertIs(v.ElementType, type_)
705*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(v), len(vector))
706*890232f2SAndroid Build Coastguard Worker    self.assertEqual([e.Value for e in v], vector)
707*890232f2SAndroid Build Coastguard Worker    self.assertSequenceEqual(v.Value, vector)
708*890232f2SAndroid Build Coastguard Worker
709*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsInt, len(vector))
710*890232f2SAndroid Build Coastguard Worker
711*890232f2SAndroid Build Coastguard Worker  def test_empty_typed_vector(self):
712*890232f2SAndroid Build Coastguard Worker    for type_ in (Type.VECTOR_BOOL, Type.VECTOR_INT, Type.VECTOR_UINT,
713*890232f2SAndroid Build Coastguard Worker                  Type.VECTOR_FLOAT, Type.VECTOR_KEY,
714*890232f2SAndroid Build Coastguard Worker                  Type.VECTOR_STRING_DEPRECATED):
715*890232f2SAndroid Build Coastguard Worker      for bw in 1, 2, 4, 8:
716*890232f2SAndroid Build Coastguard Worker        for ebw in 1, 2, 4, 8:
717*890232f2SAndroid Build Coastguard Worker          with self.subTest(type=type_, bw=bw, ebw=ebw):
718*890232f2SAndroid Build Coastguard Worker            data = bytes([
719*890232f2SAndroid Build Coastguard Worker                # TypedVector[type_]
720*890232f2SAndroid Build Coastguard Worker                *uint_bytes(0, ebw),
721*890232f2SAndroid Build Coastguard Worker                # Root
722*890232f2SAndroid Build Coastguard Worker                *uint_bytes(0, bw),
723*890232f2SAndroid Build Coastguard Worker                packed_type(type_, ebw),
724*890232f2SAndroid Build Coastguard Worker                bw
725*890232f2SAndroid Build Coastguard Worker            ])
726*890232f2SAndroid Build Coastguard Worker
727*890232f2SAndroid Build Coastguard Worker            element_type = Type.ToTypedVectorElementType(type_)
728*890232f2SAndroid Build Coastguard Worker            if element_type == Type.STRING:
729*890232f2SAndroid Build Coastguard Worker              element_type = Type.KEY
730*890232f2SAndroid Build Coastguard Worker            self._check_typed_vector(data, [], element_type)
731*890232f2SAndroid Build Coastguard Worker
732*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_bool(self):
733*890232f2SAndroid Build Coastguard Worker    vector = [True, False, False, False, True]
734*890232f2SAndroid Build Coastguard Worker
735*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
736*890232f2SAndroid Build Coastguard Worker      for ebw in 1, 2, 4, 8:
737*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, ebw=ebw):
738*890232f2SAndroid Build Coastguard Worker          data = bytes([
739*890232f2SAndroid Build Coastguard Worker              # TypedVector[Type.BOOL]
740*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector), ebw),
741*890232f2SAndroid Build Coastguard Worker              *b''.join(uint_bytes(int(e), ebw) for e in vector),
742*890232f2SAndroid Build Coastguard Worker              # Root
743*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector) * ebw, bw),
744*890232f2SAndroid Build Coastguard Worker              packed_type(Type.VECTOR_BOOL, ebw),
745*890232f2SAndroid Build Coastguard Worker              bw,
746*890232f2SAndroid Build Coastguard Worker          ])
747*890232f2SAndroid Build Coastguard Worker          self._check_typed_vector(data, vector, Type.BOOL)
748*890232f2SAndroid Build Coastguard Worker
749*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_int(self):
750*890232f2SAndroid Build Coastguard Worker    vector = [-100, 200, -300]
751*890232f2SAndroid Build Coastguard Worker
752*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
753*890232f2SAndroid Build Coastguard Worker      for ebw in 2, 4, 8:
754*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, ebw=ebw):
755*890232f2SAndroid Build Coastguard Worker          data = bytes([
756*890232f2SAndroid Build Coastguard Worker              # TypedVector[Type.INT]
757*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector), ebw),
758*890232f2SAndroid Build Coastguard Worker              *b''.join(int_bytes(e, ebw) for e in vector),
759*890232f2SAndroid Build Coastguard Worker              # Root
760*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector) * ebw, bw),
761*890232f2SAndroid Build Coastguard Worker              packed_type(Type.VECTOR_INT, ebw),
762*890232f2SAndroid Build Coastguard Worker              bw,
763*890232f2SAndroid Build Coastguard Worker          ])
764*890232f2SAndroid Build Coastguard Worker          self._check_typed_vector(data, vector, Type.INT)
765*890232f2SAndroid Build Coastguard Worker
766*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_uint(self):
767*890232f2SAndroid Build Coastguard Worker    vector = [100, 200, 300, 400, 0]
768*890232f2SAndroid Build Coastguard Worker
769*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
770*890232f2SAndroid Build Coastguard Worker      for ebw in 2, 4, 8:
771*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, ebw=ebw):
772*890232f2SAndroid Build Coastguard Worker          data = bytes([
773*890232f2SAndroid Build Coastguard Worker              # TypedVector[Type.UINT]
774*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector), ebw),
775*890232f2SAndroid Build Coastguard Worker              *b''.join(int_bytes(e, ebw) for e in vector),
776*890232f2SAndroid Build Coastguard Worker              # Root
777*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector) * ebw, bw),
778*890232f2SAndroid Build Coastguard Worker              packed_type(Type.VECTOR_UINT, ebw),
779*890232f2SAndroid Build Coastguard Worker              bw,
780*890232f2SAndroid Build Coastguard Worker          ])
781*890232f2SAndroid Build Coastguard Worker          self._check_typed_vector(data, vector, Type.UINT)
782*890232f2SAndroid Build Coastguard Worker
783*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_float(self):
784*890232f2SAndroid Build Coastguard Worker    vector = [3.64, -6.36, 3.14, 634.0, -42.0]
785*890232f2SAndroid Build Coastguard Worker
786*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
787*890232f2SAndroid Build Coastguard Worker      for ebw in 4, 8:
788*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, ebw=ebw):
789*890232f2SAndroid Build Coastguard Worker          data = bytes([
790*890232f2SAndroid Build Coastguard Worker              # TypedVector[Type.FLOAT]
791*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector), ebw),
792*890232f2SAndroid Build Coastguard Worker              *b''.join(float_bytes(e, ebw) for e in vector),
793*890232f2SAndroid Build Coastguard Worker              # Root
794*890232f2SAndroid Build Coastguard Worker              *uint_bytes(ebw * len(vector), bw),
795*890232f2SAndroid Build Coastguard Worker              packed_type(Type.VECTOR_FLOAT, ebw),
796*890232f2SAndroid Build Coastguard Worker              bw,
797*890232f2SAndroid Build Coastguard Worker          ])
798*890232f2SAndroid Build Coastguard Worker
799*890232f2SAndroid Build Coastguard Worker          for a, b in zip(flexbuffers.Loads(data), vector):
800*890232f2SAndroid Build Coastguard Worker            self.assertAlmostEqual(a, b, places=2)
801*890232f2SAndroid Build Coastguard Worker
802*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_key(self):
803*890232f2SAndroid Build Coastguard Worker    vector = ['red', 'green', 'blue']
804*890232f2SAndroid Build Coastguard Worker
805*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
806*890232f2SAndroid Build Coastguard Worker      for ebw in 1, 2, 4, 8:
807*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, ebw=ebw):
808*890232f2SAndroid Build Coastguard Worker          data = bytes([
809*890232f2SAndroid Build Coastguard Worker              # Keys
810*890232f2SAndroid Build Coastguard Worker              *key_bytes(vector[0]),
811*890232f2SAndroid Build Coastguard Worker              *key_bytes(vector[1]),
812*890232f2SAndroid Build Coastguard Worker              *key_bytes(vector[2]),
813*890232f2SAndroid Build Coastguard Worker              # TypedVector[Type.KEY]
814*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector), ebw),
815*890232f2SAndroid Build Coastguard Worker              *uint_bytes(15 + 1 * ebw, ebw),  # offset to vector[0]
816*890232f2SAndroid Build Coastguard Worker              *uint_bytes(11 + 2 * ebw, ebw),  # offset to vector[1]
817*890232f2SAndroid Build Coastguard Worker              *uint_bytes(5 + 3 * ebw, ebw),  # offset to vector[2]
818*890232f2SAndroid Build Coastguard Worker              # Root
819*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector) * ebw, bw),  # offset to vector
820*890232f2SAndroid Build Coastguard Worker              packed_type(Type.VECTOR_KEY, ebw),
821*890232f2SAndroid Build Coastguard Worker              bw,
822*890232f2SAndroid Build Coastguard Worker          ])
823*890232f2SAndroid Build Coastguard Worker          self._check_typed_vector(data, vector, Type.KEY)
824*890232f2SAndroid Build Coastguard Worker
825*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_string(self):
826*890232f2SAndroid Build Coastguard Worker    vector = ['red', 'green', 'blue']
827*890232f2SAndroid Build Coastguard Worker
828*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
829*890232f2SAndroid Build Coastguard Worker      for ebw in 1, 2, 4, 8:
830*890232f2SAndroid Build Coastguard Worker        with self.subTest(bw=bw, ebw=ebw):
831*890232f2SAndroid Build Coastguard Worker          data = bytes([
832*890232f2SAndroid Build Coastguard Worker              # Strings
833*890232f2SAndroid Build Coastguard Worker              *str_bytes(vector[0], 1),  # 5 bytes
834*890232f2SAndroid Build Coastguard Worker              *str_bytes(vector[1], 1),  # 7 bytes
835*890232f2SAndroid Build Coastguard Worker              *str_bytes(vector[2], 1),  # 6 bytes
836*890232f2SAndroid Build Coastguard Worker              # TypedVector[Type.STRING]
837*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector), ebw),
838*890232f2SAndroid Build Coastguard Worker              *uint_bytes(17 + 1 * ebw, ebw),  # offset to vector[0]
839*890232f2SAndroid Build Coastguard Worker              *uint_bytes(12 + 2 * ebw, ebw),  # offset to vector[1]
840*890232f2SAndroid Build Coastguard Worker              *uint_bytes(5 + 3 * ebw, ebw),  # offset to vector[2]
841*890232f2SAndroid Build Coastguard Worker              # Root
842*890232f2SAndroid Build Coastguard Worker              *uint_bytes(len(vector) * ebw, bw),  # offset to vector
843*890232f2SAndroid Build Coastguard Worker              packed_type(Type.VECTOR_STRING_DEPRECATED, ebw),
844*890232f2SAndroid Build Coastguard Worker              bw,
845*890232f2SAndroid Build Coastguard Worker          ])
846*890232f2SAndroid Build Coastguard Worker
847*890232f2SAndroid Build Coastguard Worker          # We have to pass Type.KEY because of Type.VECTOR_STRING_DEPRECATED.
848*890232f2SAndroid Build Coastguard Worker          self._check_typed_vector(data, vector, Type.KEY)
849*890232f2SAndroid Build Coastguard Worker
850*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_string_deprecated(self):
851*890232f2SAndroid Build Coastguard Worker    # Check FlexBuffersDeprecatedTest() inside test.cpp for details.
852*890232f2SAndroid Build Coastguard Worker    vector = [300 * 'A', 'test']
853*890232f2SAndroid Build Coastguard Worker
854*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
855*890232f2SAndroid Build Coastguard Worker    with fbb.TypedVector():
856*890232f2SAndroid Build Coastguard Worker      for e in vector:
857*890232f2SAndroid Build Coastguard Worker        fbb.String(e)
858*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
859*890232f2SAndroid Build Coastguard Worker
860*890232f2SAndroid Build Coastguard Worker    # We have to pass Type.KEY because of Type.VECTOR_STRING_DEPRECATED.
861*890232f2SAndroid Build Coastguard Worker    self._check_typed_vector(data, vector, Type.KEY)
862*890232f2SAndroid Build Coastguard Worker
863*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_invalid(self):
864*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
865*890232f2SAndroid Build Coastguard Worker
866*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(RuntimeError):
867*890232f2SAndroid Build Coastguard Worker      fbb.TypedVectorFromElements(['string', 423])
868*890232f2SAndroid Build Coastguard Worker
869*890232f2SAndroid Build Coastguard Worker  def test_empty_vector(self):
870*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
871*890232f2SAndroid Build Coastguard Worker      for ebw in 1, 2, 4, 8:
872*890232f2SAndroid Build Coastguard Worker        data = bytes([
873*890232f2SAndroid Build Coastguard Worker            *uint_bytes(0, ebw),
874*890232f2SAndroid Build Coastguard Worker            # Root
875*890232f2SAndroid Build Coastguard Worker            *uint_bytes(0, bw),
876*890232f2SAndroid Build Coastguard Worker            packed_type(Type.VECTOR, ebw),
877*890232f2SAndroid Build Coastguard Worker            bw,
878*890232f2SAndroid Build Coastguard Worker        ])
879*890232f2SAndroid Build Coastguard Worker
880*890232f2SAndroid Build Coastguard Worker        root = flexbuffers.GetRoot(data)
881*890232f2SAndroid Build Coastguard Worker        self.assertTrue(root.IsVector)
882*890232f2SAndroid Build Coastguard Worker        self.assertEqual(len(root.AsVector), 0)
883*890232f2SAndroid Build Coastguard Worker
884*890232f2SAndroid Build Coastguard Worker        self.assertEqual(flexbuffers.Loads(data), [])
885*890232f2SAndroid Build Coastguard Worker
886*890232f2SAndroid Build Coastguard Worker  def test_vector1(self):
887*890232f2SAndroid Build Coastguard Worker    vector = [300, 400, 500]
888*890232f2SAndroid Build Coastguard Worker
889*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
890*890232f2SAndroid Build Coastguard Worker      for ebw in 2, 4, 8:
891*890232f2SAndroid Build Coastguard Worker        for tbw_ignored in 1, 2, 4, 8:
892*890232f2SAndroid Build Coastguard Worker          with self.subTest(bw=bw, ebw=ebw, ignore=tbw_ignored):
893*890232f2SAndroid Build Coastguard Worker            data = bytes([
894*890232f2SAndroid Build Coastguard Worker                # Vector length
895*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(vector), ebw),
896*890232f2SAndroid Build Coastguard Worker                # Vector elements
897*890232f2SAndroid Build Coastguard Worker                *int_bytes(vector[0], ebw),
898*890232f2SAndroid Build Coastguard Worker                *int_bytes(vector[1], ebw),
899*890232f2SAndroid Build Coastguard Worker                *int_bytes(vector[2], ebw),
900*890232f2SAndroid Build Coastguard Worker                # Vector types
901*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INT, tbw_ignored),
902*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INT, tbw_ignored),
903*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INT, tbw_ignored),
904*890232f2SAndroid Build Coastguard Worker                # Root
905*890232f2SAndroid Build Coastguard Worker                *uint_bytes(ebw * len(vector) + len(vector), bw),
906*890232f2SAndroid Build Coastguard Worker                packed_type(Type.VECTOR, ebw),
907*890232f2SAndroid Build Coastguard Worker                bw,
908*890232f2SAndroid Build Coastguard Worker            ])
909*890232f2SAndroid Build Coastguard Worker
910*890232f2SAndroid Build Coastguard Worker            root = flexbuffers.GetRoot(data)
911*890232f2SAndroid Build Coastguard Worker            self.assertTrue(root.IsVector)
912*890232f2SAndroid Build Coastguard Worker            self.assertFalse(root.IsMap)
913*890232f2SAndroid Build Coastguard Worker
914*890232f2SAndroid Build Coastguard Worker            v = root.AsVector
915*890232f2SAndroid Build Coastguard Worker            self.assertEqual(len(v), len(vector))
916*890232f2SAndroid Build Coastguard Worker
917*890232f2SAndroid Build Coastguard Worker            for i in range(len(v)):
918*890232f2SAndroid Build Coastguard Worker              self.assertTrue(v[i].IsInt)
919*890232f2SAndroid Build Coastguard Worker              self.assertEqual(v[i].AsInt, vector[i])
920*890232f2SAndroid Build Coastguard Worker
921*890232f2SAndroid Build Coastguard Worker            for i, e in enumerate(v):
922*890232f2SAndroid Build Coastguard Worker              self.assertTrue(e.IsInt)
923*890232f2SAndroid Build Coastguard Worker              self.assertEqual(e.AsInt, vector[i])
924*890232f2SAndroid Build Coastguard Worker
925*890232f2SAndroid Build Coastguard Worker            with self.assertRaises(IndexError):
926*890232f2SAndroid Build Coastguard Worker              v[-1].AsInt  # pylint: disable=pointless-statement
927*890232f2SAndroid Build Coastguard Worker
928*890232f2SAndroid Build Coastguard Worker            with self.assertRaises(IndexError):
929*890232f2SAndroid Build Coastguard Worker              v[3].AsInt  # pylint: disable=pointless-statement
930*890232f2SAndroid Build Coastguard Worker
931*890232f2SAndroid Build Coastguard Worker            with self.assertRaises(TypeError):
932*890232f2SAndroid Build Coastguard Worker              root.AsMap  # pylint: disable=pointless-statement
933*890232f2SAndroid Build Coastguard Worker
934*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsInt, len(vector))
935*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsFloat, float(len(vector)))
936*890232f2SAndroid Build Coastguard Worker
937*890232f2SAndroid Build Coastguard Worker            self.assertEqual(flexbuffers.Loads(data), vector)
938*890232f2SAndroid Build Coastguard Worker
939*890232f2SAndroid Build Coastguard Worker  def test_vector2(self):
940*890232f2SAndroid Build Coastguard Worker    vector = [1984, 'August', True]
941*890232f2SAndroid Build Coastguard Worker
942*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
943*890232f2SAndroid Build Coastguard Worker      with self.subTest(bw=bw):
944*890232f2SAndroid Build Coastguard Worker        data = bytes([
945*890232f2SAndroid Build Coastguard Worker            *str_bytes(vector[1], 1),
946*890232f2SAndroid Build Coastguard Worker            # Vector
947*890232f2SAndroid Build Coastguard Worker            *uint_bytes(len(vector), 2),
948*890232f2SAndroid Build Coastguard Worker            *int_bytes(vector[0], 2),
949*890232f2SAndroid Build Coastguard Worker            *uint_bytes(11, 2),  # offset to 'August'
950*890232f2SAndroid Build Coastguard Worker            *uint_bytes(int(vector[2]), 2),
951*890232f2SAndroid Build Coastguard Worker            packed_type(Type.INT, 2),
952*890232f2SAndroid Build Coastguard Worker            packed_type(Type.STRING, 1),
953*890232f2SAndroid Build Coastguard Worker            packed_type(Type.BOOL, 2),
954*890232f2SAndroid Build Coastguard Worker            # Root
955*890232f2SAndroid Build Coastguard Worker            *uint_bytes(2 * len(vector) + len(vector), bw),  # offset to vector
956*890232f2SAndroid Build Coastguard Worker            packed_type(Type.VECTOR, 2),
957*890232f2SAndroid Build Coastguard Worker            bw,
958*890232f2SAndroid Build Coastguard Worker        ])
959*890232f2SAndroid Build Coastguard Worker        self.assertEqual(flexbuffers.Loads(data), vector)
960*890232f2SAndroid Build Coastguard Worker
961*890232f2SAndroid Build Coastguard Worker        root = flexbuffers.GetRoot(data)
962*890232f2SAndroid Build Coastguard Worker        self.assertTrue(root.IsVector)
963*890232f2SAndroid Build Coastguard Worker
964*890232f2SAndroid Build Coastguard Worker        v = root.AsVector
965*890232f2SAndroid Build Coastguard Worker        self.assertTrue(v[0].IsInt)
966*890232f2SAndroid Build Coastguard Worker        self.assertEqual(v[0].AsInt, 1984)
967*890232f2SAndroid Build Coastguard Worker
968*890232f2SAndroid Build Coastguard Worker        self.assertTrue(v[1].IsString)
969*890232f2SAndroid Build Coastguard Worker        self.assertEqual(v[1].AsString, 'August')
970*890232f2SAndroid Build Coastguard Worker
971*890232f2SAndroid Build Coastguard Worker        self.assertTrue(v[2].IsBool)
972*890232f2SAndroid Build Coastguard Worker        self.assertTrue(v[2].AsBool)
973*890232f2SAndroid Build Coastguard Worker
974*890232f2SAndroid Build Coastguard Worker        self.assertEqual(v.Value, vector)
975*890232f2SAndroid Build Coastguard Worker
976*890232f2SAndroid Build Coastguard Worker        self.assertEqual(root.AsInt, len(vector))
977*890232f2SAndroid Build Coastguard Worker
978*890232f2SAndroid Build Coastguard Worker  def test_empty_map(self):
979*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
980*890232f2SAndroid Build Coastguard Worker      for kbw in 1, 2, 4, 8:
981*890232f2SAndroid Build Coastguard Worker        for vbw in 1, 2, 4, 8:
982*890232f2SAndroid Build Coastguard Worker          data = bytes([
983*890232f2SAndroid Build Coastguard Worker              *uint_bytes(0, kbw),  # Keys length
984*890232f2SAndroid Build Coastguard Worker              *uint_bytes(0, vbw),
985*890232f2SAndroid Build Coastguard Worker              *uint_bytes(kbw, vbw),
986*890232f2SAndroid Build Coastguard Worker              *uint_bytes(0, vbw),  # Values length
987*890232f2SAndroid Build Coastguard Worker              # Root
988*890232f2SAndroid Build Coastguard Worker              *uint_bytes(0, bw),
989*890232f2SAndroid Build Coastguard Worker              packed_type(Type.MAP, vbw),
990*890232f2SAndroid Build Coastguard Worker              bw,
991*890232f2SAndroid Build Coastguard Worker          ])
992*890232f2SAndroid Build Coastguard Worker
993*890232f2SAndroid Build Coastguard Worker          root = flexbuffers.GetRoot(data)
994*890232f2SAndroid Build Coastguard Worker          self.assertTrue(root.IsMap)
995*890232f2SAndroid Build Coastguard Worker          self.assertEqual(len(root.AsMap), 0)
996*890232f2SAndroid Build Coastguard Worker
997*890232f2SAndroid Build Coastguard Worker          self.assertEqual(flexbuffers.Loads(data), {})
998*890232f2SAndroid Build Coastguard Worker
999*890232f2SAndroid Build Coastguard Worker  def test_map(self):
1000*890232f2SAndroid Build Coastguard Worker    value = {'foo': 13, 'bar': 14}
1001*890232f2SAndroid Build Coastguard Worker
1002*890232f2SAndroid Build Coastguard Worker    for bw in 1, 2, 4, 8:
1003*890232f2SAndroid Build Coastguard Worker      for kbw in 1, 2, 4, 8:
1004*890232f2SAndroid Build Coastguard Worker        for vbw in 1, 2, 4, 8:
1005*890232f2SAndroid Build Coastguard Worker          with self.subTest(kbw=kbw, vbw=vbw, bw=bw):
1006*890232f2SAndroid Build Coastguard Worker            data = bytes([
1007*890232f2SAndroid Build Coastguard Worker                *key_bytes('foo'),  # 4 bytes
1008*890232f2SAndroid Build Coastguard Worker                *key_bytes('bar'),  # 4 bytes
1009*890232f2SAndroid Build Coastguard Worker                # Map
1010*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(value), kbw),
1011*890232f2SAndroid Build Coastguard Worker                *uint_bytes(4 + 1 * kbw, kbw),  # offset to 'bar'
1012*890232f2SAndroid Build Coastguard Worker                *uint_bytes(8 + 2 * kbw, kbw),  # offset to 'foo'
1013*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(value) * kbw, vbw),  # offset to keys
1014*890232f2SAndroid Build Coastguard Worker                *uint_bytes(kbw, vbw),
1015*890232f2SAndroid Build Coastguard Worker                *uint_bytes(len(value), vbw),
1016*890232f2SAndroid Build Coastguard Worker                *int_bytes(value['bar'], vbw),
1017*890232f2SAndroid Build Coastguard Worker                *int_bytes(value['foo'], vbw),
1018*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INT, vbw),
1019*890232f2SAndroid Build Coastguard Worker                packed_type(Type.INT, vbw),
1020*890232f2SAndroid Build Coastguard Worker                # Root
1021*890232f2SAndroid Build Coastguard Worker                *uint_bytes(vbw * len(value) + len(value),
1022*890232f2SAndroid Build Coastguard Worker                            bw),  # offset to values
1023*890232f2SAndroid Build Coastguard Worker                packed_type(Type.MAP, vbw),
1024*890232f2SAndroid Build Coastguard Worker                bw,
1025*890232f2SAndroid Build Coastguard Worker            ])
1026*890232f2SAndroid Build Coastguard Worker
1027*890232f2SAndroid Build Coastguard Worker            root = flexbuffers.GetRoot(data)
1028*890232f2SAndroid Build Coastguard Worker            self.assertTrue(root.IsMap)
1029*890232f2SAndroid Build Coastguard Worker
1030*890232f2SAndroid Build Coastguard Worker            m = root.AsMap
1031*890232f2SAndroid Build Coastguard Worker            self.assertEqual(len(m), 2)
1032*890232f2SAndroid Build Coastguard Worker            self.assertEqual(m[0].AsInt, 14)
1033*890232f2SAndroid Build Coastguard Worker            self.assertEqual(m[1].AsInt, 13)
1034*890232f2SAndroid Build Coastguard Worker
1035*890232f2SAndroid Build Coastguard Worker            self.assertEqual(m['bar'].AsInt, 14)
1036*890232f2SAndroid Build Coastguard Worker            self.assertEqual(m['foo'].AsInt, 13)
1037*890232f2SAndroid Build Coastguard Worker
1038*890232f2SAndroid Build Coastguard Worker            for invalid_key in 'a', 'b', 'no':
1039*890232f2SAndroid Build Coastguard Worker              with self.assertRaises(KeyError):
1040*890232f2SAndroid Build Coastguard Worker                m[invalid_key]  # pylint: disable=pointless-statement
1041*890232f2SAndroid Build Coastguard Worker
1042*890232f2SAndroid Build Coastguard Worker            values = m.Values
1043*890232f2SAndroid Build Coastguard Worker            self.assertEqual(len(values), 2)
1044*890232f2SAndroid Build Coastguard Worker            self.assertEqual(values[0].AsInt, 14)
1045*890232f2SAndroid Build Coastguard Worker            self.assertEqual(values[1].AsInt, 13)
1046*890232f2SAndroid Build Coastguard Worker
1047*890232f2SAndroid Build Coastguard Worker            keys = m.Keys
1048*890232f2SAndroid Build Coastguard Worker            self.assertEqual(len(keys), 2)
1049*890232f2SAndroid Build Coastguard Worker            self.assertEqual(len(keys[0].AsKey), 3)
1050*890232f2SAndroid Build Coastguard Worker            self.assertEqual(keys[0].AsKey, 'bar')
1051*890232f2SAndroid Build Coastguard Worker            self.assertEqual(len(keys[1].AsKey), 3)
1052*890232f2SAndroid Build Coastguard Worker            self.assertEqual(keys[1].AsKey, 'foo')
1053*890232f2SAndroid Build Coastguard Worker
1054*890232f2SAndroid Build Coastguard Worker            keys = [key.AsKey for key in keys]
1055*890232f2SAndroid Build Coastguard Worker            self.assertEqual(sorted(keys), keys)
1056*890232f2SAndroid Build Coastguard Worker
1057*890232f2SAndroid Build Coastguard Worker            self.assertEqual(root.AsInt, len(value))
1058*890232f2SAndroid Build Coastguard Worker
1059*890232f2SAndroid Build Coastguard Worker            self.assertEqual(flexbuffers.Loads(data), value)
1060*890232f2SAndroid Build Coastguard Worker
1061*890232f2SAndroid Build Coastguard Worker  def test_alignment(self):
1062*890232f2SAndroid Build Coastguard Worker    value = ['test', 7]
1063*890232f2SAndroid Build Coastguard Worker
1064*890232f2SAndroid Build Coastguard Worker    data = bytes([
1065*890232f2SAndroid Build Coastguard Worker        *key_bytes('test'),  # 5 bytes: 'test' and \0
1066*890232f2SAndroid Build Coastguard Worker        0,
1067*890232f2SAndroid Build Coastguard Worker        0,
1068*890232f2SAndroid Build Coastguard Worker        0,  # 3 bytes: alignment
1069*890232f2SAndroid Build Coastguard Worker        # Vector
1070*890232f2SAndroid Build Coastguard Worker        *uint_bytes(len(value), byte_width=8),
1071*890232f2SAndroid Build Coastguard Worker        *uint_bytes(16, byte_width=8),
1072*890232f2SAndroid Build Coastguard Worker        *uint_bytes(7, byte_width=8),
1073*890232f2SAndroid Build Coastguard Worker        packed_type(Type.KEY, 1),
1074*890232f2SAndroid Build Coastguard Worker        packed_type(Type.INT, 8),
1075*890232f2SAndroid Build Coastguard Worker        # Root
1076*890232f2SAndroid Build Coastguard Worker        *uint_bytes(8 * len(value) + len(value), 1),
1077*890232f2SAndroid Build Coastguard Worker        packed_type(Type.VECTOR, 8),
1078*890232f2SAndroid Build Coastguard Worker        1,
1079*890232f2SAndroid Build Coastguard Worker    ])
1080*890232f2SAndroid Build Coastguard Worker
1081*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), value)
1082*890232f2SAndroid Build Coastguard Worker
1083*890232f2SAndroid Build Coastguard Worker
1084*890232f2SAndroid Build Coastguard Workerclass EncoderTest(unittest.TestCase):
1085*890232f2SAndroid Build Coastguard Worker  """Tests to check FlexBuffer encoding functions."""
1086*890232f2SAndroid Build Coastguard Worker
1087*890232f2SAndroid Build Coastguard Worker  def test_null(self):
1088*890232f2SAndroid Build Coastguard Worker    def encode_null():
1089*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder()
1090*890232f2SAndroid Build Coastguard Worker      fbb.Null()
1091*890232f2SAndroid Build Coastguard Worker      return fbb.Finish()
1092*890232f2SAndroid Build Coastguard Worker
1093*890232f2SAndroid Build Coastguard Worker    self.assertIsNone(flexbuffers.Loads(encode_null()))
1094*890232f2SAndroid Build Coastguard Worker
1095*890232f2SAndroid Build Coastguard Worker  def test_bool(self):
1096*890232f2SAndroid Build Coastguard Worker    for value in False, True:
1097*890232f2SAndroid Build Coastguard Worker      data = encode_type(Type.BOOL, value)
1098*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), value)
1099*890232f2SAndroid Build Coastguard Worker
1100*890232f2SAndroid Build Coastguard Worker  def test_int(self):
1101*890232f2SAndroid Build Coastguard Worker    for byte_width in 1, 2, 4, 8:
1102*890232f2SAndroid Build Coastguard Worker      for type_ in Type.INT, Type.INDIRECT_INT, Type.UINT, Type.INDIRECT_UINT:
1103*890232f2SAndroid Build Coastguard Worker        with self.subTest(byte_width=byte_width, type=type_):
1104*890232f2SAndroid Build Coastguard Worker          value = min_value(type_, byte_width)
1105*890232f2SAndroid Build Coastguard Worker          data = encode_type(type_, value)
1106*890232f2SAndroid Build Coastguard Worker          self.assertEqual(flexbuffers.Loads(data), value)
1107*890232f2SAndroid Build Coastguard Worker
1108*890232f2SAndroid Build Coastguard Worker          value = max_value(type_, byte_width)
1109*890232f2SAndroid Build Coastguard Worker          data = encode_type(type_, value)
1110*890232f2SAndroid Build Coastguard Worker          self.assertEqual(flexbuffers.Loads(data), value)
1111*890232f2SAndroid Build Coastguard Worker
1112*890232f2SAndroid Build Coastguard Worker  def test_float(self):
1113*890232f2SAndroid Build Coastguard Worker    for value in 3.141592, 7.62, 999.99:
1114*890232f2SAndroid Build Coastguard Worker      for type_ in Type.FLOAT, Type.INDIRECT_FLOAT:
1115*890232f2SAndroid Build Coastguard Worker        with self.subTest(value=value, type=type_):
1116*890232f2SAndroid Build Coastguard Worker          data = encode_type(type_, value)
1117*890232f2SAndroid Build Coastguard Worker          self.assertEqual(flexbuffers.Loads(data), value)
1118*890232f2SAndroid Build Coastguard Worker
1119*890232f2SAndroid Build Coastguard Worker          data = encode_type(type_, value, 4)
1120*890232f2SAndroid Build Coastguard Worker          self.assertAlmostEqual(flexbuffers.Loads(data), value, places=4)
1121*890232f2SAndroid Build Coastguard Worker
1122*890232f2SAndroid Build Coastguard Worker          data = encode_type(type_, value, 8)
1123*890232f2SAndroid Build Coastguard Worker          self.assertEqual(flexbuffers.Loads(data), value)
1124*890232f2SAndroid Build Coastguard Worker
1125*890232f2SAndroid Build Coastguard Worker  def test_string(self):
1126*890232f2SAndroid Build Coastguard Worker    for value in '', 'x', 'color', 'hello world':
1127*890232f2SAndroid Build Coastguard Worker      with self.subTest(value=value):
1128*890232f2SAndroid Build Coastguard Worker        data = encode_type(Type.STRING, value)
1129*890232f2SAndroid Build Coastguard Worker        self.assertEqual(flexbuffers.Loads(data), value)
1130*890232f2SAndroid Build Coastguard Worker
1131*890232f2SAndroid Build Coastguard Worker  def test_blob(self):
1132*890232f2SAndroid Build Coastguard Worker    for value in bytes(), bytes([240, 12, 143, 7]), bytes(1000 * [17]):
1133*890232f2SAndroid Build Coastguard Worker      with self.subTest(value=value):
1134*890232f2SAndroid Build Coastguard Worker        data = encode_type(Type.BLOB, value)
1135*890232f2SAndroid Build Coastguard Worker        self.assertEqual(flexbuffers.Loads(data), value)
1136*890232f2SAndroid Build Coastguard Worker
1137*890232f2SAndroid Build Coastguard Worker  def test_key(self):
1138*890232f2SAndroid Build Coastguard Worker    for value in '', 'color', 'hello world':
1139*890232f2SAndroid Build Coastguard Worker      with self.subTest(value=value):
1140*890232f2SAndroid Build Coastguard Worker        data = encode_type(Type.KEY, value)
1141*890232f2SAndroid Build Coastguard Worker        self.assertEqual(flexbuffers.Loads(data), value)
1142*890232f2SAndroid Build Coastguard Worker
1143*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(ValueError):
1144*890232f2SAndroid Build Coastguard Worker      encode_type(Type.KEY, (b'\x00' * 10).decode('ascii'))
1145*890232f2SAndroid Build Coastguard Worker
1146*890232f2SAndroid Build Coastguard Worker  def test_vector(self):
1147*890232f2SAndroid Build Coastguard Worker
1148*890232f2SAndroid Build Coastguard Worker    def encode_vector(elements, element_type):
1149*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder()
1150*890232f2SAndroid Build Coastguard Worker      with fbb.Vector():
1151*890232f2SAndroid Build Coastguard Worker        add = fbb.Adder(element_type)
1152*890232f2SAndroid Build Coastguard Worker        for e in elements:
1153*890232f2SAndroid Build Coastguard Worker          add(e)
1154*890232f2SAndroid Build Coastguard Worker      return fbb.Finish()
1155*890232f2SAndroid Build Coastguard Worker
1156*890232f2SAndroid Build Coastguard Worker    def encode_vector_from_elements(elements):
1157*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder()
1158*890232f2SAndroid Build Coastguard Worker      fbb.VectorFromElements(elements)
1159*890232f2SAndroid Build Coastguard Worker      return fbb.Finish()
1160*890232f2SAndroid Build Coastguard Worker
1161*890232f2SAndroid Build Coastguard Worker    for elements in [], [1435], [56, 23, 0, 6783]:
1162*890232f2SAndroid Build Coastguard Worker      data = encode_vector(elements, Type.INT)
1163*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1164*890232f2SAndroid Build Coastguard Worker
1165*890232f2SAndroid Build Coastguard Worker      data = encode_vector_from_elements(elements)
1166*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1167*890232f2SAndroid Build Coastguard Worker
1168*890232f2SAndroid Build Coastguard Worker    # Elements of different type: one by one
1169*890232f2SAndroid Build Coastguard Worker    elements = [56.0, 'flexbuffers', 0, False, 75123]
1170*890232f2SAndroid Build Coastguard Worker
1171*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1172*890232f2SAndroid Build Coastguard Worker    with fbb.Vector():
1173*890232f2SAndroid Build Coastguard Worker      fbb.Float(elements[0])
1174*890232f2SAndroid Build Coastguard Worker      fbb.String(elements[1])
1175*890232f2SAndroid Build Coastguard Worker      fbb.UInt(elements[2], 8)
1176*890232f2SAndroid Build Coastguard Worker      fbb.Bool(elements[3])
1177*890232f2SAndroid Build Coastguard Worker      fbb.Int(elements[4])
1178*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1179*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), elements)
1180*890232f2SAndroid Build Coastguard Worker
1181*890232f2SAndroid Build Coastguard Worker    # Elements of different type: all at once
1182*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1183*890232f2SAndroid Build Coastguard Worker    fbb.VectorFromElements(elements)
1184*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1185*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), elements)
1186*890232f2SAndroid Build Coastguard Worker
1187*890232f2SAndroid Build Coastguard Worker  def test_nested_vectors(self):
1188*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1189*890232f2SAndroid Build Coastguard Worker    with fbb.Vector():
1190*890232f2SAndroid Build Coastguard Worker      fbb.String('begin')
1191*890232f2SAndroid Build Coastguard Worker      fbb.IndirectInt(42)
1192*890232f2SAndroid Build Coastguard Worker      with fbb.Vector():
1193*890232f2SAndroid Build Coastguard Worker        for i in range(5):
1194*890232f2SAndroid Build Coastguard Worker          fbb.Int(i)
1195*890232f2SAndroid Build Coastguard Worker      fbb.String('end')
1196*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1197*890232f2SAndroid Build Coastguard Worker
1198*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
1199*890232f2SAndroid Build Coastguard Worker        flexbuffers.Loads(data), ['begin', 42, [0, 1, 2, 3, 4], 'end'])
1200*890232f2SAndroid Build Coastguard Worker
1201*890232f2SAndroid Build Coastguard Worker  def test_big_vector(self):
1202*890232f2SAndroid Build Coastguard Worker    n = 10 * 1000
1203*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1204*890232f2SAndroid Build Coastguard Worker    with fbb.Vector():
1205*890232f2SAndroid Build Coastguard Worker      for i in range(n):
1206*890232f2SAndroid Build Coastguard Worker        fbb.Int(i)
1207*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(fbb.Finish()), list(range(n)))
1208*890232f2SAndroid Build Coastguard Worker
1209*890232f2SAndroid Build Coastguard Worker  def test_typed_vector(self):
1210*890232f2SAndroid Build Coastguard Worker
1211*890232f2SAndroid Build Coastguard Worker    def encode_typed_vector_from_elements(elements, element_type=None):
1212*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder()
1213*890232f2SAndroid Build Coastguard Worker      fbb.TypedVectorFromElements(elements, element_type)
1214*890232f2SAndroid Build Coastguard Worker      return fbb.Finish()
1215*890232f2SAndroid Build Coastguard Worker
1216*890232f2SAndroid Build Coastguard Worker    for elements in [], [False], [True], [False, True, True, False, False]:
1217*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements, Type.BOOL)
1218*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1219*890232f2SAndroid Build Coastguard Worker
1220*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements)
1221*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1222*890232f2SAndroid Build Coastguard Worker
1223*890232f2SAndroid Build Coastguard Worker    for elements in [], [23455], [351, -2, 0, 6783, 0, -10]:
1224*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements, Type.INT)
1225*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1226*890232f2SAndroid Build Coastguard Worker
1227*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements)
1228*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1229*890232f2SAndroid Build Coastguard Worker
1230*890232f2SAndroid Build Coastguard Worker    for elements in [], [23455], [351, 2, 0, 6783, 0, 10]:
1231*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements)
1232*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1233*890232f2SAndroid Build Coastguard Worker
1234*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements, Type.INT)
1235*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1236*890232f2SAndroid Build Coastguard Worker
1237*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements, Type.UINT)
1238*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1239*890232f2SAndroid Build Coastguard Worker
1240*890232f2SAndroid Build Coastguard Worker    for elements in [], [7.0], [52.0, 51.2, 70.0, -4.0]:
1241*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements, Type.FLOAT)
1242*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1243*890232f2SAndroid Build Coastguard Worker
1244*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements)
1245*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1246*890232f2SAndroid Build Coastguard Worker
1247*890232f2SAndroid Build Coastguard Worker    for elements in [], ['color'], ['x', 'y']:
1248*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements, Type.KEY)
1249*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1250*890232f2SAndroid Build Coastguard Worker
1251*890232f2SAndroid Build Coastguard Worker      data = encode_typed_vector_from_elements(elements)
1252*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(data), elements)
1253*890232f2SAndroid Build Coastguard Worker
1254*890232f2SAndroid Build Coastguard Worker  def test_typed_vector_from_array(self):
1255*890232f2SAndroid Build Coastguard Worker
1256*890232f2SAndroid Build Coastguard Worker    def encode_array(typecode, values):
1257*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder()
1258*890232f2SAndroid Build Coastguard Worker      fbb.VectorFromElements(array.array(typecode, values))
1259*890232f2SAndroid Build Coastguard Worker      return fbb.Finish()
1260*890232f2SAndroid Build Coastguard Worker
1261*890232f2SAndroid Build Coastguard Worker    values = [1.0, 3.14, -2.54, 0.0]
1262*890232f2SAndroid Build Coastguard Worker    data = encode_array('f', values)
1263*890232f2SAndroid Build Coastguard Worker    for a, b in zip(flexbuffers.Loads(data), values):
1264*890232f2SAndroid Build Coastguard Worker      self.assertAlmostEqual(a, b, places=2)
1265*890232f2SAndroid Build Coastguard Worker
1266*890232f2SAndroid Build Coastguard Worker    values = [1.0, 3.14, -2.54, 0.0]
1267*890232f2SAndroid Build Coastguard Worker    data = encode_array('d', values)
1268*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), values)
1269*890232f2SAndroid Build Coastguard Worker
1270*890232f2SAndroid Build Coastguard Worker    values = [1, -7, 9, 26, 12]
1271*890232f2SAndroid Build Coastguard Worker    data = encode_array('i', values)
1272*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), values)
1273*890232f2SAndroid Build Coastguard Worker
1274*890232f2SAndroid Build Coastguard Worker    values = [0, 1, 2, 3, 4, 5, 6]
1275*890232f2SAndroid Build Coastguard Worker    data = encode_array('I', values)
1276*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), values)
1277*890232f2SAndroid Build Coastguard Worker
1278*890232f2SAndroid Build Coastguard Worker  def test_fixed_typed_vector(self):
1279*890232f2SAndroid Build Coastguard Worker
1280*890232f2SAndroid Build Coastguard Worker    def encode_fixed_typed_vector(elements, element_type=None):
1281*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder()
1282*890232f2SAndroid Build Coastguard Worker      fbb.FixedTypedVectorFromElements(elements, element_type)
1283*890232f2SAndroid Build Coastguard Worker      return fbb.Finish()
1284*890232f2SAndroid Build Coastguard Worker
1285*890232f2SAndroid Build Coastguard Worker    for elements in ((-2, 2), (1, 2, 3), (100, -100, 200, -200), (4.0, 7.0),
1286*890232f2SAndroid Build Coastguard Worker                     (0.0, 1.0, 8.0), (9.0, 7.0, 1.0, 5.5)):
1287*890232f2SAndroid Build Coastguard Worker      with self.subTest(elements=elements):
1288*890232f2SAndroid Build Coastguard Worker        data = encode_fixed_typed_vector(elements)
1289*890232f2SAndroid Build Coastguard Worker        self.assertSequenceEqual(flexbuffers.Loads(data), elements)
1290*890232f2SAndroid Build Coastguard Worker
1291*890232f2SAndroid Build Coastguard Worker    elements = [-170, 432, 0, -7]
1292*890232f2SAndroid Build Coastguard Worker    data = encode_fixed_typed_vector(elements, Type.INT)
1293*890232f2SAndroid Build Coastguard Worker    self.assertSequenceEqual(flexbuffers.Loads(data), elements)
1294*890232f2SAndroid Build Coastguard Worker
1295*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(ValueError):
1296*890232f2SAndroid Build Coastguard Worker      encode_fixed_typed_vector([])  # Invalid input length
1297*890232f2SAndroid Build Coastguard Worker
1298*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(ValueError):
1299*890232f2SAndroid Build Coastguard Worker      encode_fixed_typed_vector([1])  # Invalid input length
1300*890232f2SAndroid Build Coastguard Worker
1301*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(ValueError):
1302*890232f2SAndroid Build Coastguard Worker      encode_fixed_typed_vector([1, 2, 3, 4, 5])  # Invalid input length
1303*890232f2SAndroid Build Coastguard Worker
1304*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(TypeError):
1305*890232f2SAndroid Build Coastguard Worker      encode_fixed_typed_vector([1, 1.0])  # Invalid input types
1306*890232f2SAndroid Build Coastguard Worker
1307*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(TypeError):
1308*890232f2SAndroid Build Coastguard Worker      encode_fixed_typed_vector(['', ''])  # Invalid input types
1309*890232f2SAndroid Build Coastguard Worker
1310*890232f2SAndroid Build Coastguard Worker  def test_map_builder(self):
1311*890232f2SAndroid Build Coastguard Worker
1312*890232f2SAndroid Build Coastguard Worker    def get_keys(data):
1313*890232f2SAndroid Build Coastguard Worker      return [key.AsKey for key in flexbuffers.GetRoot(data).AsMap.Keys]
1314*890232f2SAndroid Build Coastguard Worker
1315*890232f2SAndroid Build Coastguard Worker    # Empty map
1316*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1317*890232f2SAndroid Build Coastguard Worker    with fbb.Map():
1318*890232f2SAndroid Build Coastguard Worker      pass
1319*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1320*890232f2SAndroid Build Coastguard Worker
1321*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), {})
1322*890232f2SAndroid Build Coastguard Worker
1323*890232f2SAndroid Build Coastguard Worker    # Two-element map of Int
1324*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1325*890232f2SAndroid Build Coastguard Worker    with fbb.Map():
1326*890232f2SAndroid Build Coastguard Worker      fbb.Int('y', -2)
1327*890232f2SAndroid Build Coastguard Worker      fbb.Int('x', 10)
1328*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1329*890232f2SAndroid Build Coastguard Worker
1330*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), {'x': 10, 'y': -2})
1331*890232f2SAndroid Build Coastguard Worker
1332*890232f2SAndroid Build Coastguard Worker    # Multiple-element map of vectors
1333*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1334*890232f2SAndroid Build Coastguard Worker    with fbb.Map():
1335*890232f2SAndroid Build Coastguard Worker      with fbb.Vector('v'):
1336*890232f2SAndroid Build Coastguard Worker        fbb.Int(45)
1337*890232f2SAndroid Build Coastguard Worker      with fbb.TypedVector('tv'):
1338*890232f2SAndroid Build Coastguard Worker        fbb.Int(-7)
1339*890232f2SAndroid Build Coastguard Worker      fbb.FixedTypedVectorFromElements('ftv', [-2.0, 1.0])
1340*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1341*890232f2SAndroid Build Coastguard Worker
1342*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
1343*890232f2SAndroid Build Coastguard Worker        flexbuffers.Loads(data), {
1344*890232f2SAndroid Build Coastguard Worker            'v': [45],
1345*890232f2SAndroid Build Coastguard Worker            'tv': [-7],
1346*890232f2SAndroid Build Coastguard Worker            'ftv': [-2.0, 1.0]
1347*890232f2SAndroid Build Coastguard Worker        })
1348*890232f2SAndroid Build Coastguard Worker
1349*890232f2SAndroid Build Coastguard Worker    keys = get_keys(data)
1350*890232f2SAndroid Build Coastguard Worker    self.assertEqual(sorted(keys), keys)
1351*890232f2SAndroid Build Coastguard Worker
1352*890232f2SAndroid Build Coastguard Worker    # Multiple-element map of different types
1353*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1354*890232f2SAndroid Build Coastguard Worker    with fbb.Map():
1355*890232f2SAndroid Build Coastguard Worker      fbb.Null('n')
1356*890232f2SAndroid Build Coastguard Worker      fbb.Bool('b', False)
1357*890232f2SAndroid Build Coastguard Worker      fbb.Int('i', -27)
1358*890232f2SAndroid Build Coastguard Worker      fbb.UInt('u', 27)
1359*890232f2SAndroid Build Coastguard Worker      fbb.Float('f', -0.85)
1360*890232f2SAndroid Build Coastguard Worker      fbb.String('s', 'String')
1361*890232f2SAndroid Build Coastguard Worker      fbb.Blob('bb', b'data')
1362*890232f2SAndroid Build Coastguard Worker      fbb.IndirectInt('ii', -9500)
1363*890232f2SAndroid Build Coastguard Worker      fbb.IndirectUInt('iu', 540)
1364*890232f2SAndroid Build Coastguard Worker      fbb.IndirectFloat('if', 0.0)
1365*890232f2SAndroid Build Coastguard Worker      fbb.VectorFromElements('v', [2, 1, 0.0])
1366*890232f2SAndroid Build Coastguard Worker      fbb.TypedVectorFromElements('tv', [2, 1, 0])
1367*890232f2SAndroid Build Coastguard Worker      fbb.FixedTypedVectorFromElements('ftv', [2.0, -6.0])
1368*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1369*890232f2SAndroid Build Coastguard Worker
1370*890232f2SAndroid Build Coastguard Worker    self.assertEqual(
1371*890232f2SAndroid Build Coastguard Worker        flexbuffers.Loads(data), {
1372*890232f2SAndroid Build Coastguard Worker            'n': None,
1373*890232f2SAndroid Build Coastguard Worker            'b': False,
1374*890232f2SAndroid Build Coastguard Worker            'i': -27,
1375*890232f2SAndroid Build Coastguard Worker            'u': 27,
1376*890232f2SAndroid Build Coastguard Worker            'f': -0.85,
1377*890232f2SAndroid Build Coastguard Worker            's': 'String',
1378*890232f2SAndroid Build Coastguard Worker            'bb': b'data',
1379*890232f2SAndroid Build Coastguard Worker            'ii': -9500,
1380*890232f2SAndroid Build Coastguard Worker            'iu': 540,
1381*890232f2SAndroid Build Coastguard Worker            'if': 0.0,
1382*890232f2SAndroid Build Coastguard Worker            'v': [2, 1, 0.0],
1383*890232f2SAndroid Build Coastguard Worker            'tv': [2, 1, 0],
1384*890232f2SAndroid Build Coastguard Worker            'ftv': [2.0, -6.0]
1385*890232f2SAndroid Build Coastguard Worker        })
1386*890232f2SAndroid Build Coastguard Worker
1387*890232f2SAndroid Build Coastguard Worker    keys = get_keys(data)
1388*890232f2SAndroid Build Coastguard Worker    self.assertEqual(sorted(keys), keys)
1389*890232f2SAndroid Build Coastguard Worker
1390*890232f2SAndroid Build Coastguard Worker  def test_map_python(self):
1391*890232f2SAndroid Build Coastguard Worker    maps = [
1392*890232f2SAndroid Build Coastguard Worker        {},
1393*890232f2SAndroid Build Coastguard Worker        {
1394*890232f2SAndroid Build Coastguard Worker            'key': 'value'
1395*890232f2SAndroid Build Coastguard Worker        },
1396*890232f2SAndroid Build Coastguard Worker        {
1397*890232f2SAndroid Build Coastguard Worker            'x': None,
1398*890232f2SAndroid Build Coastguard Worker            'y': 3400,
1399*890232f2SAndroid Build Coastguard Worker            'z': -7040
1400*890232f2SAndroid Build Coastguard Worker        },
1401*890232f2SAndroid Build Coastguard Worker        {
1402*890232f2SAndroid Build Coastguard Worker            'zzz': 100,
1403*890232f2SAndroid Build Coastguard Worker            'aaa': 5.0,
1404*890232f2SAndroid Build Coastguard Worker            'ccc': ['Test', 32, False, None, True]
1405*890232f2SAndroid Build Coastguard Worker        },
1406*890232f2SAndroid Build Coastguard Worker        {
1407*890232f2SAndroid Build Coastguard Worker            'name': ['John', 'Smith'],
1408*890232f2SAndroid Build Coastguard Worker            'valid': True,
1409*890232f2SAndroid Build Coastguard Worker            'note': None,
1410*890232f2SAndroid Build Coastguard Worker            'address': {
1411*890232f2SAndroid Build Coastguard Worker                'lines': [175, 'Alhambra'],
1412*890232f2SAndroid Build Coastguard Worker                'city': 'San Francisco',
1413*890232f2SAndroid Build Coastguard Worker                'zip': 94123,
1414*890232f2SAndroid Build Coastguard Worker            },
1415*890232f2SAndroid Build Coastguard Worker        },
1416*890232f2SAndroid Build Coastguard Worker    ]
1417*890232f2SAndroid Build Coastguard Worker
1418*890232f2SAndroid Build Coastguard Worker    for m in maps:
1419*890232f2SAndroid Build Coastguard Worker      self.assertEqual(flexbuffers.Loads(flexbuffers.Dumps(m)), m)
1420*890232f2SAndroid Build Coastguard Worker
1421*890232f2SAndroid Build Coastguard Worker  def test_gold_from_file(self):
1422*890232f2SAndroid Build Coastguard Worker    data = read_test_file(GOLD_FLEXBUFFER_FILE)
1423*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), GOLD_FLEXBUFFER_OBJ)
1424*890232f2SAndroid Build Coastguard Worker
1425*890232f2SAndroid Build Coastguard Worker  def test_gold_from_builder(self):
1426*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1427*890232f2SAndroid Build Coastguard Worker    with fbb.Map():
1428*890232f2SAndroid Build Coastguard Worker      with fbb.Vector('vec'):
1429*890232f2SAndroid Build Coastguard Worker        fbb.Int(-100)
1430*890232f2SAndroid Build Coastguard Worker        fbb.String('Fred')
1431*890232f2SAndroid Build Coastguard Worker        fbb.IndirectFloat(4.0)
1432*890232f2SAndroid Build Coastguard Worker        i_f = fbb.LastValue
1433*890232f2SAndroid Build Coastguard Worker        fbb.Blob(bytes([77]))
1434*890232f2SAndroid Build Coastguard Worker        fbb.Bool(False)
1435*890232f2SAndroid Build Coastguard Worker        fbb.ReuseValue(i_f)
1436*890232f2SAndroid Build Coastguard Worker
1437*890232f2SAndroid Build Coastguard Worker      vec = [1, 2, 3]
1438*890232f2SAndroid Build Coastguard Worker      fbb.VectorFromElements('bar', vec)
1439*890232f2SAndroid Build Coastguard Worker      fbb.FixedTypedVectorFromElements('bar3', [1, 2, 3])
1440*890232f2SAndroid Build Coastguard Worker      fbb.VectorFromElements('bools', [True, False, True, False])
1441*890232f2SAndroid Build Coastguard Worker      fbb.Bool('bool', True)
1442*890232f2SAndroid Build Coastguard Worker      fbb.Float('foo', 100)
1443*890232f2SAndroid Build Coastguard Worker      with fbb.Map('mymap'):
1444*890232f2SAndroid Build Coastguard Worker        fbb.String('foo', 'Fred')
1445*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1446*890232f2SAndroid Build Coastguard Worker
1447*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), GOLD_FLEXBUFFER_OBJ)
1448*890232f2SAndroid Build Coastguard Worker
1449*890232f2SAndroid Build Coastguard Worker  def test_min_bit_width(self):
1450*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder(force_min_bit_width=flexbuffers.BitWidth.W8)
1451*890232f2SAndroid Build Coastguard Worker    fbb.TypedVectorFromElements([0, 1, 0, 1, 0])
1452*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1453*890232f2SAndroid Build Coastguard Worker
1454*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(data)
1455*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsTypedVector)
1456*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsTypedVector.ByteWidth, 1)
1457*890232f2SAndroid Build Coastguard Worker
1458*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder(force_min_bit_width=flexbuffers.BitWidth.W32)
1459*890232f2SAndroid Build Coastguard Worker    fbb.TypedVectorFromElements([0, 1, 0, 1, 0])
1460*890232f2SAndroid Build Coastguard Worker    data = fbb.Finish()
1461*890232f2SAndroid Build Coastguard Worker
1462*890232f2SAndroid Build Coastguard Worker    root = flexbuffers.GetRoot(data)
1463*890232f2SAndroid Build Coastguard Worker    self.assertTrue(root.IsTypedVector)
1464*890232f2SAndroid Build Coastguard Worker    self.assertEqual(root.AsTypedVector.ByteWidth, 4)
1465*890232f2SAndroid Build Coastguard Worker
1466*890232f2SAndroid Build Coastguard Worker  def test_share_keys(self):
1467*890232f2SAndroid Build Coastguard Worker
1468*890232f2SAndroid Build Coastguard Worker    def encode_key_vector(value, count, share_keys):
1469*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder(share_keys=share_keys)
1470*890232f2SAndroid Build Coastguard Worker      with fbb.Vector():
1471*890232f2SAndroid Build Coastguard Worker        for _ in range(count):
1472*890232f2SAndroid Build Coastguard Worker          fbb.Key(value)
1473*890232f2SAndroid Build Coastguard Worker      return fbb.Finish(), fbb.KeyPool.Elements
1474*890232f2SAndroid Build Coastguard Worker
1475*890232f2SAndroid Build Coastguard Worker    data, pool = encode_key_vector('test', 10, share_keys=False)
1476*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(pool), 0)
1477*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(data), 74)
1478*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), 10 * ['test'])
1479*890232f2SAndroid Build Coastguard Worker
1480*890232f2SAndroid Build Coastguard Worker    data, pool = encode_key_vector('test', 10, share_keys=True)
1481*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(pool), 1)
1482*890232f2SAndroid Build Coastguard Worker    self.assertEqual(pool[0], 'test'.encode('ascii'))
1483*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(data), 29)
1484*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), 10 * ['test'])
1485*890232f2SAndroid Build Coastguard Worker
1486*890232f2SAndroid Build Coastguard Worker  def test_share_strings(self):
1487*890232f2SAndroid Build Coastguard Worker
1488*890232f2SAndroid Build Coastguard Worker    def encode_string_vector(value, count, share_strings):
1489*890232f2SAndroid Build Coastguard Worker      fbb = flexbuffers.Builder(share_strings=share_strings)
1490*890232f2SAndroid Build Coastguard Worker      with fbb.Vector():
1491*890232f2SAndroid Build Coastguard Worker        for _ in range(count):
1492*890232f2SAndroid Build Coastguard Worker          fbb.String(value)
1493*890232f2SAndroid Build Coastguard Worker      return fbb.Finish(), fbb.StringPool.Elements
1494*890232f2SAndroid Build Coastguard Worker
1495*890232f2SAndroid Build Coastguard Worker    data, pool = encode_string_vector('test', 10, share_strings=False)
1496*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(pool), 0)
1497*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(data), 84)
1498*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), 10 * ['test'])
1499*890232f2SAndroid Build Coastguard Worker
1500*890232f2SAndroid Build Coastguard Worker    data, pool = encode_string_vector('test', 10, share_strings=True)
1501*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(pool), 1)
1502*890232f2SAndroid Build Coastguard Worker    self.assertEqual(pool[0], 'test'.encode('utf-8'))
1503*890232f2SAndroid Build Coastguard Worker    self.assertEqual(len(data), 30)
1504*890232f2SAndroid Build Coastguard Worker    self.assertEqual(flexbuffers.Loads(data), 10 * ['test'])
1505*890232f2SAndroid Build Coastguard Worker
1506*890232f2SAndroid Build Coastguard Worker  def test_invalid_stack_size(self):
1507*890232f2SAndroid Build Coastguard Worker    fbb = flexbuffers.Builder()
1508*890232f2SAndroid Build Coastguard Worker
1509*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(RuntimeError):
1510*890232f2SAndroid Build Coastguard Worker      fbb.Finish()
1511*890232f2SAndroid Build Coastguard Worker
1512*890232f2SAndroid Build Coastguard Worker    fbb.Int(100)
1513*890232f2SAndroid Build Coastguard Worker    fbb.Int(200)
1514*890232f2SAndroid Build Coastguard Worker    with self.assertRaises(RuntimeError):
1515*890232f2SAndroid Build Coastguard Worker      fbb.Finish()
1516*890232f2SAndroid Build Coastguard Worker
1517*890232f2SAndroid Build Coastguard Worker    fbb.Clear()
1518*890232f2SAndroid Build Coastguard Worker    fbb.Int(420)
1519*890232f2SAndroid Build Coastguard Worker    fbb.Finish()
1520*890232f2SAndroid Build Coastguard Worker
1521*890232f2SAndroid Build Coastguard Worker
1522*890232f2SAndroid Build Coastguard Workerif __name__ == '__main__':
1523*890232f2SAndroid Build Coastguard Worker  unittest.main()
1524