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