| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library test.src.summary.flat_buffers_test; | |
| 6 | |
| 7 import 'dart:typed_data'; | |
| 8 | |
| 9 import 'package:analyzer/src/summary/flat_buffers.dart'; | |
| 10 import 'package:test/test.dart'; | |
| 11 import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
| 12 | |
| 13 main() { | |
| 14 defineReflectiveSuite(() { | |
| 15 defineReflectiveTests(BuilderTest); | |
| 16 }); | |
| 17 } | |
| 18 | |
| 19 @reflectiveTest | |
| 20 class BuilderTest { | |
| 21 void test_error_addInt32_withoutStartTable() { | |
| 22 Builder builder = new Builder(); | |
| 23 expect(() { | |
| 24 builder.addInt32(0, 0); | |
| 25 }, throwsStateError); | |
| 26 } | |
| 27 | |
| 28 void test_error_addOffset_withoutStartTable() { | |
| 29 Builder builder = new Builder(); | |
| 30 expect(() { | |
| 31 builder.addOffset(0, new Offset(0)); | |
| 32 }, throwsStateError); | |
| 33 } | |
| 34 | |
| 35 void test_error_endTable_withoutStartTable() { | |
| 36 Builder builder = new Builder(); | |
| 37 expect(() { | |
| 38 builder.endTable(); | |
| 39 }, throwsStateError); | |
| 40 } | |
| 41 | |
| 42 void test_error_startTable_duringTable() { | |
| 43 Builder builder = new Builder(); | |
| 44 builder.startTable(); | |
| 45 expect(() { | |
| 46 builder.startTable(); | |
| 47 }, throwsStateError); | |
| 48 } | |
| 49 | |
| 50 void test_error_writeString_duringTable() { | |
| 51 Builder builder = new Builder(); | |
| 52 builder.startTable(); | |
| 53 expect(() { | |
| 54 builder.writeString('12345'); | |
| 55 }, throwsStateError); | |
| 56 } | |
| 57 | |
| 58 void test_file_identifier() { | |
| 59 Uint8List byteList; | |
| 60 { | |
| 61 Builder builder = new Builder(initialSize: 0); | |
| 62 builder.startTable(); | |
| 63 Offset offset = builder.endTable(); | |
| 64 byteList = builder.finish(offset, 'Az~ÿ'); | |
| 65 } | |
| 66 // Convert byteList to a ByteData so that we can read data from it. | |
| 67 ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes); | |
| 68 // First 4 bytes are an offset to the table data. | |
| 69 int tableDataLoc = byteData.getUint32(0, Endianness.LITTLE_ENDIAN); | |
| 70 // Next 4 bytes are the file identifier. | |
| 71 expect(byteData.getUint8(4), 65); // 'a' | |
| 72 expect(byteData.getUint8(5), 122); // 'z' | |
| 73 expect(byteData.getUint8(6), 126); // '~' | |
| 74 expect(byteData.getUint8(7), 255); // 'ÿ' | |
| 75 // First 4 bytes of the table data are a backwards offset to the vtable. | |
| 76 int vTableLoc = tableDataLoc - | |
| 77 byteData.getInt32(tableDataLoc, Endianness.LITTLE_ENDIAN); | |
| 78 // First 2 bytes of the vtable are the size of the vtable in bytes, which | |
| 79 // should be 4. | |
| 80 expect(byteData.getUint16(vTableLoc, Endianness.LITTLE_ENDIAN), 4); | |
| 81 // Next 2 bytes are the size of the object in bytes (including the vtable | |
| 82 // pointer), which should be 4. | |
| 83 expect(byteData.getUint16(vTableLoc + 2, Endianness.LITTLE_ENDIAN), 4); | |
| 84 } | |
| 85 | |
| 86 void test_low() { | |
| 87 Builder builder = new Builder(initialSize: 0); | |
| 88 builder.lowReset(); | |
| 89 expect((builder..lowWriteUint8(1)).lowFinish(), [1]); | |
| 90 expect((builder..lowWriteUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]); | |
| 91 expect((builder..lowWriteUint8(3)).lowFinish(), | |
| 92 [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]); | |
| 93 expect((builder..lowWriteUint8(4)).lowFinish(), | |
| 94 [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); | |
| 95 expect((builder..lowWriteUint8(5)).lowFinish(), | |
| 96 [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); | |
| 97 expect((builder..lowWriteUint32(6)).lowFinish(), | |
| 98 [6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); | |
| 99 } | |
| 100 | |
| 101 void test_table_default() { | |
| 102 List<int> byteList; | |
| 103 { | |
| 104 Builder builder = new Builder(initialSize: 0); | |
| 105 builder.startTable(); | |
| 106 builder.addInt32(0, 10, 10); | |
| 107 builder.addInt32(1, 20, 10); | |
| 108 Offset offset = builder.endTable(); | |
| 109 byteList = builder.finish(offset); | |
| 110 } | |
| 111 // read and verify | |
| 112 BufferContext buffer = new BufferContext.fromBytes(byteList); | |
| 113 int objectOffset = buffer.derefObject(0); | |
| 114 // was not written, so uses the new default value | |
| 115 expect(const Int32Reader().vTableGet(buffer, objectOffset, 0, 15), 15); | |
| 116 // has the written value | |
| 117 expect(const Int32Reader().vTableGet(buffer, objectOffset, 1, 15), 20); | |
| 118 } | |
| 119 | |
| 120 void test_table_format() { | |
| 121 Uint8List byteList; | |
| 122 { | |
| 123 Builder builder = new Builder(initialSize: 0); | |
| 124 builder.startTable(); | |
| 125 builder.addInt32(0, 10); | |
| 126 builder.addInt32(1, 20); | |
| 127 builder.addInt32(2, 30); | |
| 128 byteList = builder.finish(builder.endTable()); | |
| 129 } | |
| 130 // Convert byteList to a ByteData so that we can read data from it. | |
| 131 ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes); | |
| 132 // First 4 bytes are an offset to the table data. | |
| 133 int tableDataLoc = byteData.getUint32(0, Endianness.LITTLE_ENDIAN); | |
| 134 // First 4 bytes of the table data are a backwards offset to the vtable. | |
| 135 int vTableLoc = tableDataLoc - | |
| 136 byteData.getInt32(tableDataLoc, Endianness.LITTLE_ENDIAN); | |
| 137 // First 2 bytes of the vtable are the size of the vtable in bytes, which | |
| 138 // should be 10. | |
| 139 expect(byteData.getUint16(vTableLoc, Endianness.LITTLE_ENDIAN), 10); | |
| 140 // Next 2 bytes are the size of the object in bytes (including the vtable | |
| 141 // pointer), which should be 16. | |
| 142 expect(byteData.getUint16(vTableLoc + 2, Endianness.LITTLE_ENDIAN), 16); | |
| 143 // Remaining 6 bytes are the offsets within the object where the ints are | |
| 144 // located. | |
| 145 for (int i = 0; i < 3; i++) { | |
| 146 int offset = | |
| 147 byteData.getUint16(vTableLoc + 4 + 2 * i, Endianness.LITTLE_ENDIAN); | |
| 148 expect(byteData.getInt32(tableDataLoc + offset, Endianness.LITTLE_ENDIAN), | |
| 149 10 + 10 * i); | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 void test_table_string() { | |
| 154 String latinString = 'test'; | |
| 155 String unicodeString = 'Проба пера'; | |
| 156 List<int> byteList; | |
| 157 { | |
| 158 Builder builder = new Builder(initialSize: 0); | |
| 159 Offset<String> latinStringOffset = builder.writeString(latinString); | |
| 160 Offset<String> unicodeStringOffset = builder.writeString(unicodeString); | |
| 161 builder.startTable(); | |
| 162 builder.addOffset(0, latinStringOffset); | |
| 163 builder.addOffset(1, unicodeStringOffset); | |
| 164 Offset offset = builder.endTable(); | |
| 165 byteList = builder.finish(offset); | |
| 166 } | |
| 167 // read and verify | |
| 168 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 169 int objectOffset = buf.derefObject(0); | |
| 170 expect(const StringReader().vTableGet(buf, objectOffset, 0), latinString); | |
| 171 expect(const StringReader().vTableGet(buf, objectOffset, 1), unicodeString); | |
| 172 } | |
| 173 | |
| 174 void test_table_types() { | |
| 175 List<int> byteList; | |
| 176 { | |
| 177 Builder builder = new Builder(initialSize: 0); | |
| 178 Offset<String> stringOffset = builder.writeString('12345'); | |
| 179 builder.startTable(); | |
| 180 builder.addBool(0, true); | |
| 181 builder.addInt8(1, 10); | |
| 182 builder.addInt32(2, 20); | |
| 183 builder.addOffset(3, stringOffset); | |
| 184 builder.addInt32(4, 40); | |
| 185 builder.addUint32(5, 0x9ABCDEF0); | |
| 186 builder.addUint8(6, 0x9A); | |
| 187 Offset offset = builder.endTable(); | |
| 188 byteList = builder.finish(offset); | |
| 189 } | |
| 190 // read and verify | |
| 191 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 192 int objectOffset = buf.derefObject(0); | |
| 193 expect(const BoolReader().vTableGet(buf, objectOffset, 0), true); | |
| 194 expect(const Int8Reader().vTableGet(buf, objectOffset, 1), 10); | |
| 195 expect(const Int32Reader().vTableGet(buf, objectOffset, 2), 20); | |
| 196 expect(const StringReader().vTableGet(buf, objectOffset, 3), '12345'); | |
| 197 expect(const Int32Reader().vTableGet(buf, objectOffset, 4), 40); | |
| 198 expect(const Uint32Reader().vTableGet(buf, objectOffset, 5), 0x9ABCDEF0); | |
| 199 expect(const Uint8Reader().vTableGet(buf, objectOffset, 6), 0x9A); | |
| 200 } | |
| 201 | |
| 202 void test_writeList_of_Uint32() { | |
| 203 List<int> values = <int>[10, 100, 12345, 0x9abcdef0]; | |
| 204 // write | |
| 205 List<int> byteList; | |
| 206 { | |
| 207 Builder builder = new Builder(initialSize: 0); | |
| 208 Offset offset = builder.writeListUint32(values); | |
| 209 byteList = builder.finish(offset); | |
| 210 } | |
| 211 // read and verify | |
| 212 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 213 List<int> items = const Uint32ListReader().read(buf, 0); | |
| 214 expect(items, hasLength(4)); | |
| 215 expect(items, orderedEquals(values)); | |
| 216 } | |
| 217 | |
| 218 void test_writeList_ofBool() { | |
| 219 void verifyListBooleans(int len, List<int> trueBits) { | |
| 220 // write | |
| 221 List<int> byteList; | |
| 222 { | |
| 223 Builder builder = new Builder(initialSize: 0); | |
| 224 List<bool> values = new List<bool>.filled(len, false); | |
| 225 for (int bit in trueBits) { | |
| 226 values[bit] = true; | |
| 227 } | |
| 228 Offset offset = builder.writeListBool(values); | |
| 229 byteList = builder.finish(offset); | |
| 230 } | |
| 231 // read and verify | |
| 232 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 233 List<bool> items = const BoolListReader().read(buf, 0); | |
| 234 expect(items, hasLength(len)); | |
| 235 for (int i = 0; i < items.length; i++) { | |
| 236 expect(items[i], trueBits.contains(i), reason: 'bit $i of $len'); | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 verifyListBooleans(0, <int>[]); | |
| 241 verifyListBooleans(1, <int>[]); | |
| 242 verifyListBooleans(1, <int>[0]); | |
| 243 verifyListBooleans(31, <int>[0, 1]); | |
| 244 verifyListBooleans(31, <int>[1, 2, 24, 25, 30]); | |
| 245 verifyListBooleans(31, <int>[0, 30]); | |
| 246 verifyListBooleans(32, <int>[1, 2, 24, 25, 31]); | |
| 247 verifyListBooleans(33, <int>[1, 2, 24, 25, 32]); | |
| 248 verifyListBooleans(33, <int>[1, 2, 24, 25, 31, 32]); | |
| 249 verifyListBooleans(63, <int>[]); | |
| 250 verifyListBooleans(63, <int>[0, 1, 2, 61, 62]); | |
| 251 verifyListBooleans(63, new List<int>.generate(63, (i) => i)); | |
| 252 verifyListBooleans(64, <int>[]); | |
| 253 verifyListBooleans(64, <int>[0, 1, 2, 61, 62, 63]); | |
| 254 verifyListBooleans(64, <int>[1, 2, 62]); | |
| 255 verifyListBooleans(64, <int>[0, 1, 2, 63]); | |
| 256 verifyListBooleans(64, new List<int>.generate(64, (i) => i)); | |
| 257 verifyListBooleans(100, <int>[0, 3, 30, 60, 90, 99]); | |
| 258 } | |
| 259 | |
| 260 void test_writeList_ofFloat64() { | |
| 261 List<double> values = <double>[-1.234567, 3.4E+9, -5.6E-13, 7.8, 12.13]; | |
| 262 // write | |
| 263 List<int> byteList; | |
| 264 { | |
| 265 Builder builder = new Builder(initialSize: 0); | |
| 266 Offset offset = builder.writeListFloat64(values); | |
| 267 byteList = builder.finish(offset); | |
| 268 } | |
| 269 // read and verify | |
| 270 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 271 List<double> items = const Float64ListReader().read(buf, 0); | |
| 272 expect(items, hasLength(5)); | |
| 273 expect(items, orderedEquals(values)); | |
| 274 } | |
| 275 | |
| 276 void test_writeList_ofInt32() { | |
| 277 List<int> byteList; | |
| 278 { | |
| 279 Builder builder = new Builder(initialSize: 0); | |
| 280 Offset offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]); | |
| 281 byteList = builder.finish(offset); | |
| 282 } | |
| 283 // read and verify | |
| 284 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 285 List<int> items = const ListReader<int>(const Int32Reader()).read(buf, 0); | |
| 286 expect(items, hasLength(5)); | |
| 287 expect(items, orderedEquals(<int>[1, 2, 3, 4, 5])); | |
| 288 } | |
| 289 | |
| 290 void test_writeList_ofObjects() { | |
| 291 List<int> byteList; | |
| 292 { | |
| 293 Builder builder = new Builder(initialSize: 0); | |
| 294 // write the object #1 | |
| 295 Offset object1; | |
| 296 { | |
| 297 builder.startTable(); | |
| 298 builder.addInt32(0, 10); | |
| 299 builder.addInt32(1, 20); | |
| 300 object1 = builder.endTable(); | |
| 301 } | |
| 302 // write the object #1 | |
| 303 Offset object2; | |
| 304 { | |
| 305 builder.startTable(); | |
| 306 builder.addInt32(0, 100); | |
| 307 builder.addInt32(1, 200); | |
| 308 object2 = builder.endTable(); | |
| 309 } | |
| 310 // write the list | |
| 311 Offset offset = builder.writeList([object1, object2]); | |
| 312 byteList = builder.finish(offset); | |
| 313 } | |
| 314 // read and verify | |
| 315 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 316 List<TestPointImpl> items = | |
| 317 const ListReader<TestPointImpl>(const TestPointReader()).read(buf, 0); | |
| 318 expect(items, hasLength(2)); | |
| 319 expect(items[0].x, 10); | |
| 320 expect(items[0].y, 20); | |
| 321 expect(items[1].x, 100); | |
| 322 expect(items[1].y, 200); | |
| 323 } | |
| 324 | |
| 325 void test_writeList_ofStrings_asRoot() { | |
| 326 List<int> byteList; | |
| 327 { | |
| 328 Builder builder = new Builder(initialSize: 0); | |
| 329 Offset<String> str1 = builder.writeString('12345'); | |
| 330 Offset<String> str2 = builder.writeString('ABC'); | |
| 331 Offset offset = builder.writeList([str1, str2]); | |
| 332 byteList = builder.finish(offset); | |
| 333 } | |
| 334 // read and verify | |
| 335 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 336 List<String> items = | |
| 337 const ListReader<String>(const StringReader()).read(buf, 0); | |
| 338 expect(items, hasLength(2)); | |
| 339 expect(items, contains('12345')); | |
| 340 expect(items, contains('ABC')); | |
| 341 } | |
| 342 | |
| 343 void test_writeList_ofStrings_inObject() { | |
| 344 List<int> byteList; | |
| 345 { | |
| 346 Builder builder = new Builder(initialSize: 0); | |
| 347 Offset listOffset = builder.writeList( | |
| 348 [builder.writeString('12345'), builder.writeString('ABC')]); | |
| 349 builder.startTable(); | |
| 350 builder.addOffset(0, listOffset); | |
| 351 Offset offset = builder.endTable(); | |
| 352 byteList = builder.finish(offset); | |
| 353 } | |
| 354 // read and verify | |
| 355 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 356 StringListWrapperImpl reader = new StringListWrapperReader().read(buf, 0); | |
| 357 List<String> items = reader.items; | |
| 358 expect(items, hasLength(2)); | |
| 359 expect(items, contains('12345')); | |
| 360 expect(items, contains('ABC')); | |
| 361 } | |
| 362 | |
| 363 void test_writeList_ofUint32() { | |
| 364 List<int> byteList; | |
| 365 { | |
| 366 Builder builder = new Builder(initialSize: 0); | |
| 367 Offset offset = builder.writeListUint32(<int>[1, 2, 0x9ABCDEF0]); | |
| 368 byteList = builder.finish(offset); | |
| 369 } | |
| 370 // read and verify | |
| 371 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 372 List<int> items = const Uint32ListReader().read(buf, 0); | |
| 373 expect(items, hasLength(3)); | |
| 374 expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0])); | |
| 375 } | |
| 376 | |
| 377 void test_writeList_ofUint8() { | |
| 378 List<int> byteList; | |
| 379 { | |
| 380 Builder builder = new Builder(initialSize: 0); | |
| 381 Offset offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]); | |
| 382 byteList = builder.finish(offset); | |
| 383 } | |
| 384 // read and verify | |
| 385 BufferContext buf = new BufferContext.fromBytes(byteList); | |
| 386 List<int> items = const Uint8ListReader().read(buf, 0); | |
| 387 expect(items, hasLength(5)); | |
| 388 expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A])); | |
| 389 } | |
| 390 } | |
| 391 | |
| 392 class StringListWrapperImpl { | |
| 393 final BufferContext bp; | |
| 394 final int offset; | |
| 395 | |
| 396 StringListWrapperImpl(this.bp, this.offset); | |
| 397 | |
| 398 List<String> get items => | |
| 399 const ListReader<String>(const StringReader()).vTableGet(bp, offset, 0); | |
| 400 } | |
| 401 | |
| 402 class StringListWrapperReader extends TableReader<StringListWrapperImpl> { | |
| 403 const StringListWrapperReader(); | |
| 404 | |
| 405 @override | |
| 406 StringListWrapperImpl createObject(BufferContext object, int offset) { | |
| 407 return new StringListWrapperImpl(object, offset); | |
| 408 } | |
| 409 } | |
| 410 | |
| 411 class TestPointImpl { | |
| 412 final BufferContext bp; | |
| 413 final int offset; | |
| 414 | |
| 415 TestPointImpl(this.bp, this.offset); | |
| 416 | |
| 417 int get x => const Int32Reader().vTableGet(bp, offset, 0, 0); | |
| 418 | |
| 419 int get y => const Int32Reader().vTableGet(bp, offset, 1, 0); | |
| 420 } | |
| 421 | |
| 422 class TestPointReader extends TableReader<TestPointImpl> { | |
| 423 const TestPointReader(); | |
| 424 | |
| 425 @override | |
| 426 TestPointImpl createObject(BufferContext object, int offset) { | |
| 427 return new TestPointImpl(object, offset); | |
| 428 } | |
| 429 } | |
| OLD | NEW |