static void Test(FlatBufferDeserializationOption option)
        {
            string schema = $@"
                {MetadataHelpers.AllAttributes}
                namespace ForceWriteTests;
                table Table ({MetadataKeys.SerializerKind}:""{option}"") {{ Struct:Struct; }}
                struct Struct ({MetadataKeys.WriteThrough}) {{ foo:int; bar:int ({MetadataKeys.WriteThrough}:""false""); }} 
            ";

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

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

            table.Struct     = (dynamic)Activator.CreateInstance(structType);
            table.Struct.foo = 42;
            table.Struct.bar = 65;

            byte[] data = new byte[100];
            serializer.Write(data, (object)table);

            dynamic parsed = serializer.Parse(data);

            parsed.Struct.foo = 100;

            Assert.Throws <NotMutableException>(() => parsed.Struct.bar = 22);

            dynamic parsed2 = serializer.Parse(data);

            Assert.Equal(100, (int)parsed2.Struct.foo);
            Assert.Equal(65, (int)parsed2.Struct.bar);
        }
Exemple #2
0
    public void InvalidEnumTest_DuplicateNames_BitFlags()
    {
        string fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : ubyte (bit_flags) {{ Red, Blue, Yellow, Red }}";
        var    ex  = Assert.Throws <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(fbs, new()));

        Assert.Contains("error: enum value already exists: Red", ex.Message);
    }
Exemple #3
0
    public void InvalidEnumTest_ValueOutOfRangeOfUnderlyingType_Below()
    {
        string fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : ulong {{ Red = -1, Blue = 255, Yellow = 256 }}";
        var    ex  = Assert.Throws <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(fbs, new()));

        Assert.Contains("error: enum value does not fit, \"-1\"", ex.Message);
    }
Exemple #4
0
    public void FlagsTest_TooMany()
    {
        string fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : ubyte (bit_flags) {{ A, B, C, D, E, F, G, H, I }}";
        var    ex  = Assert.Throws <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(fbs, new()));

        Assert.Contains("error: bit flag out of range of underlying integral type", ex.Message);
    }
Exemple #5
0
    public void InvalidEnumTest_NaturalOverflow()
    {
        string fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : ubyte {{ Red = 255, Blue }}";
        var    ex  = Assert.Throws <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(fbs, new()));

        Assert.Contains("error: enum value does not fit, \"255 + 1\" out of [0; 255]", ex.Message);
    }
    public void NullableAnnotations()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace NullableAnnotationTests;

            table Table ({MetadataKeys.SerializerKind}) {{
                foo:Foo;
                defaultInt:int32 = 3;
                str:string;
                nullableInt:int32 = null;
                arrayVector:[int32] ({MetadataKeys.VectorKind}:""Array"");
                memoryVector:[ubyte] ({MetadataKeys.VectorKind}:""Memory"");
                listVector:[int32] ({MetadataKeys.VectorKind}:""IList"");
                nestedTable:InnerTable;
            }}

            table InnerTable {{ str:string; }}

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

        Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(
            schema,
            new());
    }
Exemple #7
0
        public void StructVector_NestedStruct()
        {
            int length = 7;

            string schema = $@"
            namespace StructVectorTests;

            table Table ({MetadataKeys.SerializerKind}) {{
                foo:Foo;
            }}
            struct Bar {{ A:ubyte; B:ulong; }}
            struct Foo {{
              V:[Bar:{length}] ({MetadataKeys.NonVirtualProperty});
            }}";

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

            Type tableType = asm.GetType("StructVectorTests.Table");
            Type fooType   = asm.GetType("StructVectorTests.Foo");

            Assert.IsFalse(fooType.GetProperty("__flatsharp__V_0").GetMethod.IsVirtual);
            Assert.IsFalse(fooType.GetProperty("__flatsharp__V_0").SetMethod.IsVirtual);

            Type barType = asm.GetType("StructVectorTests.Bar");

            dynamic table = Activator.CreateInstance(tableType);
            dynamic foo   = Activator.CreateInstance(fooType);

            table.foo = foo;

            Assert.AreEqual(length, foo.V.Count);

            for (int i = 0; i < length; ++i)
            {
                dynamic bar = Activator.CreateInstance(barType);
                bar.A = (byte)i;
                bar.B = (ulong)i;

                foo.V[i] = bar;
            }

            byte[] data = new byte[1024];

            var serializer = CompilerTestHelpers.CompilerTestSerializer.Compile((object)table);

            serializer.Write(data, (object)table);
            dynamic parsed = serializer.Parse(data);
            dynamic copy   = Activator.CreateInstance(tableType, (object)parsed);

            Assert.AreEqual(length, parsed.foo.V.Count);
            for (int i = 0; i < length; ++i)
            {
                Assert.AreEqual((byte)i, parsed.foo.V[i].A);
                Assert.AreEqual((byte)i, copy.foo.V[i].A);
                Assert.AreEqual((ulong)i, parsed.foo.V[i].B);
                Assert.AreEqual((ulong)i, copy.foo.V[i].B);
            }
        }
Exemple #8
0
        public void BasicEnumTest_Byte()
        {
            string           schema = @"
namespace Foo.Bar;

table Request { str:string; }
table Response { str:string; }
rpc_service Service {
    HelloUnary(Request):Response (streaming:unary);
    HelloServer(Request):Response (streaming:""server"");
    HelloClient(Request):Response (streaming:client);
    HelloBidi(Request):Response (streaming:""bidi"");
    HelloUnaryImplicit(Request):Response;
}
";
            BaseSchemaMember member = FlatSharpCompiler.TestHookParseSyntax(schema);
            var rpcDef = member.Children["Foo"].Children["Bar"].Children["Service"] as RpcDefinition;

            Assert.IsNotNull(rpcDef);

            Assert.AreEqual(5, rpcDef.Methods.Count);
            Assert.AreEqual(("Request", "Response", RpcStreamingType.Unary), rpcDef.Methods["HelloUnary"]);
            Assert.AreEqual(("Request", "Response", RpcStreamingType.Unary), rpcDef.Methods["HelloUnaryImplicit"]);
            Assert.AreEqual(("Request", "Response", RpcStreamingType.Server), rpcDef.Methods["HelloServer"]);
            Assert.AreEqual(("Request", "Response", RpcStreamingType.Client), rpcDef.Methods["HelloClient"]);
            Assert.AreEqual(("Request", "Response", RpcStreamingType.Bidirectional), rpcDef.Methods["HelloBidi"]);
        }
Exemple #9
0
        public void EnumTest <T>(string flatBufferType) where T : struct
        {
            string   fbs = $"namespace Foo.Bar; enum MyEnum : {flatBufferType} {{ Red, Blue = 3, Green, Yellow }}";
            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(fbs, new());

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

            Assert.IsTrue(t.IsEnum);
            Assert.AreEqual(typeof(T), Enum.GetUnderlyingType(t));
            Assert.IsTrue(t.GetCustomAttribute <FlatSharp.Attributes.FlatBufferEnumAttribute>() != null);

            string[] names = Enum.GetNames(t);
            Assert.AreEqual(4, names.Length);
            Assert.AreEqual("Red", names[0]);
            Assert.AreEqual("Blue", names[1]);
            Assert.AreEqual("Green", names[2]);
            Assert.AreEqual("Yellow", names[3]);

            Array values = Enum.GetValues(t);

            Assert.AreEqual(Convert.ChangeType(0, typeof(T)), (T)values.GetValue(0));
            Assert.AreEqual(Convert.ChangeType(3, typeof(T)), (T)values.GetValue(1));
            Assert.AreEqual(Convert.ChangeType(4, typeof(T)), (T)values.GetValue(2));
            Assert.AreEqual(Convert.ChangeType(5, typeof(T)), (T)values.GetValue(3));
        }
        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);

                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];
                CompilerTestHelpers.CompilerTestSerializer.ReflectionSerialize(Activator.CreateInstance(tableType), data);
                CompilerTestHelpers.CompilerTestSerializer.ReflectionParse(tableType, data);
            }
            catch (TargetInvocationException ex)
            {
                throw ex.InnerException;
            }
        }
Exemple #11
0
    public void InvalidEnumTest_NotAnInt()
    {
        // Quirk of the grammar allows this.
        string fbs = $"{MetadataHelpers.AllAttributes}namespace Foo.Bar; enum MyEnum : uint {{ Red = 1.2 }}";
        var    ex  = Assert.Throws <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(fbs, new()));

        Assert.Contains("error: enum value does not fit, \"1.2\"", ex.Message);
    }
        public void LegacyObsoleteDefaultConstructor()
        {
            string schema = $@"
            namespace Foo; 
            table Table ({MetadataKeys.ObsoleteDefaultConstructorLegacy}) {{ Int:int; }}";

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

            Assert.IsTrue(ex.Errors[0].StartsWith("Message='The 'ObsoleteDefaultConstructor' metadata attribute has been deprecated. Please use the 'fs_defaultCtor' attribute instead.'"));
        }
        public void DefaultCtorKind_None_Struct()
        {
            string schema = $@"
            namespace Foo; 
            struct InnerStruct ({MetadataKeys.DefaultConstructorKind}:""{DefaultConstructorKind.None}"") {{ Int:int; }}";

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

            Assert.AreEqual("Message='Structs must have default constructors.', Scope=$..Foo.InnerStruct", ex.Errors[0]);
        }
Exemple #14
0
        public void ForceWrite_OnOptionalScalar()
        {
            string schema = $@"
            namespace ForceWriteTests;
            table Table {{  optInt:int = null ({MetadataKeys.ForceWrite}); }}
            ";

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

            Assert.IsTrue(ex.Errors[0].StartsWith("Message='Property 'optInt' on table 'ForceWriteTests.Table' declares the ForceWrite option, but the type is not supported for force write.', Scope=$"));
        }
        public void ObsoleteConstructorExplicitFalse()
        {
            string schema = "namespace Foo; table BaseTable (obsoleteDefaultConstructor:\"false\") { Int:int; }";

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

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

            Assert.IsNull(constructor.GetCustomAttribute <ObsoleteAttribute>());
        }
    public void UnsupportedAttribute_ForceAlign_TableField()
    {
        string schema = @"
            namespace ns;
            table Foo { Value : int (force_align: 2); }
        ";

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

        Assert.Contains("FlatSharp does not support the 'force_align' attribute.", ex.Message);
    }
Exemple #17
0
    public void DefaultCtorKind_None_Struct()
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace Foo; 
            struct InnerStruct ({MetadataKeys.DefaultConstructorKind}:""{DefaultConstructorKind.None}"") {{ Int:int; }}";

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

        Assert.Contains("The attribute 'fs_defaultCtor' value None is not valid on Struct elements.", ex.Errors[0]);
    }
Exemple #18
0
        public void TestMultipleNamespaces()
        {
            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(Schema, new());

            Assert.IsNotNull(asm.GetType("NamespaceA.NamespaceB.TableInNestedNS"));
            Assert.IsNotNull(asm.GetType("NamespaceA.NamespaceB.EnumInNestedNS"));
            Assert.IsNotNull(asm.GetType("NamespaceA.NamespaceB.StructInNestedNS"));
            Assert.IsNotNull(asm.GetType("NamespaceA.TableInFirstNS"));
            Assert.IsNotNull(asm.GetType("NamespaceC.TableInC"));
            Assert.IsNotNull(asm.GetType("NamespaceA.SecondTableInA"));
        }
Exemple #19
0
        public void DuplicateTypesDifferentFiles()
        {
            string baseFbs  = "include \"A.fbs\"; namespace Foo; table BaseTable (PrecompiledSerializer) { BaseTable:BaseTable; }";
            var    includes = new Dictionary <string, string>
            {
                { "A.fbs", "namespace Foo; table BaseTable { BaseTable:BaseTable; }" },
            };

            var ex = Assert.ThrowsException <InvalidFbsFileException>(() => FlatSharpCompiler.TestHookCreateCSharp(baseFbs, includes));

            Assert.IsTrue(ex.Message.Contains("Duplicate member name"));
        }
 public void StructMember_with_id()
 {
     try
     {
         const string Schema = "namespace TableMemberTests; struct Struct { member:string (id:1); member2:int (id:0); }";
         Assert.ThrowsException <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(Schema, new()));
     }
     catch (TargetInvocationException ex)
     {
         throw ex.InnerException;
     }
 }
 public void TableMember_has_id_attribute_but_with_no_value()
 {
     try
     {
         const string Schema = "namespace TableMemberTests; table Table { member:string (id:0); member2:int (id); }";
         Assert.ThrowsException <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(Schema, new()));
     }
     catch (TargetInvocationException ex)
     {
         throw ex.InnerException;
     }
 }
 public void TableMember_only_some_fields_have_id()
 {
     try
     {
         const string Schema = "namespace TableMemberTests; table Table { member:string (id:1); member2:int; }";
         Assert.ThrowsException <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(Schema, new()));
     }
     catch (TargetInvocationException ex)
     {
         throw ex.InnerException;
     }
 }
        public void Unknown_Root_Type_No_File_Identifier()
        {
            string schema = $@"
            namespace FileIdTests.A;
            table Table {{ foo:int; }}
            root_type Something;
            ";

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

            Assert.IsTrue(ex.Errors[0].StartsWith("Message='Unable to resolve root_type 'Something'.', Scope=$"));
        }
        public void Manually_Specified_Id_TooLong()
        {
            string schema = $@"
            namespace FileIdTests.A;
            table Table ({MetadataKeys.FileIdentifier}:AbCdefg) {{ foo:int; }}
            root_type Table;
            ";

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

            Assert.AreEqual(ex.Errors[0], "Message='File identifier 'AbCdefg' is invalid. FileIdentifiers must be exactly 4 ASCII characters.', Scope=$.");
        }
Exemple #25
0
        public void SortedVector_Dictionary_NoKey()
        {
            string schema = $@"
table Monster (PrecompiledSerializer) {{
  Vector:[VectorMember] (VectorType:IDictionary);
}}
table VectorMember {{
    Data:string;
}}";

            Assert.ThrowsException <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(schema));
        }
Exemple #26
0
        public void SortedVector_IndexedVector_NoKey()
        {
            string schema = $@"
table Monster ({MetadataKeys.SerializerKind}) {{
  Vector:[VectorMember] ({MetadataKeys.VectorKind}:IIndexedVector);
}}
table VectorMember {{
    Data:string;
}}";

            Assert.ThrowsException <InvalidFbsFileException>(() => FlatSharpCompiler.CompileAndLoadAssembly(schema, new()));
        }
Exemple #27
0
    public void DefaultCtorKind_NoValue_Struct()
    {
        string schema = $"{MetadataHelpers.AllAttributes}namespace Foo; struct BaseTable ({MetadataKeys.DefaultConstructorKind}) {{ Int:int; }}";

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

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

        Assert.NotNull(constructor);
        Assert.True(constructor.IsPublic);
        Assert.Null(constructor.GetCustomAttribute <ObsoleteAttribute>());
    }
Exemple #28
0
    public void Root_Type_With_No_File_Identifier()
    {
        string schema = $@"
            namespace FileIdTests.A;
            table Table {{ foo:int; }}
            root_type Table;
            ";

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

        Assert.Null(
            asm.GetType("FileIdTests.A.Table").GetCustomAttribute <FlatBufferTableAttribute>().FileIdentifier);
    }
Exemple #29
0
    public void Enum_Root_Type()
    {
        string schema = $@"
            namespace FileIdTests.A;
            table Table {{ foo:int; }}
            enum Enum : ubyte {{ Foo, Bar, Baz }}
            root_type Enum;
            ";

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

        Assert.Contains("error: unknown root type: Enum", ex.Errors[0]);
    }
Exemple #30
0
    public void Struct_Root_Type()
    {
        string schema = $@"
            namespace FileIdTests.A;
            table Table {{ foo:int; }}
            struct Struct {{ foo:int; }}
            root_type Struct;
            ";

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

        Assert.Contains("error: root type must be a table", ex.Errors[0]);
    }