• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import 'dart:typed_data';
6import 'dart:io' as io;
7
8import 'package:path/path.dart' as path;
9
10import 'package:flat_buffers/flat_buffers.dart';
11import 'package:test/test.dart';
12import 'package:test_reflective_loader/test_reflective_loader.dart';
13
14import './monster_test_my_game.example_generated.dart' as example;
15
16main() {
17  defineReflectiveSuite(() {
18    defineReflectiveTests(BuilderTest);
19    defineReflectiveTests(CheckOtherLangaugesData);
20    defineReflectiveTests(GeneratorTest);
21  });
22}
23
24int indexToField(int index) {
25  return (1 + 1 + index) * 2;
26}
27
28@reflectiveTest
29class CheckOtherLangaugesData {
30  test_cppData() async {
31    List<int> data = await new io.File(path.join(
32      path.dirname(io.Platform.script.path),
33      'monsterdata_test.mon',
34    )).readAsBytes();
35    example.Monster mon = new example.Monster(data);
36    expect(mon.hp, 80);
37    expect(mon.mana, 150);
38    expect(mon.name, 'MyMonster');
39    expect(mon.pos.x, 1.0);
40    expect(mon.pos.y, 2.0);
41    expect(mon.pos.z, 3.0);
42    expect(mon.pos.test1, 3.0);
43    expect(mon.pos.test2.value, 2.0);
44    expect(mon.pos.test3.a, 5);
45    expect(mon.pos.test3.b, 6);
46    expect(mon.testType.value, example.AnyTypeId.Monster.value);
47    expect(mon.test is example.Monster, true);
48    final monster2 = mon.test as example.Monster;
49    expect(monster2.name, "Fred");
50
51    expect(mon.inventory.length, 5);
52    expect(mon.inventory.reduce((cur, next) => cur + next), 10);
53    expect(mon.test4.length, 2);
54    expect(
55        mon.test4[0].a + mon.test4[0].b + mon.test4[1].a + mon.test4[1].b, 100);
56    expect(mon.testarrayofstring.length, 2);
57    expect(mon.testarrayofstring[0], "test1");
58    expect(mon.testarrayofstring[1], "test2");
59
60    // this will fail if accessing any field fails.
61    expect(
62      mon.toString(),
63      'Monster{'
64      'pos: Vec3{x: 1.0, y: 2.0, z: 3.0, test1: 3.0, test2: Color{value: 2}, test3: Test{a: 5, b: 6}}, '
65      'mana: 150, hp: 80, name: MyMonster, inventory: [0, 1, 2, 3, 4], '
66      'color: Color{value: 8}, testType: AnyTypeId{value: 1}, '
67      'test: Monster{pos: null, mana: 150, hp: 100, name: Fred, '
68      'inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, '
69      'test: null, test4: null, testarrayofstring: null, '
70      'testarrayoftables: null, enemy: null, testnestedflatbuffer: null, '
71      'testempty: null, testbool: false, testhashs32Fnv1: 0, '
72      'testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, '
73      'testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, '
74      'testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, '
75      'testf2: 3.0, testf3: 0.0, testarrayofstring2: null, '
76      'testarrayofsortedstruct: null, flex: null, test5: null, '
77      'vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, '
78      'vectorOfReferrables: null, singleWeakReference: 0, '
79      'vectorOfWeakReferences: null, vectorOfStrongReferrables: null, '
80      'coOwningReference: 0, vectorOfCoOwningReferences: null, '
81      'nonOwningReference: 0, vectorOfNonOwningReferences: null, '
82      'anyUniqueType: AnyUniqueAliasesTypeId{value: 0}, anyUnique: null, '
83      'anyAmbiguousType: AnyAmbiguousAliasesTypeId{value: 0}, '
84      'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race{value: -1}, '
85      'testrequirednestedflatbuffer: null}, '
86      'test4: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], '
87      'testarrayofstring: [test1, test2], testarrayoftables: null, '
88      'enemy: Monster{pos: null, mana: 150, hp: 100, name: Fred, '
89      'inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, '
90      'test: null, test4: null, testarrayofstring: null, '
91      'testarrayoftables: null, enemy: null, testnestedflatbuffer: null, '
92      'testempty: null, testbool: false, testhashs32Fnv1: 0, '
93      'testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, '
94      'testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, '
95      'testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, '
96      'testf2: 3.0, testf3: 0.0, testarrayofstring2: null, '
97      'testarrayofsortedstruct: null, flex: null, test5: null, '
98      'vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, '
99      'vectorOfReferrables: null, singleWeakReference: 0, '
100      'vectorOfWeakReferences: null, vectorOfStrongReferrables: null, '
101      'coOwningReference: 0, vectorOfCoOwningReferences: null, '
102      'nonOwningReference: 0, vectorOfNonOwningReferences: null, '
103      'anyUniqueType: AnyUniqueAliasesTypeId{value: 0}, anyUnique: null, '
104      'anyAmbiguousType: AnyAmbiguousAliasesTypeId{value: 0}, '
105      'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race{value: -1}, '
106      'testrequirednestedflatbuffer: null}, '
107      'testnestedflatbuffer: null, testempty: null, testbool: true, '
108      'testhashs32Fnv1: -579221183, testhashu32Fnv1: 3715746113, '
109      'testhashs64Fnv1: 7930699090847568257, '
110      'testhashu64Fnv1: 7930699090847568257, '
111      'testhashs32Fnv1a: -1904106383, testhashu32Fnv1a: 2390860913, '
112      'testhashs64Fnv1a: 4898026182817603057, '
113      'testhashu64Fnv1a: 4898026182817603057, '
114      'testarrayofbools: [true, false, true], testf: 3.14159, testf2: 3.0, '
115      'testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, '
116      'flex: null, test5: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], '
117      'vectorOfLongs: [1, 100, 10000, 1000000, 100000000], '
118      'vectorOfDoubles: [-1.7976931348623157e+308, 0.0, 1.7976931348623157e+308], '
119      'parentNamespaceTest: null, vectorOfReferrables: null, '
120      'singleWeakReference: 0, vectorOfWeakReferences: null, '
121      'vectorOfStrongReferrables: null, coOwningReference: 0, '
122      'vectorOfCoOwningReferences: null, nonOwningReference: 0, '
123      'vectorOfNonOwningReferences: null, '
124      'anyUniqueType: AnyUniqueAliasesTypeId{value: 0}, anyUnique: null, '
125      'anyAmbiguousType: AnyAmbiguousAliasesTypeId{value: 0}, '
126      'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race{value: -1}, '
127      'testrequirednestedflatbuffer: null}',
128    );
129  }
130}
131
132@reflectiveTest
133class BuilderTest {
134  void test_monsterBuilder() {
135    final fbBuilder = new Builder();
136    final str = fbBuilder.writeString('MyMonster');
137
138    fbBuilder.writeString('test1');
139    fbBuilder.writeString('test2');
140    final testArrayOfString = fbBuilder.endStructVector(2);
141
142    final fred = fbBuilder.writeString('Fred');
143
144    final List<int> treasure = [0, 1, 2, 3, 4];
145    final inventory = fbBuilder.writeListUint8(treasure);
146
147    final monBuilder = new example.MonsterBuilder(fbBuilder)
148      ..begin()
149      ..addNameOffset(fred);
150    final mon2 = monBuilder.finish();
151
152    final testBuilder = new example.TestBuilder(fbBuilder);
153    testBuilder.finish(10, 20);
154    testBuilder.finish(30, 40);
155    final test4 = fbBuilder.endStructVector(2);
156
157    monBuilder
158      ..begin()
159      ..addPos(
160        new example.Vec3Builder(fbBuilder).finish(
161          1.0,
162          2.0,
163          3.0,
164          3.0,
165          example.Color.Green,
166          () => testBuilder.finish(5, 6),
167        ),
168      )
169      ..addHp(80)
170      ..addNameOffset(str)
171      ..addInventoryOffset(inventory)
172      ..addTestType(example.AnyTypeId.Monster)
173      ..addTestOffset(mon2)
174      ..addTest4Offset(test4)
175      ..addTestarrayofstringOffset(testArrayOfString);
176    final mon = monBuilder.finish();
177    fbBuilder.finish(mon);
178  }
179
180  void test_error_addInt32_withoutStartTable() {
181    Builder builder = new Builder();
182    expect(() {
183      builder.addInt32(0, 0);
184    }, throwsStateError);
185  }
186
187  void test_error_addOffset_withoutStartTable() {
188    Builder builder = new Builder();
189    expect(() {
190      builder.addOffset(0, 0);
191    }, throwsStateError);
192  }
193
194  void test_error_endTable_withoutStartTable() {
195    Builder builder = new Builder();
196    expect(() {
197      builder.endTable();
198    }, throwsStateError);
199  }
200
201  void test_error_startTable_duringTable() {
202    Builder builder = new Builder();
203    builder.startTable();
204    expect(() {
205      builder.startTable();
206    }, throwsStateError);
207  }
208
209  void test_error_writeString_duringTable() {
210    Builder builder = new Builder();
211    builder.startTable();
212    expect(() {
213      builder.writeString('12345');
214    }, throwsStateError);
215  }
216
217  void test_file_identifier() {
218    Uint8List byteList;
219    {
220      Builder builder = new Builder(initialSize: 0);
221      builder.startTable();
222      int offset = builder.endTable();
223      byteList = builder.finish(offset, 'Az~ÿ');
224    }
225    // Convert byteList to a ByteData so that we can read data from it.
226    ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
227    // First 4 bytes are an offset to the table data.
228    int tableDataLoc = byteData.getUint32(0, Endian.little);
229    // Next 4 bytes are the file identifier.
230    expect(byteData.getUint8(4), 65); // 'a'
231    expect(byteData.getUint8(5), 122); // 'z'
232    expect(byteData.getUint8(6), 126); // '~'
233    expect(byteData.getUint8(7), 255); // 'ÿ'
234    // First 4 bytes of the table data are a backwards offset to the vtable.
235    int vTableLoc =
236        tableDataLoc - byteData.getInt32(tableDataLoc, Endian.little);
237    // First 2 bytes of the vtable are the size of the vtable in bytes, which
238    // should be 4.
239    expect(byteData.getUint16(vTableLoc, Endian.little), 4);
240    // Next 2 bytes are the size of the object in bytes (including the vtable
241    // pointer), which should be 4.
242    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 4);
243  }
244
245  void test_low() {
246    Builder builder = new Builder(initialSize: 0);
247    expect((builder..putUint8(1)).lowFinish(), [1]);
248    expect((builder..putUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]);
249    expect((builder..putUint8(3)).lowFinish(),
250        [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
251    expect((builder..putUint8(4)).lowFinish(),
252        [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
253    expect((builder..putUint8(5)).lowFinish(),
254        [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
255    expect((builder..putUint32(6)).lowFinish(),
256        [6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
257  }
258
259  void test_table_default() {
260    List<int> byteList;
261    {
262      Builder builder = new Builder(initialSize: 0);
263      builder.startTable();
264      builder.addInt32(0, 10, 10);
265      builder.addInt32(1, 20, 10);
266      int offset = builder.endTable();
267      byteList = builder.finish(offset);
268      expect(builder.size(), byteList.length);
269    }
270    // read and verify
271    BufferContext buffer = new BufferContext.fromBytes(byteList);
272    int objectOffset = buffer.derefObject(0);
273    // was not written, so uses the new default value
274    expect(
275        const Int32Reader()
276            .vTableGet(buffer, objectOffset, indexToField(0), 15),
277        15);
278    // has the written value
279    expect(
280        const Int32Reader()
281            .vTableGet(buffer, objectOffset, indexToField(1), 15),
282        20);
283  }
284
285  void test_table_format() {
286    Uint8List byteList;
287    {
288      Builder builder = new Builder(initialSize: 0);
289      builder.startTable();
290      builder.addInt32(0, 10);
291      builder.addInt32(1, 20);
292      builder.addInt32(2, 30);
293      byteList = builder.finish(builder.endTable());
294    }
295    // Convert byteList to a ByteData so that we can read data from it.
296    ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
297    // First 4 bytes are an offset to the table data.
298    int tableDataLoc = byteData.getUint32(0, Endian.little);
299    // First 4 bytes of the table data are a backwards offset to the vtable.
300    int vTableLoc =
301        tableDataLoc - byteData.getInt32(tableDataLoc, Endian.little);
302    // First 2 bytes of the vtable are the size of the vtable in bytes, which
303    // should be 10.
304    expect(byteData.getUint16(vTableLoc, Endian.little), 10);
305    // Next 2 bytes are the size of the object in bytes (including the vtable
306    // pointer), which should be 16.
307    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 16);
308    // Remaining 6 bytes are the offsets within the object where the ints are
309    // located.
310    for (int i = 0; i < 3; i++) {
311      int offset = byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
312      expect(
313          byteData.getInt32(tableDataLoc + offset, Endian.little), 10 + 10 * i);
314    }
315  }
316
317  void test_table_string() {
318    String latinString = 'test';
319    String unicodeString = 'Проба пера';
320    List<int> byteList;
321    {
322      Builder builder = new Builder(initialSize: 0);
323      int latinStringOffset = builder.writeString(latinString);
324      int unicodeStringOffset = builder.writeString(unicodeString);
325      builder.startTable();
326      builder.addOffset(0, latinStringOffset);
327      builder.addOffset(1, unicodeStringOffset);
328      int offset = builder.endTable();
329      byteList = builder.finish(offset);
330    }
331    // read and verify
332    BufferContext buf = new BufferContext.fromBytes(byteList);
333    int objectOffset = buf.derefObject(0);
334    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(0)),
335        latinString);
336    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(1)),
337        unicodeString);
338  }
339
340  void test_table_types() {
341    List<int> byteList;
342    {
343      Builder builder = new Builder(initialSize: 0);
344      int stringOffset = builder.writeString('12345');
345      builder.startTable();
346      builder.addBool(0, true);
347      builder.addInt8(1, 10);
348      builder.addInt32(2, 20);
349      builder.addOffset(3, stringOffset);
350      builder.addInt32(4, 40);
351      builder.addUint32(5, 0x9ABCDEF0);
352      builder.addUint8(6, 0x9A);
353      int offset = builder.endTable();
354      byteList = builder.finish(offset);
355    }
356    // read and verify
357    BufferContext buf = new BufferContext.fromBytes(byteList);
358    int objectOffset = buf.derefObject(0);
359    expect(
360        const BoolReader().vTableGet(buf, objectOffset, indexToField(0)), true);
361    expect(
362        const Int8Reader().vTableGet(buf, objectOffset, indexToField(1)), 10);
363    expect(
364        const Int32Reader().vTableGet(buf, objectOffset, indexToField(2)), 20);
365    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(3)),
366        '12345');
367    expect(
368        const Int32Reader().vTableGet(buf, objectOffset, indexToField(4)), 40);
369    expect(const Uint32Reader().vTableGet(buf, objectOffset, indexToField(5)),
370        0x9ABCDEF0);
371    expect(const Uint8Reader().vTableGet(buf, objectOffset, indexToField(6)),
372        0x9A);
373  }
374
375  void test_writeList_of_Uint32() {
376    List<int> values = <int>[10, 100, 12345, 0x9abcdef0];
377    // write
378    List<int> byteList;
379    {
380      Builder builder = new Builder(initialSize: 0);
381      int offset = builder.writeListUint32(values);
382      byteList = builder.finish(offset);
383    }
384    // read and verify
385    BufferContext buf = new BufferContext.fromBytes(byteList);
386    List<int> items = const Uint32ListReader().read(buf, 0);
387    expect(items, hasLength(4));
388    expect(items, orderedEquals(values));
389  }
390
391  void test_writeList_ofBool() {
392    void verifyListBooleans(int len, List<int> trueBits) {
393      // write
394      List<int> byteList;
395      {
396        Builder builder = new Builder(initialSize: 0);
397        List<bool> values = new List<bool>.filled(len, false);
398        for (int bit in trueBits) {
399          values[bit] = true;
400        }
401        int offset = builder.writeListBool(values);
402        byteList = builder.finish(offset);
403      }
404      // read and verify
405      BufferContext buf = new BufferContext.fromBytes(byteList);
406      List<bool> items = const BoolListReader().read(buf, 0);
407      expect(items, hasLength(len));
408      for (int i = 0; i < items.length; i++) {
409        expect(items[i], trueBits.contains(i), reason: 'bit $i of $len');
410      }
411    }
412
413    verifyListBooleans(0, <int>[]);
414    verifyListBooleans(1, <int>[]);
415    verifyListBooleans(1, <int>[0]);
416    verifyListBooleans(31, <int>[0, 1]);
417    verifyListBooleans(31, <int>[1, 2, 24, 25, 30]);
418    verifyListBooleans(31, <int>[0, 30]);
419    verifyListBooleans(32, <int>[1, 2, 24, 25, 31]);
420    verifyListBooleans(33, <int>[1, 2, 24, 25, 32]);
421    verifyListBooleans(33, <int>[1, 2, 24, 25, 31, 32]);
422    verifyListBooleans(63, <int>[]);
423    verifyListBooleans(63, <int>[0, 1, 2, 61, 62]);
424    verifyListBooleans(63, new List<int>.generate(63, (i) => i));
425    verifyListBooleans(64, <int>[]);
426    verifyListBooleans(64, <int>[0, 1, 2, 61, 62, 63]);
427    verifyListBooleans(64, <int>[1, 2, 62]);
428    verifyListBooleans(64, <int>[0, 1, 2, 63]);
429    verifyListBooleans(64, new List<int>.generate(64, (i) => i));
430    verifyListBooleans(100, <int>[0, 3, 30, 60, 90, 99]);
431  }
432
433  void test_writeList_ofInt32() {
434    List<int> byteList;
435    {
436      Builder builder = new Builder(initialSize: 0);
437      int offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]);
438      byteList = builder.finish(offset);
439    }
440    // read and verify
441    BufferContext buf = new BufferContext.fromBytes(byteList);
442    List<int> items = const ListReader<int>(const Int32Reader()).read(buf, 0);
443    expect(items, hasLength(5));
444    expect(items, orderedEquals(<int>[1, 2, 3, 4, 5]));
445  }
446
447  void test_writeList_ofFloat64() {
448    List<double> values = <double>[-1.234567, 3.4E+9, -5.6E-13, 7.8, 12.13];
449    // write
450    List<int> byteList;
451    {
452      Builder builder = new Builder(initialSize: 0);
453      int offset = builder.writeListFloat64(values);
454      byteList = builder.finish(offset);
455    }
456
457    // read and verify
458    BufferContext buf = new BufferContext.fromBytes(byteList);
459    List<double> items = const Float64ListReader().read(buf, 0);
460
461    expect(items, hasLength(values.length));
462    for (int i = 0; i < values.length; i++) {
463      expect(values[i], closeTo(items[i], .001));
464    }
465  }
466
467  void test_writeList_ofFloat32() {
468    List<double> values = [1.0, 2.23, -3.213, 7.8, 12.13];
469    // write
470    List<int> byteList;
471    {
472      Builder builder = new Builder(initialSize: 0);
473      int offset = builder.writeListFloat32(values);
474      byteList = builder.finish(offset);
475    }
476    // read and verify
477    BufferContext buf = new BufferContext.fromBytes(byteList);
478    List<double> items = const Float32ListReader().read(buf, 0);
479    expect(items, hasLength(5));
480    for (int i = 0; i < values.length; i++) {
481      expect(values[i], closeTo(items[i], .001));
482    }
483  }
484
485  void test_writeList_ofObjects() {
486    List<int> byteList;
487    {
488      Builder builder = new Builder(initialSize: 0);
489      // write the object #1
490      int object1;
491      {
492        builder.startTable();
493        builder.addInt32(0, 10);
494        builder.addInt32(1, 20);
495        object1 = builder.endTable();
496      }
497      // write the object #1
498      int object2;
499      {
500        builder.startTable();
501        builder.addInt32(0, 100);
502        builder.addInt32(1, 200);
503        object2 = builder.endTable();
504      }
505      // write the list
506      int offset = builder.writeList([object1, object2]);
507      byteList = builder.finish(offset);
508    }
509    // read and verify
510    BufferContext buf = new BufferContext.fromBytes(byteList);
511    List<TestPointImpl> items =
512        const ListReader<TestPointImpl>(const TestPointReader()).read(buf, 0);
513    expect(items, hasLength(2));
514    expect(items[0].x, 10);
515    expect(items[0].y, 20);
516    expect(items[1].x, 100);
517    expect(items[1].y, 200);
518  }
519
520  void test_writeList_ofStrings_asRoot() {
521    List<int> byteList;
522    {
523      Builder builder = new Builder(initialSize: 0);
524      int str1 = builder.writeString('12345');
525      int str2 = builder.writeString('ABC');
526      int offset = builder.writeList([str1, str2]);
527      byteList = builder.finish(offset);
528    }
529    // read and verify
530    BufferContext buf = new BufferContext.fromBytes(byteList);
531    List<String> items =
532        const ListReader<String>(const StringReader()).read(buf, 0);
533    expect(items, hasLength(2));
534    expect(items, contains('12345'));
535    expect(items, contains('ABC'));
536  }
537
538  void test_writeList_ofStrings_inObject() {
539    List<int> byteList;
540    {
541      Builder builder = new Builder(initialSize: 0);
542      int listOffset = builder.writeList(
543          [builder.writeString('12345'), builder.writeString('ABC')]);
544      builder.startTable();
545      builder.addOffset(0, listOffset);
546      int offset = builder.endTable();
547      byteList = builder.finish(offset);
548    }
549    // read and verify
550    BufferContext buf = new BufferContext.fromBytes(byteList);
551    StringListWrapperImpl reader = new StringListWrapperReader().read(buf, 0);
552    List<String> items = reader.items;
553    expect(items, hasLength(2));
554    expect(items, contains('12345'));
555    expect(items, contains('ABC'));
556  }
557
558  void test_writeList_ofUint32() {
559    List<int> byteList;
560    {
561      Builder builder = new Builder(initialSize: 0);
562      int offset = builder.writeListUint32(<int>[1, 2, 0x9ABCDEF0]);
563      byteList = builder.finish(offset);
564    }
565    // read and verify
566    BufferContext buf = new BufferContext.fromBytes(byteList);
567    List<int> items = const Uint32ListReader().read(buf, 0);
568    expect(items, hasLength(3));
569    expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0]));
570  }
571
572  void test_writeList_ofUint16() {
573    List<int> byteList;
574    {
575      Builder builder = new Builder(initialSize: 0);
576      int offset = builder.writeListUint16(<int>[1, 2, 60000]);
577      byteList = builder.finish(offset);
578    }
579    // read and verify
580    BufferContext buf = new BufferContext.fromBytes(byteList);
581    List<int> items = const Uint16ListReader().read(buf, 0);
582    expect(items, hasLength(3));
583    expect(items, orderedEquals(<int>[1, 2, 60000]));
584  }
585
586  void test_writeList_ofUint8() {
587    List<int> byteList;
588    {
589      Builder builder = new Builder(initialSize: 0);
590      int offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]);
591      byteList = builder.finish(offset);
592    }
593    // read and verify
594    BufferContext buf = new BufferContext.fromBytes(byteList);
595    List<int> items = const Uint8ListReader().read(buf, 0);
596    expect(items, hasLength(5));
597    expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A]));
598  }
599}
600
601class StringListWrapperImpl {
602  final BufferContext bp;
603  final int offset;
604
605  StringListWrapperImpl(this.bp, this.offset);
606
607  List<String> get items => const ListReader<String>(const StringReader())
608      .vTableGet(bp, offset, indexToField(0));
609}
610
611class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
612  const StringListWrapperReader();
613
614  @override
615  StringListWrapperImpl createObject(BufferContext object, int offset) {
616    return new StringListWrapperImpl(object, offset);
617  }
618}
619
620class TestPointImpl {
621  final BufferContext bp;
622  final int offset;
623
624  TestPointImpl(this.bp, this.offset);
625
626  int get x => const Int32Reader().vTableGet(bp, offset, indexToField(0), 0);
627
628  int get y => const Int32Reader().vTableGet(bp, offset, indexToField(1), 0);
629}
630
631class TestPointReader extends TableReader<TestPointImpl> {
632  const TestPointReader();
633
634  @override
635  TestPointImpl createObject(BufferContext object, int offset) {
636    return new TestPointImpl(object, offset);
637  }
638}
639
640@reflectiveTest
641class GeneratorTest {
642  void test_constantEnumValues() async {
643    expect(example.Color.values, same(example.Color.values));
644    expect(example.Race.values, same(example.Race.values));
645    expect(example.AnyTypeId.values, same(example.AnyTypeId.values));
646    expect(example.AnyUniqueAliasesTypeId.values, same(example.AnyUniqueAliasesTypeId.values));
647    expect(example.AnyAmbiguousAliasesTypeId.values, same(example.AnyAmbiguousAliasesTypeId.values));
648  }
649}
650