Mercurial > pub > bltoolkit
diff UnitTests/CS/Reflection/TypeHelperTest.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UnitTests/CS/Reflection/TypeHelperTest.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,239 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; + +using NUnit.Framework; + +using BLToolkit.Reflection; +using BLToolkit.EditableObjects; + +namespace Reflection +{ + [TestFixture] + public class TypeHelperTest + { + public class Attribute1 : Attribute {} + public class Attribute2 : Attribute {} + public class Attribute3 : Attribute {} + public class Attribute4 : Attribute {} + + public class Attribute5 : Attribute2 + { + public Attribute5(int n) + { + _n = n; + } + + int _n; + + public override string ToString() + { + return base.ToString() + ":" + _n; + } + } + + [Attribute1] + [Attribute5(2)] + public interface IBase1 + { + void Method1(); + } + + [Attribute5(1)] + public interface IBase2 + { + void Method2(); + } + + [Attribute2] + [Attribute5(0)] + public class Base : IBase1, IBase2 + { + public void Method1() {} + public void Method2() {} + } + + [Attribute3] + public interface IObject1 : IBase1 + { + } + + [Attribute4] + public interface IObject2 : IBase1, IBase2 + { + } + + [Attribute5(2)] + public class TestObject : Base, IObject2, IObject1, IBase2 + { + public new void Method2() {} + } + + public struct TestStruct<T,V> + { + public T _t; + public V _v; + } + + public class TestObject<T> : TestObject + { + public T Method2(T value) + { + return value; + } + + public V Method2<V>() + { + return default(V); + } + + public V Method3<V>(V value) + where V : IConvertible, IFormattable, new() + { + return value; + } + + public V Method3<V>(Nullable<V> value) + where V : struct, IFormattable + { + return value.Value; + } + + public V Method3<V, Q>(TestStruct<Nullable<V>, Q> value) + where V : struct + where Q : IFormattable + { + return default(V); + } + + public V Method4<V, Q>(TestStruct<V, Q> value) + { + return default(V); + } + } + + [Test] + public void GetAttributes() + { + object[] attrs = new TypeHelper(typeof(TestObject)).GetAttributes(); + + for (int i = 0; i < attrs.Length; i++) + { + object attr = attrs[i]; + Console.WriteLine("{0}: {1} {2}", i, attr, attr.GetHashCode()); + } + + Assert.AreEqual(typeof(Attribute5), attrs[0].GetType()); + Assert.AreEqual(typeof(Attribute5), attrs[1].GetType()); + Assert.AreEqual(typeof(Attribute4), attrs[2].GetType()); + Assert.AreEqual(typeof(Attribute3), attrs[3].GetType()); + + Assert.IsTrue( + typeof(Attribute2) == attrs[4].GetType() && typeof(Attribute5) == attrs[5].GetType() || + typeof(Attribute2) == attrs[5].GetType() && typeof(Attribute5) == attrs[4].GetType()); + + Assert.IsTrue( + typeof(Attribute1) == attrs[6].GetType() && typeof(Attribute5) == attrs[7].GetType() || + typeof(Attribute1) == attrs[7].GetType() && typeof(Attribute5) == attrs[6].GetType()); + + Assert.AreEqual(typeof(Attribute5), attrs[8].GetType()); + } + + [Test] + public void GetAttributes_ByType() + { + object[] attrs = new TypeHelper(typeof(TestObject)).GetAttributes(typeof(Attribute2)); + + foreach (object attr in attrs) + Console.WriteLine("{0} {1}", attr, attr.GetHashCode()); + + Assert.AreEqual(typeof(Attribute5), attrs[0].GetType()); + Assert.AreEqual(typeof(Attribute5), attrs[1].GetType()); + + Assert.IsTrue( + typeof(Attribute2) == attrs[2].GetType() && typeof(Attribute5) == attrs[3].GetType() || + typeof(Attribute2) == attrs[3].GetType() && typeof(Attribute5) == attrs[2].GetType()); + } + + [Test] + public void UnderlyingTypeTest() + { + Type type; + + type = TypeHelper.GetUnderlyingType(typeof(int?)); + Assert.AreEqual(typeof(int), type); + + type = TypeHelper.GetUnderlyingType(typeof(DayOfWeek?)); + Assert.AreEqual(typeof(int), type); + + type = TypeHelper.GetUnderlyingType(typeof(IComparable<int>)); + Assert.AreEqual(typeof(IComparable<int>), type); + + } + + [Test] + public void GenericsTest() + { + Type testType = typeof (TestObject<int>); + TypeHelper helper = new TypeHelper(testType); + + Assert.IsNotNull(helper.GetMethod(true, "Method2")); // Generic + Assert.IsNotNull(helper.GetMethod(false, "Method2")); // Non-generic + + // TestObject<T>.Method2<V>() is a generic method + Assert.IsNotNull(helper.GetMethod(true, "Method2", Type.EmptyTypes)); + // TestObject.Method2() is not + Assert.IsNotNull(helper.GetMethod(false, "Method2", Type.EmptyTypes)); + // TestObject<T>.Method2(T value) is neither! + Assert.IsNotNull(helper.GetMethod(false, "Method2", testType.GetGenericArguments()[0])); + // typeof(int) is same as testType.GetGenericArguments()[0] + Assert.IsNotNull(helper.GetMethod(false, "Method2", typeof(int))); + // Get TestObject<T>.Method3<V>() with constraint type hack + Assert.IsNotNull(helper.GetMethod(true, "Method3", typeof(int))); + // Get TestObject<T>.Method3<V>() with constraint violation will fail. + Assert.IsNull (helper.GetMethod(true, "Method3", typeof(object))); + // Get TestObject<T>.Method3<V>() with no types will fail + Assert.IsNull (helper.GetMethod(true, "Method3", Type.EmptyTypes)); + // Nullable<> violates IFormattable constraint + Assert.IsNull (helper.GetMethod(true, "Method3", typeof(Nullable<>))); + // Method4 does not define a costraint + Assert.IsNotNull(helper.GetMethod(true, "Method4", typeof(TestStruct<,>))); + + Assert.IsNotNull(helper.GetMethod(true, "Method3", typeof(Nullable<int>))); + Assert.IsNotNull(helper.GetMethod(true, "Method3", typeof(TestStruct<Nullable<int>, int>))); + Assert.IsNull (helper.GetMethod(true, "Method3", typeof(TestStruct<Nullable<int>, object>))); + Assert.IsNull (helper.GetMethod(true, "Method3", typeof(TestStruct<int, int>))); + + Assert.AreEqual (15, helper.GetMethods( ).Length); // 15 total + Assert.AreEqual (5, helper.GetMethods(true ).Length); // 5 generic + Assert.AreEqual (10, helper.GetMethods(false).Length); // 10 non-generics + + } + + [Test, ExpectedException(typeof(AmbiguousMatchException))] + public void GenericsAmbiguousMatchTest() + { + // There are more then one Method2 in the TestObject<T> class + new TypeHelper(typeof (TestObject<int>)).GetMethod("Method2"); + } + + public class MyArrayList : ArrayList + { + public new TestObject this[int i] + { + get { return (TestObject)base[i]; } + } + } + + [Test] + public void GetListItemType() + { + Assert.AreEqual(typeof(TestObject), TypeHelper.GetListItemType(new EditableArrayList(typeof(TestObject)))); + Assert.AreEqual(typeof(TestObject), TypeHelper.GetListItemType(new TestObject[0])); + Assert.AreEqual(typeof(TestObject), TypeHelper.GetListItemType(new MyArrayList())); + Assert.AreEqual(typeof(TestObject), TypeHelper.GetListItemType(new List<TestObject>())); + } + } +} +