Ejemplo n.º 1
0
        public void DefaultCtorKind_PublicObsolete_Table()
        {
            string schema = $@"
            namespace Foo; 
            table Table ({MetadataKeys.DefaultConstructorKind}:""{DefaultConstructorKind.PublicObsolete}"") {{ Int:int; }}";

            var  asm           = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());
            Type baseTableType = asm.GetTypes().Single(x => x.Name == "Table");

            var constructor = baseTableType.GetConstructor(new Type[0]);

            Assert.IsNotNull(constructor);
            Assert.IsTrue(constructor.IsPublic);
            Assert.IsNotNull(constructor.GetCustomAttribute <ObsoleteAttribute>());
        }
Ejemplo n.º 2
0
        public void File_Identifier_With_Manually_Specified_Id()
        {
            string schema = $@"
            namespace FileIdTests.A;
            table Table ({MetadataKeys.FileIdentifier}:""AbCd"") {{ foo:int; }}
            file_identifier ""AbCd"";
            root_type Table;
            ";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());

            Assert.AreEqual(
                "AbCd",
                asm.GetType("FileIdTests.A.Table").GetCustomAttribute <FlatBufferTableAttribute>().FileIdentifier);
        }
Ejemplo n.º 3
0
        public void TestOptionalScalars()
        {
            string schema = @"
            namespace OptionalScalarTests;
            
            enum TestEnum : ubyte
            {
                A = 1,
                B = 2
            }

            table Table (PrecompiledSerializer:greedy) {
                Bool : bool = null;
                Byte : ubyte = null;
                SByte : byte = null;
                UShort : uint16 = null;
                Short : int16 = null;
                UInt : uint32 = null;
                Int : int32 = null;
                ULong : uint64 = null;
                Long : int64 = null;
                Double : double = null;
                Float : float32 = null;
                Enum : TestEnum = null;
            }";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema);

            Type tableType = asm.GetTypes().Single(x => x.FullName == "OptionalScalarTests.Table");

            Assert.AreEqual(typeof(bool?), tableType.GetProperty("Bool").PropertyType);
            Assert.AreEqual(typeof(byte?), tableType.GetProperty("Byte").PropertyType);
            Assert.AreEqual(typeof(sbyte?), tableType.GetProperty("SByte").PropertyType);
            Assert.AreEqual(typeof(ushort?), tableType.GetProperty("UShort").PropertyType);
            Assert.AreEqual(typeof(short?), tableType.GetProperty("Short").PropertyType);
            Assert.AreEqual(typeof(uint?), tableType.GetProperty("UInt").PropertyType);
            Assert.AreEqual(typeof(int?), tableType.GetProperty("Int").PropertyType);
            Assert.AreEqual(typeof(ulong?), tableType.GetProperty("ULong").PropertyType);
            Assert.AreEqual(typeof(long?), tableType.GetProperty("Long").PropertyType);
            Assert.AreEqual(typeof(double?), tableType.GetProperty("Double").PropertyType);
            Assert.AreEqual(typeof(float?), tableType.GetProperty("Float").PropertyType);

            var underlyingType = Nullable.GetUnderlyingType(tableType.GetProperty("Enum").PropertyType);

            Assert.IsTrue(underlyingType != null);
            Assert.IsTrue(underlyingType.IsEnum);
            Assert.AreEqual(typeof(byte), Enum.GetUnderlyingType(underlyingType));
        }
Ejemplo n.º 4
0
    public void ValueStruct_Nested()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace ValueStructTests;
            table Table ({MetadataKeys.SerializerKind}:""GreedyMutable"") {{ StructVector:[Struct]; Item : Struct; }}
            struct Inner ({MetadataKeys.ValueStruct}) {{ B : ulong; }}
            struct Struct ({MetadataKeys.ValueStruct}) {{ A:int; B : Inner; C : ubyte; }} 
        ";

        Assembly asm             = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());
        Type     tableType       = asm.GetType("ValueStructTests.Table");
        Type     structType      = asm.GetType("ValueStructTests.Struct");
        Type     innerStructType = asm.GetType("ValueStructTests.Inner");

        Assert.NotNull(tableType);
        Assert.NotNull(structType);

        Assert.False(tableType.IsValueType);
        Assert.True(structType.IsValueType);
        Assert.True(innerStructType.IsValueType);

        Assert.True(structType.IsExplicitLayout);
        Assert.True(innerStructType.IsExplicitLayout);

        PropertyInfo structVectorProperty = tableType.GetProperty("StructVector");

        Assert.Equal(typeof(IList <>).MakeGenericType(structType), structVectorProperty.PropertyType);

        PropertyInfo structProperty = tableType.GetProperty("Item");

        Assert.Equal(typeof(Nullable <>).MakeGenericType(structType), structProperty.PropertyType);

        FieldInfo structA = structType.GetField("A");

        Assert.Equal(typeof(int), structA.FieldType);
        Assert.Equal(0, structA.GetCustomAttribute <FieldOffsetAttribute>().Value);

        FieldInfo structB = structType.GetField("B");

        Assert.Equal(innerStructType, structB.FieldType);
        Assert.Equal(8, structB.GetCustomAttribute <FieldOffsetAttribute>().Value);

        FieldInfo structC = structType.GetField("C");

        Assert.Equal(typeof(byte), structC.FieldType);
        Assert.Equal(16, structC.GetCustomAttribute <FieldOffsetAttribute>().Value);
    }
Ejemplo n.º 5
0
    public void BasicEnumTest_HexNumber()
    {
        string   fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : ubyte {{ Red = 0x0, Blue = 0X01, Green = 2, Yellow = 0X10 }}";
        Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(fbs, new());

        Type t = asm.GetTypes().Single(x => x.FullName == "Foo.Bar.MyEnum");

        Assert.True(t.IsEnum);
        Assert.Equal(typeof(byte), Enum.GetUnderlyingType(t));

        Array values = Enum.GetValues(t);

        Assert.Equal((byte)0, (byte)values.GetValue(0));
        Assert.Equal((byte)1, (byte)values.GetValue(1));
        Assert.Equal((byte)2, (byte)values.GetValue(2));
        Assert.Equal((byte)16, (byte)values.GetValue(3));
    }
Ejemplo n.º 6
0
    public void StructVector_UnsafeVectorOnReferenceType()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace StructVectorTests;

            struct Foo {{
              V:[int:7] ({MetadataKeys.UnsafeValueStructVector});
            }}";

        var ex = Assert.Throws <InvalidFbsFileException>(
            () => FlatSharpCompiler.CompileAndLoadAssembly(
                schema,
                new()));

        Assert.Contains($"The attribute '{MetadataKeys.UnsafeValueStructVector}' is never valid on StructField elements.", ex.Message);
    }
Ejemplo n.º 7
0
    public void SortedVector_IndexedVector_InvalidKey()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace ns;
            table Monster ({MetadataKeys.SerializerKind}) {{
              Vector:[VectorMember] ({MetadataKeys.VectorKind}:""IIndexedVector"");
            }}
            table VectorMember {{
                Data:DoesNotExist ({MetadataKeys.Key});
            }}";

        var ex = Assert.Throws<InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(schema, new()));
        Assert.Contains(
            "error: 'key' field must be string or scalar type",
            ex.Message);
    }
Ejemplo n.º 8
0
    public void SortedVector_IndexedVector_NoKey()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace ns;
            table Monster ({MetadataKeys.SerializerKind}) {{
              Vector:[VectorMember] ({MetadataKeys.VectorKind}:""IIndexedVector"");
            }}
            table VectorMember {{
                Data:string;
            }}";

        var ex = Assert.Throws<InvalidFlatBufferDefinitionException>(() => FlatSharpCompiler.CompileAndLoadAssembly(schema, new()));
        Assert.Contains(
            "Indexed vector values must have a property with the key attribute defined. Table = 'ns.VectorMember'",
            ex.Message);
    }
Ejemplo n.º 9
0
        public void Multiple_File_Identifiers_Different_Namespaces()
        {
            string schema = $@"
            namespace FileIdTests.A;
            table Table {{ foo:int; }}
            file_identifier ""doof"";

            namespace FileIdTests.B;
            table TableB {{ foo:int; }}
            root_type TableB;
            file_identifier ""food"";
            ";

            var ex = Assert.ThrowsException <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(schema, new()));

            Assert.IsTrue(ex.Errors[0].StartsWith("Message='Duplicate file identifiers: 'doof' and 'food'.', Scope=$"));
        }
Ejemplo n.º 10
0
    public void BasicEnumTest_NegativeNumbers()
    {
        string   fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : byte {{ Red = -0x02, Blue = -1, Green = 0, Yellow = 0X1, Purple = 0x02 }}";
        Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(fbs, new());

        Type t = asm.GetTypes().Single(x => x.FullName == "Foo.Bar.MyEnum");

        Assert.True(t.IsEnum);
        Assert.Equal(typeof(sbyte), Enum.GetUnderlyingType(t));

        var values = Enum.GetValues(t).OfType <object>().Select(x => new { Name = x.ToString(), Value = (sbyte)x });

        Assert.Equal((sbyte)-2, values.Single(x => x.Name == "Red").Value);
        Assert.Equal((sbyte)-1, values.Single(x => x.Name == "Blue").Value);
        Assert.Equal((sbyte)0, values.Single(x => x.Name == "Green").Value);
        Assert.Equal((sbyte)1, values.Single(x => x.Name == "Yellow").Value);
        Assert.Equal((sbyte)2, values.Single(x => x.Name == "Purple").Value);
    }
Ejemplo n.º 11
0
    public void SortedVector_IndexedVector_MultipleKeys()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace ns;
            table Monster ({MetadataKeys.SerializerKind}) {{
              Vector:[VectorMember] ({MetadataKeys.VectorKind}:""IIndexedVector"");
            }}
            table VectorMember {{
                Data:string ({MetadataKeys.Key});
                Data2:string ({MetadataKeys.Key});
            }}";

        var ex = Assert.Throws<InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(schema, new()));
        Assert.Contains(
            "error: only one field may be set as 'key'",
            ex.Message);
    }
Ejemplo n.º 12
0
        public void SharedStringMetadataTypeTest()
        {
            string schema = $@"
            namespace SharedStringTests;
            table Table {{
                foo:string ({MetadataKeys.SharedString});
                bar:[string] ({MetadataKeys.VectorKind}:array, {MetadataKeys.SharedString});
                baz:[string] ({MetadataKeys.VectorKind}:ilist, {MetadataKeys.SharedStringLegacy});
            }}";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());

            Type tableType = asm.GetTypes().Single(x => x.FullName == "SharedStringTests.Table");
            var  property  = tableType.GetProperty("foo");

            Assert.AreEqual(typeof(SharedString), property.PropertyType);
            Assert.AreEqual(typeof(SharedString[]), tableType.GetProperty("bar").PropertyType);
            Assert.AreEqual(typeof(IList <SharedString>), tableType.GetProperty("baz").PropertyType);
        }
        public void SharedStringMetadataTypeTest()
        {
            string schema = @"
            namespace SharedStringTests;
            table Table {
                foo:string (sharedstring);
                bar:[string] (VectorType:array, sharedstring);
                baz:[string] (VectorType:ilist, sharedstring);
            }";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema);

            Type tableType = asm.GetTypes().Single(x => x.FullName == "SharedStringTests.Table");
            var  property  = tableType.GetProperty("foo");

            Assert.AreEqual(typeof(SharedString), property.PropertyType);
            Assert.AreEqual(typeof(SharedString[]), tableType.GetProperty("bar").PropertyType);
            Assert.AreEqual(typeof(IList <SharedString>), tableType.GetProperty("baz").PropertyType);
        }
Ejemplo n.º 14
0
    public void Table_Root_Type()
    {
        string schema = $@"
            namespace FileIdTests.A;
            table Table {{ foo:int; }}
            struct Struct {{ foo:int; }}

            file_identifier ""abcd"";
            root_type Table;
            ";

        var  asm       = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());
        Type tabletype = asm.GetType("FileIdTests.A.Table");

        FlatBufferTableAttribute table = tabletype.GetCustomAttribute <FlatBufferTableAttribute>();

        Assert.NotNull(table);
        Assert.Equal("abcd", table.FileIdentifier);
    }
Ejemplo n.º 15
0
    public void Required_Attribute_OnSerialize()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace RequiredTests;
            table Table ({MetadataKeys.SerializerKind}:""Lazy"") {{ Struct:Struct ({MetadataKeys.Required}); String:string ({MetadataKeys.Required}); }}
            struct Struct {{ foo:int; }} 
        ";

        Assembly asm       = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());
        Type     tableType = asm.GetType("RequiredTests.Table");

        byte[] buffer = new byte[1024];

        ISerializer serializer = (ISerializer)tableType.GetProperty("Serializer", BindingFlags.Public | BindingFlags.Static).GetValue(null);

        Assert.Throws <InvalidOperationException>(
            () => serializer.Write(buffer, Activator.CreateInstance(tableType)));
    }
Ejemplo n.º 16
0
    public void ValueStruct_BasicDefinition()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace ValueStructTests;
            table Table ({MetadataKeys.SerializerKind}:""GreedyMutable"") {{ Struct:Struct; }}
            struct Struct ({MetadataKeys.ValueStruct}) {{ foo:int; }} 
        ";

        Assembly asm        = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());
        Type     tableType  = asm.GetType("ValueStructTests.Table");
        Type     structType = asm.GetType("ValueStructTests.Struct");

        Assert.NotNull(tableType);
        Assert.NotNull(structType);

        Assert.False(tableType.IsValueType);
        Assert.True(structType.IsValueType);
        Assert.True(structType.IsExplicitLayout);
    }
Ejemplo n.º 17
0
    public void StructVector_InvalidType()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace StructVectorTests;

            table Table ({MetadataKeys.SerializerKind}) {{
                foo:Foo;
            }}
            struct Foo {{
              V:[Bar:7] ({MetadataKeys.NonVirtualProperty});
            }}";

        var ex = Assert.Throws <InvalidFbsFileException>(
            () => FlatSharpCompiler.CompileAndLoadAssembly(
                schema,
                new()));

        Assert.Contains("error: structs may contain only scalar or struct fields", ex.Message);
    }
Ejemplo n.º 18
0
    public void NullableAnnotations()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace FieldNameNormalizationTests;

            table Table {{
                item_one : int32;
                item_two : int32;
                item__three : int32;
                lowerPascalCase : int32;
                item_f : int32;
            }}

            struct Struct {{
                item_one : int32;
                item_two : int32;
                ____item__three__ : int32;
                lowerPascalCase : int32;
                item_f : int32;
            }}";

        Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(
            schema,
            new CompilerOptions
        {
            NormalizeFieldNames = true,
        });

        foreach (string typeName in new[] { "FieldNameNormalizationTests.Table", "FieldNameNormalizationTests.Struct" })
        {
            Type type = asm.GetType(typeName);

            Assert.NotNull(type);
            Assert.NotNull(type.GetProperty("ItemOne"));
            Assert.NotNull(type.GetProperty("ItemTwo"));
            Assert.NotNull(type.GetProperty("ItemThree"));
            Assert.NotNull(type.GetProperty("ItemF"));
            Assert.NotNull(type.GetProperty("LowerPascalCase"));
        }
    }
Ejemplo n.º 19
0
        public void TestUnionWithAliasedStringGeneration()
        {
            const string Schema = @"
namespace Foobar;

table A { Value:int32; }
table B { Value:int32; }
struct C { Value:int32; }

union TestUnion { First:A, B, Foobar.C, StringAlias:string }

table D (PrecompiledSerializer) { Union:TestUnion; }

";
            // Simply ensure that the union is generated as FlatBufferUnion and no custom class is created.
            Assembly asm       = FlatSharpCompiler.CompileAndLoadAssembly(Schema);
            Type     unionType = asm.GetType("Foobar.TestUnion");
            Type     dType     = asm.GetType("Foobar.D");

            Assert.AreEqual(unionType, dType.GetProperty("Union").PropertyType);
        }
Ejemplo n.º 20
0
        private (PropertyInfo, Type, FlatBufferItemAttribute) CompileAndGetProperty(string typeMetadata, string fieldType, string fieldMetadata)
        {
            if (!string.IsNullOrEmpty(typeMetadata))
            {
                typeMetadata = $"({typeMetadata})";
            }

            if (!string.IsNullOrEmpty(fieldMetadata))
            {
                fieldMetadata = $"({fieldMetadata})";
            }

            string schema = $@"table MyTable {typeMetadata} {{ Field:{fieldType} {fieldMetadata}; }} table OtherTable {{ String:string (key); }}";

            Assembly asm       = FlatSharpCompiler.CompileAndLoadAssembly(schema);
            var      type      = asm.GetType("MyTable");
            var      propInfo  = type.GetProperty("Field");
            var      attribute = propInfo.GetCustomAttribute <FlatBufferItemAttribute>();

            return(propInfo, type, attribute);
        }
Ejemplo n.º 21
0
        public void TestUnionWithAliasedStringGeneration()
        {
            string schema = $@"
namespace Foobar;

table A {{ Value:int32; }}
table B {{ Value:int32; }}
struct C {{ Value:int32; }}

union TestUnion {{ First:A, B, Foobar.C, StringAlias:string }}

table D ({MetadataKeys.SerializerKind}) {{ Union:TestUnion; }}

";
            // Simply ensure that the union is generated as FlatBufferUnion and no custom class is created.
            Assembly asm       = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());
            Type     unionType = asm.GetType("Foobar.TestUnion");
            Type     dType     = asm.GetType("Foobar.D");

            Assert.AreEqual(unionType, dType.GetProperty("Union").PropertyType);
        }
Ejemplo n.º 22
0
    public void DuplicateValues()
    {
        string   fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : ubyte {{ Red = 0x0, Blue = 0X10, Yellow = 16 }}";
        Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(fbs, new());

        Type enumType = asm.GetType("Foo.Bar.MyEnum");

        Assert.NotNull(enumType);

        Array values = Enum.GetValues(enumType);

        string[] names = Enum.GetNames(enumType);

        Assert.Equal("Red", names[0]);
        Assert.Equal((byte)0, (byte)values.GetValue(0));

        Assert.Equal("Yellow", names[1]);
        Assert.Equal((byte)16, (byte)values.GetValue(1));

        Assert.Equal(2, names.Length);
        Assert.Equal(2, values.GetLength(0));
    }
Ejemplo n.º 23
0
        private void RunSingleTest <T>(string fbsType, bool deprecated = false, bool hasDefaultValue = false, T expectedDefaultValue = default)
        {
            try
            {
                string   schema = $@"namespace TableMemberTests; table Table {{ member:{fbsType}; member2:int; }}";
                Assembly asm    = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());

                Type         tableType = asm.GetType("TableMemberTests.Table");
                PropertyInfo property  = tableType.GetProperty("member");

                Assert.AreEqual(typeof(T), property.PropertyType);
                var attribute = property.GetCustomAttribute <FlatBufferItemAttribute>();

                Assert.AreEqual(0, attribute.Index);
                Assert.AreEqual(deprecated, attribute.Deprecated);

                Assert.AreEqual(hasDefaultValue, attribute.DefaultValue != null);
                if (hasDefaultValue)
                {
                    Assert.IsInstanceOfType(attribute.DefaultValue, typeof(T));

                    T actualDefault = (T)attribute.DefaultValue;
                    Assert.AreEqual(0, Comparer <T> .Default.Compare(expectedDefaultValue, actualDefault));
                }

                byte[] data     = new byte[100];
                var    compiled = CompilerTestHelpers.CompilerTestSerializer.Compile(tableType);

                compiled.Write(data, Activator.CreateInstance(tableType));
                compiled.Parse(data);
            }
            catch (TargetInvocationException ex)
            {
                throw ex.InnerException;
            }
        }
Ejemplo n.º 24
0
        public void TestCrossNamespaceUnion()
        {
            string schema = @"
namespace A;

union Either { A1, A2 }

table A1
{
	Foobar:string;
	Test:int64;
	Memory:[ubyte];
	List:[int];
}

table A2
{
   Name:string;
   Age:int;
}

table A3
{
    Union:Either;
    Union2:A.Either;
}

namespace B;

table T3
{
	Union:A.Either;
}";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());
        }
Ejemplo n.º 25
0
    public void MonsterTest(FlatBufferDeserializationOption option, string arrayVectorKind, Type arrayVectorType)
    {
        // https://github.com/google/flatbuffers/blob/master/samples/monster.fbs
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace MyGame;

            enum Color:byte {{ Red = 0, Green, Blue = 2 }}
            union Equipment {{ Weapon, Vec3, Vec4, Monster }}

            struct Vec3 {{
              x:float;
              y:float;
              z:float;
            }}

            struct Vec4 {{
              x:float;
              y:float;
              z:float;
              t:float;
            }}

            table Monster ({MetadataKeys.SerializerKind}:""{option}"") {{
              pos:Vec3;
              mana:short = 150;
              hp:short = 100;
              name:string;
              friendly:bool = false ({MetadataKeys.Deprecated});
              inventory:[ubyte];
              color:Color = Blue;
              weapons:[Weapon];
              equipped:Equipment;
              path:[Vec3];
              vec4:Vec4;
              FakeVector1:[string] ({MetadataKeys.VectorKind}:""IReadOnlyList"");
              FakeVector2:[string] ({MetadataKeys.VectorKind}:""{arrayVectorKind}"");
              FakeVector3:[string] ({MetadataKeys.VectorKind}:""IList"");
              FakeVector4:[string];
              FakeMemoryVector:[ubyte] ({MetadataKeys.VectorKind}:""Memory"");
              FakeMemoryVectorReadOnly:[ubyte] ({MetadataKeys.VectorKind}:""ReadOnlyMemory"");
            }}

            table Weapon {{
              name:string;
              damage:short;
            }}";

        Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());

        Type    weaponType  = asm.GetType("MyGame.Weapon");
        Type    monsterType = asm.GetTypes().Single(x => x.FullName == "MyGame.Monster");
        object  monster     = Activator.CreateInstance(monsterType);
        dynamic dMonster    = monster;

        Type    vec4Type = asm.GetTypes().Single(x => x.FullName == "MyGame.Vec4");
        Type    vec3Type = asm.GetTypes().Single(x => x.FullName == "MyGame.Vec3");
        object  vec      = Activator.CreateInstance(vec3Type);
        dynamic dVec     = vec;

        Assert.Equal((short)150, dMonster.mana);
        Assert.Equal((short)100, dMonster.hp);
        Assert.False(dMonster.friendly);
        Assert.Equal("Blue", dMonster.color.ToString());
        Assert.Null(dMonster.pos);

        Assert.Equal(typeof(IList <byte>), monsterType.GetProperty("inventory").PropertyType);
        Assert.Equal(typeof(IList <>).MakeGenericType(vec3Type), monsterType.GetProperty("path").PropertyType);
        Assert.Equal(typeof(IList <>).MakeGenericType(weaponType), monsterType.GetProperty("weapons").PropertyType);
        Assert.True(typeof(IFlatBufferUnion <, , ,>).MakeGenericType(weaponType, vec3Type, vec4Type, monsterType).IsAssignableFrom(Nullable.GetUnderlyingType(monsterType.GetProperty("equipped").PropertyType)));
        Assert.Equal(typeof(string), monsterType.GetProperty("name").PropertyType);
        Assert.True(monsterType.GetProperty("friendly").GetCustomAttribute <FlatBufferItemAttribute>().Deprecated);

        Assert.Equal(arrayVectorType, monsterType.GetProperty("FakeVector2").PropertyType);

        byte[]      data = new byte[1024];
        ISerializer monsterSerializer = CompilerTestHelpers.CompilerTestSerializer.Compile(monster);

        monsterSerializer.Write(data, monster);
        var parsedMonster = monsterSerializer.Parse(data);

        Assert.NotEqual(parsedMonster.GetType(), monster.GetType());

        var copiedMonster = Activator.CreateInstance(monsterType, new[] { parsedMonster });

        Assert.Equal(copiedMonster.GetType(), monster.GetType());
    }
Ejemplo n.º 26
0
        public void BasicStructTest()
        {
            string schema = @"
            namespace StructTests;
            table Table {
                foo:Foo;
                defaultInt:int32 = 3;
            }

            struct Foo {
              id:ulong;
              count:short;
              prefix:byte;
              length:uint;
            }

            struct Bar {
              parent:Foo;
              time:int;
              ratio:float;
              size:ushort;
            }";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());

            Type   tableType = asm.GetTypes().Single(x => x.FullName == "StructTests.Table");
            object table     = Activator.CreateInstance(tableType);

            Type   fooType = asm.GetTypes().Single(x => x.FullName == "StructTests.Foo");
            object foo     = Activator.CreateInstance(fooType);

            dynamic dFoo = foo;

            dFoo.id     = 123ul;
            dFoo.count  = 4;
            dFoo.prefix = 1;
            dFoo.length = 52;

            dynamic dTable = table;

            Assert.AreEqual(3, dTable.defaultInt);
            dTable.foo = dFoo;

            byte[] destination = new byte[1024];

            var    serializer   = CompilerTestHelpers.CompilerTestSerializer.Compile(table);
            int    bytesWritten = serializer.Write(destination, table);
            object parsed       = serializer.Parse(destination);

            Assert.IsTrue(tableType.IsAssignableFrom(parsed.GetType()));

            dynamic dParsedTable = parsed;

            Assert.AreEqual(3, dParsedTable.defaultInt);

            dynamic dParsedFoo = dParsedTable.foo;

            Assert.AreEqual(dFoo.id, dParsedFoo.id);
            Assert.AreEqual(dFoo.count, dParsedFoo.count);
            Assert.AreEqual(dFoo.prefix, dParsedFoo.prefix);
            Assert.AreEqual(dFoo.length, dParsedFoo.length);
        }
Ejemplo n.º 27
0
        private void Test(SetterKind setterKind, FlatBufferDeserializationOption option)
        {
            string schema = $@"
            namespace VirtualTests;
            table VirtualTable ({MetadataKeys.SerializerKind}:""{option}"") {{
                Default:int ({MetadataKeys.Setter}:""{setterKind}"");
                ForcedVirtual:int ({MetadataKeys.NonVirtualProperty}:""false"", {MetadataKeys.SetterLegacy}:""{setterKind}"");
                ForcedNonVirtual:int ({MetadataKeys.NonVirtualProperty}:""true"", {MetadataKeys.Setter}:""{(setterKind != SetterKind.None ? setterKind : SetterKind.Public)}"");
                Struct:VirtualStruct;
            }}

            struct VirtualStruct {{
                Default:int ({MetadataKeys.Setter}:""{setterKind}"");
                ForcedVirtual:int ({MetadataKeys.NonVirtualProperty}:""false"", setter:""{setterKind}"");
                ForcedNonVirtual:int ({MetadataKeys.NonVirtualProperty}:""true"", setter:""{(setterKind != SetterKind.None ? setterKind : SetterKind.Public)}"");
            }}";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema, new());

            foreach (var typeName in new[] { "VirtualTests.VirtualTable", "VirtualTests.VirtualStruct" })
            {
                Type type = asm.GetType(typeName);
                Assert.IsTrue(type.IsPublic);
                var defaultProperty          = type.GetProperty("Default");
                var forcedVirtualProperty    = type.GetProperty("ForcedVirtual");
                var forcedNonVirtualProperty = type.GetProperty("ForcedNonVirtual");

                Assert.IsNotNull(defaultProperty);
                Assert.IsNotNull(forcedVirtualProperty);
                Assert.IsNotNull(forcedNonVirtualProperty);

                Assert.IsTrue(defaultProperty.GetMethod.IsPublic);
                Assert.IsTrue(forcedVirtualProperty.GetMethod.IsPublic);
                Assert.IsTrue(forcedNonVirtualProperty.GetMethod.IsPublic);

                if (setterKind == SetterKind.PublicInit ||
                    setterKind == SetterKind.ProtectedInit ||
                    setterKind == SetterKind.ProtectedInternalInit)
                {
                    Assert.IsNotNull(defaultProperty.SetMethod.ReturnParameter.GetRequiredCustomModifiers().Any(x => x.FullName == "System.Runtime.CompilerServices.IsExternalInit"));
                    Assert.IsNotNull(forcedVirtualProperty.SetMethod.ReturnParameter.GetRequiredCustomModifiers().Any(x => x.FullName == "System.Runtime.CompilerServices.IsExternalInit"));
                    Assert.IsNotNull(forcedNonVirtualProperty.SetMethod.ReturnParameter.GetRequiredCustomModifiers().Any(x => x.FullName == "System.Runtime.CompilerServices.IsExternalInit"));
                }

                if (setterKind == SetterKind.None)
                {
                    Assert.IsNull(defaultProperty.SetMethod);
                    Assert.IsNull(forcedVirtualProperty.SetMethod);
                    Assert.IsNotNull(forcedNonVirtualProperty.SetMethod); // non-virtual can't have null setters.
                }
                else if (setterKind == SetterKind.Protected || setterKind == SetterKind.ProtectedInit)
                {
                    Assert.IsTrue(defaultProperty.SetMethod.IsFamily);
                    Assert.IsTrue(forcedVirtualProperty.SetMethod.IsFamily);
                    Assert.IsTrue(forcedNonVirtualProperty.SetMethod.IsFamily);
                }
                else if (setterKind == SetterKind.ProtectedInternal || setterKind == SetterKind.ProtectedInternalInit)
                {
                    Assert.IsTrue(defaultProperty.SetMethod.IsFamilyOrAssembly);
                    Assert.IsTrue(forcedVirtualProperty.SetMethod.IsFamilyOrAssembly);
                    Assert.IsTrue(forcedNonVirtualProperty.SetMethod.IsFamilyOrAssembly);
                }
                else if (setterKind == SetterKind.Public || setterKind == SetterKind.PublicInit)
                {
                    Assert.IsTrue(defaultProperty.SetMethod.IsPublic);
                    Assert.IsTrue(forcedVirtualProperty.SetMethod.IsPublic);
                    Assert.IsTrue(forcedNonVirtualProperty.SetMethod.IsPublic);
                }
                else
                {
                    Assert.Fail();
                }
            }
        }
Ejemplo n.º 28
0
        private void MonsterTest(string flags)
        {
            // https://github.com/google/flatbuffers/blob/master/samples/monster.fbs
            string schema = $@"
namespace MyGame;

enum Color:byte {{ Red = 0, Green, Blue = 2 }}
union Equipment {{ Weapon, Vec3, Vec4, Monster, string }}

struct Vec3 {{
  x:float;
  y:float;
  z:float;
}}

struct Vec4 {{
  x:float;
  y:float;
  z:float;
  t:float;
}}

table Monster (PrecompiledSerializer:{flags}) {{
  pos:Vec3;
  mana:short = 150;
  hp:short = 100;
  name:string;
  friendly:bool = false (deprecated);
  inventory:[ubyte];
  color:Color = Blue;
  weapons:[Weapon];
  equipped:Equipment;
  path:[Vec3];
  vec4:Vec4;
  FakeVector1:[string] (VectorType:""IReadOnlyList"");
  FakeVector2:[string] (VectorType:Array);
  FakeVector3:[string] (VectorType:IList);
  FakeVector4:[string];
  FakeMemoryVector:[ubyte] (VectorType:Memory);
  FakeMemoryVectorReadOnly:[ubyte] (VectorType:ReadOnlyMemory);
}}

table Weapon {{
  name:string;
  damage:short;
}}";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema);

            Type    weaponType  = asm.GetType("MyGame.Weapon");
            Type    monsterType = asm.GetTypes().Single(x => x.FullName == "MyGame.Monster");
            object  monster     = Activator.CreateInstance(monsterType);
            dynamic dMonster    = monster;

            Type    vec4Type = asm.GetTypes().Single(x => x.FullName == "MyGame.Vec4");
            Type    vec3Type = asm.GetTypes().Single(x => x.FullName == "MyGame.Vec3");
            object  vec      = Activator.CreateInstance(vec3Type);
            dynamic dVec     = vec;

            Assert.AreEqual((short)150, dMonster.mana);
            Assert.AreEqual((short)100, dMonster.hp);
            Assert.IsFalse(dMonster.friendly);
            Assert.AreEqual("Blue", dMonster.color.ToString());
            Assert.IsNull(dMonster.pos);

            Assert.AreEqual(typeof(IList <byte>), monsterType.GetProperty("inventory").PropertyType);
            Assert.AreEqual(typeof(IList <>).MakeGenericType(vec3Type), monsterType.GetProperty("path").PropertyType);
            Assert.AreEqual(typeof(IList <>).MakeGenericType(weaponType), monsterType.GetProperty("weapons").PropertyType);
            Assert.IsTrue(typeof(FlatBufferUnion <, , , ,>).MakeGenericType(weaponType, vec3Type, vec4Type, monsterType, typeof(string)).IsAssignableFrom(monsterType.GetProperty("equipped").PropertyType));
            Assert.AreEqual(typeof(string), monsterType.GetProperty("name").PropertyType);
            Assert.IsTrue(monsterType.GetProperty("friendly").GetCustomAttribute <FlatBufferItemAttribute>().Deprecated);

            byte[] data = new byte[1024];
            CompilerTestHelpers.CompilerTestSerializer.ReflectionSerialize(monster, data);
            var parsedMonster = CompilerTestHelpers.CompilerTestSerializer.ReflectionParse(monsterType, data);

            Assert.AreNotEqual(parsedMonster.GetType(), monster.GetType());

            var copiedMonster = Activator.CreateInstance(monsterType, new[] { parsedMonster });

            Assert.AreEqual(copiedMonster.GetType(), monster.GetType());
        }
Ejemplo n.º 29
0
        public void TestUnionCustomClassGeneration()
        {
            const string Schema    = @"
namespace Foobar;

table A { Value:int32; }
table B { Value:int32; }
struct C { Value:int32; }

union TestUnion { First:A, B, Foobar.C }

table D (PrecompiledSerializer) { Union:TestUnion; }

";
            Assembly     asm       = FlatSharpCompiler.CompileAndLoadAssembly(Schema);
            Type         unionType = asm.GetType("Foobar.TestUnion");
            Type         aType     = asm.GetType("Foobar.A");
            Type         bType     = asm.GetType("Foobar.B");
            Type         cType     = asm.GetType("Foobar.C");
            Type         dType     = asm.GetType("Foobar.D");

            Assert.AreEqual(unionType, dType.GetProperty("Union").PropertyType);

            // Custom union derives from FlatBufferUnion
            Assert.IsTrue(typeof(FlatBufferUnion <, ,>).MakeGenericType(aType, bType, cType).IsAssignableFrom(unionType));
            Type[]   types           = new[] { aType, bType, cType };
            string[] expectedAliases = new[] { "First", "B", "C" };

            // Validate nested enum
            Type nestedEnum = unionType.GetNestedTypes().Single();

            Assert.IsTrue(nestedEnum.IsEnum);
            Assert.AreEqual("ItemKind", nestedEnum.Name);
            Assert.AreEqual(typeof(byte), Enum.GetUnderlyingType(nestedEnum));
            Assert.AreEqual(types.Length, Enum.GetValues(nestedEnum).Length);
            for (int i = 0; i < types.Length; ++i)
            {
                Assert.AreEqual(expectedAliases[i], Enum.GetName(nestedEnum, (byte)(i + 1)));
            }

            // Custom union defines ctors for all input types.
            foreach (var type in types)
            {
                var ctor = unionType.GetConstructor(new[] { type });
                Assert.IsNotNull(ctor);
            }

            // Custom union defines a clone method.
            var cloneMethod = unionType.GetMethod("Clone");

            Assert.IsNotNull(cloneMethod);
            Assert.AreEqual(unionType, cloneMethod.ReturnType); // returns same type.
            Assert.IsTrue(cloneMethod.IsHideBySig);             // hides base clone method.

            var parameters = cloneMethod.GetParameters();

            Assert.AreEqual(3, parameters.Length);
            for (int i = 0; i < parameters.Length; ++i)
            {
                Assert.AreEqual(typeof(Func <,>).MakeGenericType(new[] { types[i], types[i] }), parameters[i].ParameterType);
                Assert.AreEqual("clone" + expectedAliases[i], parameters[i].Name);
            }

            var switchMethods = unionType.GetMethods().Where(m => m.Name == "Switch").Where(m => m.DeclaringType == unionType).ToArray();

            Assert.AreEqual(4, switchMethods.Length);
            Assert.AreEqual(2, switchMethods.Count(x => x.ReturnType.FullName != "System.Void")); // 2 of them return something.
            Assert.IsTrue(switchMethods.All(x => x.IsHideBySig));                                 // all of them hide the method from the base class.

            // Validate parameter names on switch method.
            var switchMethod = switchMethods.Single(x => x.ReturnType.FullName == "System.Void" && !x.IsGenericMethod);

            parameters = switchMethod.GetParameters();
            Assert.AreEqual(types.Length + 1, parameters.Length);
            Assert.AreEqual(typeof(Action), parameters[0].ParameterType);
            Assert.AreEqual("caseDefault", parameters[0].Name);

            for (int i = 0; i < types.Length; ++i)
            {
                Assert.AreEqual(typeof(Action <>).MakeGenericType(types[i]), parameters[i + 1].ParameterType);
                Assert.AreEqual("case" + expectedAliases[i], parameters[i + 1].Name);
            }

            // Now let's use it a little bit.
            for (int i = 0; i < types.Length; ++i)
            {
                object  member        = Activator.CreateInstance(types[i]);
                dynamic union         = Activator.CreateInstance(unionType, member);
                byte    discriminator = union.Discriminator;
                object  kind          = union.Kind;

                byte kindValue = Convert.ToByte((object)union.Kind);

                Assert.AreEqual(i + 1, discriminator);
                Assert.AreEqual(i + 1, kindValue);
                Assert.AreEqual(expectedAliases[i], kind.ToString());
            }
        }
        public void MonsterTest()
        {
            // https://github.com/google/flatbuffers/blob/master/samples/monster.fbs
            string schema = @"
namespace MyGame;
enum Color:byte { Red = 0, Green, Blue = 2 }

union Equipment { Weapon } // Optionally add more tables.

struct Vec3 {
  x:float;
  y:float;
  z:float;
}

table Monster (PrecompiledSerializer:""greedymutable"") {
  pos:Vec3;
  mana:short = 150;
  hp:short = 100;
  name:string;
  friendly:bool = false (deprecated);
  inventory:[ubyte];
  color:Color = Blue;
  weapons:[Weapon];
  equipped:Equipment;
  path:[Vec3];
}

table Weapon (PrecompiledSerializer:lazy) {
  name:string;
  damage:short;
}

root_type Monster;";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(schema);

            Type    weaponType  = asm.GetType("MyGame.Weapon");
            Type    monsterType = asm.GetTypes().Single(x => x.FullName == "MyGame.Monster");
            dynamic serializer  = monsterType.GetProperty("Serializer", BindingFlags.Static | BindingFlags.Public).GetValue(null);

            object  monster  = Activator.CreateInstance(monsterType);
            dynamic dMonster = monster;

            Type    vecType = asm.GetTypes().Single(x => x.FullName == "MyGame.Vec3");
            object  vec     = Activator.CreateInstance(vecType);
            dynamic dVec    = vec;

            Assert.AreEqual((short)150, dMonster.mana);
            Assert.AreEqual((short)100, dMonster.hp);
            Assert.IsFalse(dMonster.friendly);
            Assert.AreEqual("Blue", dMonster.color.ToString());
            Assert.IsNull(dMonster.pos);

            Assert.AreEqual(typeof(IList <byte>), monsterType.GetProperty("inventory").PropertyType);
            Assert.AreEqual(typeof(IList <>).MakeGenericType(vecType), monsterType.GetProperty("path").PropertyType);
            Assert.AreEqual(typeof(IList <>).MakeGenericType(weaponType), monsterType.GetProperty("weapons").PropertyType);
            Assert.AreEqual(typeof(FlatBufferUnion <>).MakeGenericType(weaponType), monsterType.GetProperty("equipped").PropertyType);
            Assert.AreEqual(typeof(string), monsterType.GetProperty("name").PropertyType);
            Assert.IsTrue(monsterType.GetProperty("friendly").GetCustomAttribute <FlatBufferItemAttribute>().Deprecated);

            byte[] data = new byte[1024];

            CompilerTestHelpers.CompilerTestSerializer.ReflectionSerialize(monster, data);
            var parsedMonster = serializer.Parse(new ArrayInputBuffer(data));

            Assert.AreEqual("Blue", parsedMonster.color.ToString());
        }