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