import 'dart:typed_data'; import 'package:flat_buffers/flex_buffers.dart' show Reference, Builder; import 'package:test/test.dart'; void main() { test('is null', () { expect(Reference.fromBuffer(b([0, 0, 1])).isNull, isTrue); }); test('bool value', () { expect(Reference.fromBuffer(b([1, 104, 1])).boolValue, isTrue); expect(Reference.fromBuffer(b([0, 104, 1])).boolValue, isFalse); }); test('int value', () { expect(Reference.fromBuffer(b([25, 4, 1])).intValue, 25); expect(Reference.fromBuffer(b([231, 4, 1])).intValue, -25); expect(Reference.fromBuffer(b([230, 8, 1])).intValue, 230); expect(Reference.fromBuffer(b([230, 0, 5, 2])).intValue, 230); expect(Reference.fromBuffer(b([1, 4, 5, 2])).intValue, 1025); expect(Reference.fromBuffer(b([255, 251, 5, 2])).intValue, -1025); expect(Reference.fromBuffer(b([1, 4, 9, 2])).intValue, 1025); expect( Reference.fromBuffer(b([255, 255, 255, 127, 6, 4])).intValue, 2147483647, ); expect(Reference.fromBuffer(b([0, 0, 0, 128, 6, 4])).intValue, -2147483648); expect( Reference.fromBuffer(b([255, 255, 255, 255, 0, 0, 0, 0, 7, 8])).intValue, 4294967295, ); expect( Reference.fromBuffer( b([255, 255, 255, 255, 255, 255, 255, 127, 7, 8]), ).intValue, 9223372036854775807, ); expect( Reference.fromBuffer(b([0, 0, 0, 0, 0, 0, 0, 128, 7, 8])).intValue, -9223372036854775808, ); // Dart does not really support UInt64 // expect(FlxValue.fromBuffer(b([255, 255, 255, 255, 255, 255, 255, 255, 11, 8])).intValue, 18446744073709551615); }); test('double value', () { expect(Reference.fromBuffer(b([0, 0, 128, 63, 14, 4])).doubleValue, 1.0); expect(Reference.fromBuffer(b([0, 0, 144, 64, 14, 4])).doubleValue, 4.5); expect( Reference.fromBuffer(b([205, 204, 204, 61, 14, 4])).doubleValue, closeTo(.1, .001), ); expect( Reference.fromBuffer( b([154, 153, 153, 153, 153, 153, 185, 63, 15, 8]), ).doubleValue, .1, ); }); test('num value', () { expect(Reference.fromBuffer(b([0, 0, 144, 64, 14, 4])).numValue, 4.5); expect( Reference.fromBuffer(b([205, 204, 204, 61, 14, 4])).numValue, closeTo(.1, .001), ); expect( Reference.fromBuffer( b([154, 153, 153, 153, 153, 153, 185, 63, 15, 8]), ).numValue, .1, ); expect(Reference.fromBuffer(b([255, 251, 5, 2])).numValue, -1025); }); test('string value', () { expect( Reference.fromBuffer( b([5, 77, 97, 120, 105, 109, 0, 6, 20, 1]), ).stringValue, 'Maxim', ); expect( Reference.fromBuffer( b([10, 104, 101, 108, 108, 111, 32, 240, 159, 152, 177, 0, 11, 20, 1]), ).stringValue, 'hello 😱', ); }); test('blob value', () { expect(Reference.fromBuffer(b([3, 1, 2, 3, 3, 100, 1])).blobValue, [ 1, 2, 3, ]); }); test('bool vector', () { var flx = Reference.fromBuffer(b([3, 1, 0, 1, 3, 144, 1])); expect(flx[0].boolValue, true); expect(flx[1].boolValue, false); expect(flx[2].boolValue, true); }); test('number vector', () { testNumbers([3, 1, 2, 3, 3, 44, 1], [1, 2, 3]); testNumbers([3, 255, 2, 3, 3, 44, 1], [-1, 2, 3]); testNumbers([3, 0, 1, 0, 43, 2, 3, 0, 6, 45, 1], [1, 555, 3]); testNumbers( [3, 0, 0, 0, 1, 0, 0, 0, 204, 216, 0, 0, 3, 0, 0, 0, 12, 46, 1], [1, 55500, 3], ); testNumbers( [ 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 172, 128, 94, 239, 12, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 24, 47, 1, ], [1, 55555555500, 3], ); testNumbers( [3, 0, 0, 0, 0, 0, 192, 63, 0, 0, 32, 64, 0, 0, 96, 64, 12, 54, 1], [1.5, 2.5, 3.5], ); testNumbers( [ 3, 0, 0, 0, 0, 0, 0, 0, 154, 153, 153, 153, 153, 153, 241, 63, 154, 153, 153, 153, 153, 153, 1, 64, 102, 102, 102, 102, 102, 102, 10, 64, 24, 55, 1, ], [1.1, 2.2, 3.3], ); }); test('number vector, fixed type', () { testNumbers([1, 2, 2, 64, 1], [1, 2]); testNumbers([255, 255, 0, 1, 4, 65, 1], [-1, 256]); testNumbers([211, 255, 255, 255, 0, 232, 3, 0, 8, 66, 1], [-45, 256000]); testNumbers( [ 211, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 16, 67, 1, ], [-45, 9223372036854775807], ); testNumbers([1, 2, 2, 68, 1], [1, 2]); testNumbers([1, 0, 0, 1, 4, 69, 1], [1, 256]); testNumbers([45, 0, 0, 0, 0, 232, 3, 0, 8, 70, 1], [45, 256000]); testNumbers([205, 204, 140, 63, 0, 0, 0, 192, 8, 74, 1], [1.1, -2]); testNumbers( [ 154, 153, 153, 153, 153, 153, 241, 63, 0, 0, 0, 0, 0, 0, 112, 192, 16, 75, 1, ], [1.1, -256], ); testNumbers( [211, 255, 255, 255, 0, 232, 3, 0, 4, 0, 0, 0, 12, 78, 1], [-45, 256000, 4], ); testNumbers( [ 211, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 4, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 32, 91, 1, ], [-45, 9223372036854775807, 4, 9], ); testNumbers( [ 45, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 127, 4, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 32, 95, 1, ], [45, 9223372036854775807, 4, 9], ); testNumbers( [ 154, 153, 153, 153, 153, 153, 241, 63, 0, 0, 0, 0, 0, 0, 112, 64, 0, 0, 0, 0, 0, 0, 16, 64, 24, 87, 1, ], [1.1, 256, 4], ); testNumbers( [ 154, 153, 153, 153, 153, 153, 241, 63, 0, 0, 0, 0, 0, 0, 112, 64, 0, 0, 0, 0, 0, 0, 16, 64, 0, 0, 0, 0, 0, 0, 34, 64, 32, 99, 1, ], [1.1, 256, 4, 9], ); }); test('string vector', () { testStrings( [ 3, 102, 111, 111, 0, 3, 98, 97, 114, 0, 3, 98, 97, 122, 0, 3, 15, 11, 7, 3, 60, 1, ], ['foo', 'bar', 'baz'], ); testStrings( [ 3, 102, 111, 111, 0, 3, 98, 97, 114, 0, 3, 98, 97, 122, 0, 6, 15, 11, 7, 18, 14, 10, 6, 60, 1, ], ['foo', 'bar', 'baz', 'foo', 'bar', 'baz'], ); }); test('mixed vector', () { var flx = Reference.fromBuffer( b([ 3, 102, 111, 111, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 251, 255, 255, 255, 255, 255, 255, 255, 205, 204, 204, 204, 204, 204, 244, 63, 1, 0, 0, 0, 0, 0, 0, 0, 20, 4, 4, 15, 104, 45, 43, 1, ]), ); expect(flx.length, 5); expect(flx[0].stringValue, 'foo'); expect(flx[1].numValue, 1); expect(flx[2].numValue, -5); expect(flx[3].numValue, 1.3); expect(flx[4].boolValue, true); }); test('single value map', () { var flx = Reference.fromBuffer(b([97, 0, 1, 3, 1, 1, 1, 12, 4, 2, 36, 1])); expect(flx.length, 1); expect(flx['a'].numValue, 12); }); test('two value map', () { var flx = Reference.fromBuffer( b([0, 97, 0, 2, 4, 4, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1]), ); expect(flx.length, 2); expect(flx['a'].numValue, 12); expect(flx[''].numValue, 45); }); test('complex map', () { var flx = complexMap(); expect(flx.length, 5); expect(flx['age'].numValue, 35); expect(flx['weight'].numValue, 72.5); expect(flx['name'].stringValue, 'Maxim'); expect(flx['flags'].length, 4); expect(flx['flags'][0].boolValue, true); expect(flx['flags'][1].boolValue, false); expect(flx['flags'][2].boolValue, true); expect(flx['flags'][3].boolValue, true); expect(flx['address'].length, 3); expect(flx['address']['city'].stringValue, 'Bla'); expect(flx['address']['zip'].stringValue, '12345'); expect(flx['address']['countryCode'].stringValue, 'XX'); expect( () => flx['address']['country'].stringValue, throwsA( predicate( (dynamic e) => e is ArgumentError && e.message == 'Key: [country] is not applicable on: //address of: ValueType.Map', ), ), ); expect( () => flx['address']['countryCode'][0], throwsA( predicate( (dynamic e) => e is ArgumentError && e.message == 'Key: [0] is not applicable on: //address/countryCode of: ValueType.String', ), ), ); expect( () => flx[1], throwsA( predicate( (dynamic e) => e is ArgumentError && e.message == 'Key: [1] is not applicable on: / of: ValueType.Map', ), ), ); expect( () => flx['flags'][4], throwsA( predicate( (dynamic e) => e is ArgumentError && e.message == 'Key: [4] is not applicable on: //flags of: ValueType.VectorBool length: 4', ), ), ); expect( () => flx['flags'][-1], throwsA( predicate( (dynamic e) => e is ArgumentError && e.message == 'Key: [-1] is not applicable on: //flags of: ValueType.VectorBool length: 4', ), ), ); }); test('complex map to json', () { var flx = complexMap(); expect( flx.json, '{"address":{"city":"Bla","countryCode":"XX","zip":"12345"},"age":35,"flags":[true,false,true,true],"name":"Maxim","weight":72.5}', ); }); test('complex map iterators', () { var flx = complexMap(); expect(flx.mapKeyIterable.map((e) => e).toList(), [ 'address', 'age', 'flags', 'name', 'weight', ]); expect(flx.mapValueIterable.map((e) => e.json).toList(), [ flx['address'].json, flx['age'].json, flx['flags'].json, flx['name'].json, flx['weight'].json, ]); expect(flx['flags'].vectorIterable.map((e) => e.boolValue).toList(), [ true, false, true, true, ]); }); test('bug where offest were stored as int instead of uint', () { const data = [ 99, 104, 97, 110, 110, 101, 108, 115, 95, 105, 110, 0, 100, 105, 108, 97, 116, 105, 111, 110, 95, 104, 101, 105, 103, 104, 116, 95, 102, 97, 99, 116, 111, 114, 0, 100, 105, 108, 97, 116, 105, 111, 110, 95, 119, 105, 100, 116, 104, 95, 102, 97, 99, 116, 111, 114, 0, 102, 117, 115, 101, 100, 95, 97, 99, 116, 105, 118, 97, 116, 105, 111, 110, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0, 112, 97, 100, 95, 118, 97, 108, 117, 101, 115, 0, 112, 97, 100, 100, 105, 110, 103, 0, 115, 116, 114, 105, 100, 101, 95, 104, 101, 105, 103, 104, 116, 0, 115, 116, 114, 105, 100, 101, 95, 119, 105, 100, 116, 104, 0, 8, 130, 119, 97, 76, 51, 41, 34, 21, 8, 1, 8, 64, 1, 1, 1, 1, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 16, 36, 1, ]; var flx = Reference.fromBuffer(b(data)); expect( flx.json, '{"channels_in":64,"dilation_height_factor":1,"dilation_width_factor":1,"fused_activation_function":1,"pad_values":1,"padding":0,"stride_height":1,"stride_width":1}', ); const object = { "channels_in": 64, "dilation_height_factor": 1, "dilation_width_factor": 1, "fused_activation_function": 1, "pad_values": 1, "padding": 0, "stride_height": 1, "stride_width": 1, }; var data1 = Builder.buildFromObject(object).asUint8List(); expect(data1.length, data.length); var flx1 = Reference.fromBuffer(b(data1)); expect( flx1.json, '{"channels_in":64,"dilation_height_factor":1,"dilation_width_factor":1,"fused_activation_function":1,"pad_values":1,"padding":0,"stride_height":1,"stride_width":1}', ); }); } ByteBuffer b(List values) { var data = Uint8List.fromList(values); return data.buffer; } void testNumbers(List buffer, List numbers) { var flx = Reference.fromBuffer(b(buffer)); expect(flx.length, numbers.length); for (var i = 0; i < flx.length; i++) { expect(flx[i].numValue, closeTo(numbers[i], 0.001)); } } void testStrings(List buffer, List numbers) { var flx = Reference.fromBuffer(b(buffer)); expect(flx.length, numbers.length); for (var i = 0; i < flx.length; i++) { expect(flx[i].stringValue, numbers[i]); } } Reference complexMap() { // { // "age": 35, // "flags": [True, False, True, True], // "weight": 72.5, // "name": "Maxim", // "address": { // "city": "Bla", // "zip": "12345", // "countryCode": "XX", // } // } return Reference.fromBuffer( b([ 97, 100, 100, 114, 101, 115, 115, 0, 99, 105, 116, 121, 0, 3, 66, 108, 97, 0, 99, 111, 117, 110, 116, 114, 121, 67, 111, 100, 101, 0, 2, 88, 88, 0, 122, 105, 112, 0, 5, 49, 50, 51, 52, 53, 0, 3, 38, 29, 14, 3, 1, 3, 38, 22, 15, 20, 20, 20, 97, 103, 101, 0, 102, 108, 97, 103, 115, 0, 4, 1, 0, 1, 1, 110, 97, 109, 101, 0, 5, 77, 97, 120, 105, 109, 0, 119, 101, 105, 103, 104, 116, 0, 5, 93, 36, 33, 23, 12, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 0, 51, 0, 0, 0, 45, 0, 0, 0, 0, 0, 145, 66, 36, 4, 144, 20, 14, 25, 38, 1, ]), ); }