public void GetCustomAttributes_DuplicateAttributesWereAddedToTable_TableAttributesDisallowingMultipleOverwritesExistingAttributes()
        {
            ReflectionTableBuilder builder = new ReflectionTableBuilder();

            builder.ForType <DecoratedTypes.Base>()
            .AddTypeAttributes(new InheritedSingleAttribute("Q"), new InheritedMultiAttribute("Q"), new NonInheritedSingleAttribute("Q"), new NonInheritedMultiAttribute("Q"))
            ;

            var table   = builder.CreateTable();
            var context = new TableReflectionContext(table, TableReflectionContextOptions.Default);

            var originalType = typeof(DecoratedTypes.Base);
            var mappedType   = context.MapType(originalType);

            var expected = new Attribute[] {
                new InheritedMultiAttribute("Q"),
                new InheritedSingleAttribute("Q"),
                new NonInheritedMultiAttribute("Q"),
                new NonInheritedSingleAttribute("Q"),
                new InheritedMultiAttribute(nameof(DecoratedTypes.Base)),
                new NonInheritedMultiAttribute(nameof(DecoratedTypes.Base))
            };

            var actual = FilterAttributes(mappedType.GetCustomAttributes(true));

            SequenceAssert.AreEquivalent(expected, actual);
        }
        public void GetCustomAttributes_ChainedReflectionContexts_ReturnsExpectedAttributes()
        {
            ReflectionTableBuilder builderA = new ReflectionTableBuilder();

            builderA.ForType <DecoratedTypes.Base>()
            .AddTypeAttributes(new InheritedSingleAttribute("Q"), new InheritedMultiAttribute("Q"), new NonInheritedSingleAttribute("Q"), new NonInheritedMultiAttribute("Q"))
            .AddMemberAttributes(t => t.OverriddenProperty, new InheritedSingleAttribute("Q"), new InheritedMultiAttribute("Q"), new NonInheritedSingleAttribute("Q"), new NonInheritedMultiAttribute("Q"))
            ;

            var tableA   = builderA.CreateTable();
            var contextA = new TableReflectionContext(tableA, TableReflectionContextOptions.Default);

            var originalType = typeof(DecoratedTypes.Base);
            var mappedTypeA  = contextA.MapType(originalType);

            ReflectionTableBuilder builderB = new ReflectionTableBuilder();

            builderB.ForType <DecoratedTypes.Base>()
            .AddTypeAttributes(new InheritedSingleAttribute("2"), new InheritedMultiAttribute("2"), new NonInheritedSingleAttribute("2"), new NonInheritedMultiAttribute("2"))
            .AddMemberAttributes(t => t.OverriddenProperty, new InheritedSingleAttribute("2"), new InheritedMultiAttribute("2"), new NonInheritedSingleAttribute("2"), new NonInheritedMultiAttribute("2"))
            ;

            var tableB   = builderB.CreateTable();
            var contextB = new TableReflectionContext(tableB, TableReflectionContextOptions.Default);

            var mappedTypeComposite = contextB.MapType(mappedTypeA);

            var actual   = FilterAttributes(mappedTypeComposite.GetCustomAttributes());
            var expected = new Attribute[]
            {
                new NonInheritedMultiAttribute(nameof(DecoratedTypes.Base)),
                new InheritedMultiAttribute(nameof(DecoratedTypes.Base)),
                new InheritedMultiAttribute("Q"),
                new NonInheritedMultiAttribute("Q"),
                new InheritedSingleAttribute("2"),
                new InheritedMultiAttribute("2"),
                new NonInheritedSingleAttribute("2"),
                new NonInheritedMultiAttribute("2")
            };

            SequenceAssert.AreEquivalent(expected, actual);

            actual   = FilterAttributes(mappedTypeComposite.GetProperty(nameof(UndecoratedTypes.Base.OverriddenProperty)).GetCustomAttributes());
            expected = new Attribute[]
            {
                new NonInheritedMultiAttribute(nameof(DecoratedTypes.Base)),
                new InheritedMultiAttribute(nameof(DecoratedTypes.Base)),
                new InheritedMultiAttribute("Q"),
                new NonInheritedMultiAttribute("Q"),
                new InheritedSingleAttribute("2"),
                new InheritedMultiAttribute("2"),
                new NonInheritedSingleAttribute("2"),
                new NonInheritedMultiAttribute("2")
            };

            SequenceAssert.AreEquivalent(expected, actual);
        }
        public void GetCustomAttributes_SpecificAttributeType_CorrectlyFiltersAttributes()
        {
            ReflectionTableBuilder builderA = new ReflectionTableBuilder();

            builderA.ForType <UndecoratedTypes.Base>()
            .AddTypeAttributes(CreateTestAttributes(nameof(UndecoratedTypes.Base)));

            var tableA   = builderA.CreateTable();
            var contextA = new TableReflectionContext(tableA, TableReflectionContextOptions.Default);

            var actual   = contextA.MapType(typeof(UndecoratedTypes.Base)).GetCustomAttributes(typeof(InheritedSingleAttribute), true);
            var expected = typeof(DecoratedTypes.Base).GetCustomAttributes(typeof(InheritedSingleAttribute), true);

            Assert.AreEqual(expected.GetType(), actual.GetType());
            SequenceAssert.AreEquivalent(expected, actual);
        }
        private IReflectionTable CreateTable()
        {
            ReflectionTableBuilder builder = new ReflectionTableBuilder();

            builder
            .AddTypeAttributes <UndecoratedTypes.IBase1>(CreateTestAttributes <UndecoratedTypes.IBase1>())
            .AddPropertyAttributes <UndecoratedTypes.IBase1>(nameof(UndecoratedTypes.IBase1.ImplementedProperty), CreateTestAttributes <UndecoratedTypes.IBase1>())
            .AddPropertyAttributes <UndecoratedTypes.IBase1>(nameof(UndecoratedTypes.IBase1.HiddenProperty), CreateTestAttributes <UndecoratedTypes.IBase1>())
            .AddMemberAttributes <UndecoratedTypes.IBase1>(c => c.ImplementedMethod1(0, 0), CreateTestAttributes <UndecoratedTypes.IBase1>())
            .AddMemberAttributes <UndecoratedTypes.IBase1>(c => c.HiddenMethod1(0), CreateTestAttributes <UndecoratedTypes.IBase1>())
            .AddMemberAttributes <UndecoratedTypes.IBase1>(c => c.OverloadedMethod(default(int)), CreateTestAttributes(nameof(UndecoratedTypes.IBase1) + "int"))
            .AddMemberAttributes <UndecoratedTypes.IBase1>(c => c.OverloadedMethod(default(long)), CreateTestAttributes(nameof(UndecoratedTypes.IBase1) + "long"))

            .AddTypeAttributes <UndecoratedTypes.IBase2>(CreateTestAttributes <UndecoratedTypes.IBase2>())
            .AddMemberAttributes <UndecoratedTypes.IBase2>(c => c.ImplementedMethod1(0, 0), CreateTestAttributes <UndecoratedTypes.IBase2>())

            .AddTypeAttributes <UndecoratedTypes.IComposite>(CreateTestAttributes <UndecoratedTypes.IComposite>())
            .AddPropertyAttributes <UndecoratedTypes.IComposite>(nameof(UndecoratedTypes.IComposite.HiddenProperty), CreateTestAttributes <UndecoratedTypes.IComposite>())
            .AddMemberAttributes <UndecoratedTypes.IComposite>(c => c.HiddenMethod1(0), CreateTestAttributes <UndecoratedTypes.IComposite>())

            .AddTypeAttributes <UndecoratedTypes.Base>(CreateTestAttributes <UndecoratedTypes.Base>())
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.HiddenProperty, CreateTestAttributes <UndecoratedTypes.Base>())
            .ForType <UndecoratedTypes.Base>()
            .AddMemberAttributes(c => c.ImplementedProperty, CreateTestAttributes <UndecoratedTypes.Base>())
            .AddMemberAttributes(c => c.OverriddenProperty, CreateTestAttributes <UndecoratedTypes.Base>())
            .AddMemberAttributes(c => c.OverriddenProperty2, CreateTestAttributes <UndecoratedTypes.Base>())
            .AddMemberAttributes(c => c.HiddenMethod1(0), CreateTestAttributes <UndecoratedTypes.Base>())
            .AddMemberAttributes(c => c.OverriddenMethod(0, 0), CreateTestAttributes <UndecoratedTypes.Base>())
            .Builder
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.ImplementedMethod1(0, 0), CreateTestAttributes <UndecoratedTypes.Base>())
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.OverloadedMethod(default(int)), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "int"))
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.OverloadedMethod(default(long)), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "long"))
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.m_baseField, CreateTestAttributes(nameof(UndecoratedTypes.Base)))
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.m_hiddenBaseField, CreateTestAttributes(nameof(UndecoratedTypes.Base)))
            .AddMemberAttributes <UndecoratedTypes.Base>(c => UndecoratedTypes.Base.s_baseField, CreateTestAttributes(nameof(UndecoratedTypes.Base)))
            .AddMemberAttributes <UndecoratedTypes.Base>(c => UndecoratedTypes.Base.s_hiddenBaseField, CreateTestAttributes(nameof(UndecoratedTypes.Base)))
            .AddEventAttributes <UndecoratedTypes.Base>(nameof(UndecoratedTypes.Base.StaticBaseEvent), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "_S"))
            .AddEventAttributes <UndecoratedTypes.Base>(nameof(UndecoratedTypes.Base.NonVirtualBaseEvent), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "_V"))
            .AddEventAttributes <UndecoratedTypes.Base>(nameof(UndecoratedTypes.Base.HiddenBaseEvent), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "_H"))
            .AddEventAttributes <UndecoratedTypes.Base>(nameof(UndecoratedTypes.Base.OverriddenEvent), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "_O"))
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.GenericMethod(default(long), default(int)), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "void"))
            .AddParameterAttributes <UndecoratedTypes.Base>(c => c.GenericMethod(Decorate.Parameter <long>(CreateTestAttributes(nameof(UndecoratedTypes.Base) + "long")),
                                                                                 Decorate.Parameter <int>(CreateTestAttributes(nameof(UndecoratedTypes.Base) + "int").AsEnumerable())))
            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.GenericMethod <string>(default(int), default(string)), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "T"))
            .AddParameterAttributes <UndecoratedTypes.Base>(c => c.GenericMethod <string>(Decorate.Parameter <long>(CreateTestAttributes(nameof(UndecoratedTypes.Base) + "long")),
                                                                                          (Decorate.Parameter <string>(CreateTestAttributes(nameof(UndecoratedTypes.Base) + "T")))))
            .AddReturnParameterAttributes <UndecoratedTypes.Base>(c => c.GenericMethod <string>(default(long), default(string)), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "T").ToArray())

            .AddMemberAttributes <UndecoratedTypes.Base>(c => c.GenericMethod <string, string>(default(string), default(string)), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "TU"))
            .AddParameterAttributes <UndecoratedTypes.Base>(c => c.GenericMethod <string, string>(Decorate.Parameter <string>(CreateTestAttributes(nameof(UndecoratedTypes.Base) + "U")),
                                                                                                  Decorate.Parameter <string>(CreateTestAttributes(nameof(UndecoratedTypes.Base) + "T"))))
            .AddReturnParameterAttributes <UndecoratedTypes.Base>(c => c.GenericMethod <string, string>(default(string), default(string)), CreateTestAttributes(nameof(UndecoratedTypes.Base) + "TU").ToArray())
            .AddMemberAttributes(() => UndecoratedTypes.Base.StaticMethod(default(int)), CreateTestAttributes(nameof(UndecoratedTypes.Base)).AsEnumerable())

            .AddTypeAttributes <UndecoratedTypes.Derived>(CreateTestAttributes <UndecoratedTypes.Derived>())
            .AddMemberAttributes <UndecoratedTypes.Derived>(der => der.HiddenProperty, CreateTestAttributes <UndecoratedTypes.Derived>().AsEnumerable())
            .AddMemberAttributes <UndecoratedTypes.Derived>(der => der.OverriddenProperty2, CreateTestAttributes <UndecoratedTypes.Derived>())
            .AddMemberAttributes <UndecoratedTypes.Derived>(c => c.m_derivedField, CreateTestAttributes(nameof(UndecoratedTypes.Derived)))
            .AddMemberAttributes <UndecoratedTypes.Derived>(c => c.m_hiddenBaseField, CreateTestAttributes(nameof(UndecoratedTypes.Derived)))
            .AddMemberAttributes <UndecoratedTypes.Derived>(c => UndecoratedTypes.Derived.s_hiddenBaseField, CreateTestAttributes(nameof(UndecoratedTypes.Derived)))
            .AddEventAttributes <UndecoratedTypes.Derived>(nameof(UndecoratedTypes.Derived.HiddenBaseEvent), CreateTestAttributes(nameof(UndecoratedTypes.Derived)))
            ;

            builder.AddTypeAttributes <UndecoratedTypes.SubDerived>(CreateTestAttributes <UndecoratedTypes.SubDerived>())
            .AddMemberAttributes <UndecoratedTypes.SubDerived>(der => der.OverriddenProperty, CreateTestAttributes <UndecoratedTypes.SubDerived>())
            .AddMemberAttributes <UndecoratedTypes.SubDerived>(der => der.OverriddenProperty2, CreateTestAttributes <UndecoratedTypes.SubDerived>())
            .AddMemberAttributes <UndecoratedTypes.SubDerived>(c => c.OverloadedMethod(default(int)), CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "int"))
            .AddMemberAttributes <UndecoratedTypes.SubDerived>(c => c.OverloadedMethod(default(long)), CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "long"))
            .AddMemberAttributes <UndecoratedTypes.SubDerived>(c => c.OverriddenMethod(0, 0), CreateTestAttributes(nameof(UndecoratedTypes.SubDerived)))
            .ForType <UndecoratedTypes.SubDerived>()
            .AddEventAttributes(nameof(UndecoratedTypes.SubDerived.OverriddenEvent), CreateTestAttributes(nameof(UndecoratedTypes.SubDerived)))
            .AddReturnParameterAttributes(c => c.GenericMethod <string>(default(long), default(string)), CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "T").ToArray())
            .AddParameterAttributes(c => c.GenericMethod(Decorate.Parameter <long>(CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "long")), Decorate.Parameter <int>(CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "int"))))
            ;

            builder.AddParameterAttributes <UndecoratedTypes.SubDerived>(c => c.GenericMethod <object>(default(long), Decorate.Parameter <object>(CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "T"))));
            builder.AddParameterAttributes <UndecoratedTypes.SubDerived>(c => c.GenericMethod <string, string>(Decorate.Parameter <string>(CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "U")),
                                                                                                               Decorate.Parameter <string>(CreateTestAttributes(nameof(UndecoratedTypes.SubDerived) + "T"))))
            ;

            builder.AddTypeAttributes <UndecoratedTypes.GenericDerived>(CreateTestAttributes <UndecoratedTypes.GenericDerived>())
            .AddTypeAttributes(typeof(UndecoratedTypes.GenericDerived <>), CreateTestAttributes("GenericDerived<TType>"))
            ;
            builder.AddMemberAttributes <UndecoratedTypes.GenericDerived <object> >(cls => cls.GenericMethod(null, null), CreateTestAttributes("GenericDerived<TType>"))
            ;
            return(builder.CreateTable());
        }