using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; namespace Chernobyl.Reflection.Template { /// <summary> /// A helper base testing class for testing types that implement the /// <see cref="IInstance"/> interface. /// /// Note to implementors: the <see cref="INamed"/> instance created by the /// <see cref="NamedTests.CreateNamed"/> method must be named "test_name" /// so that the <see cref="NamedTests.NameIsExpected"/> test method may pass. /// </summary> public abstract class InstanceTests : ComponentTests { [Test, Description("Tests the IInstance to see if it can contain an " + "IComponent that is a constructor.")] public void InstanceWithConstructorTest() { IInstance instance = CreateInstanceWithConstructor(); IMember constructor = instance.ComponentChildren.OfType<IMember>().First(); Assert.IsNotNull(constructor, "A constructor was not created"); } [Test, Description("Tests the IInstance to see if it can contain an " + "IComponent that is a method.")] public void InstanceWithMethodTest() { IInstance instance = CreateInstanceWithMethod(); IMember method = instance.ComponentChildren.OfType<IMember>().First(); Assert.IsNotNull(method, "A method was not created"); } [Test, Description("Tests the IInstance to see if it can contain an " + "IComponent that is a property.")] public void InstanceWithPropertyTest() { IInstance instance = CreateInstanceWithProperty(); IMember property = instance.ComponentChildren.OfType<IMember>().First(); Assert.IsNotNull(property, "A property was not created"); } [Test, Description("Tests the IInstance to see if it can contain an " + "IComponent that is a field.")] public void InstanceWithFieldTest() { IInstance instance = CreateInstanceWithField(); IMember field = instance.ComponentChildren.OfType<IMember>().First(); Assert.IsNotNull(field, "A property was not created"); } [Test, Description("Tests the IInstance to see if it can contain an " + "IComponent that is a event.")] public void InstanceWithEventTest() { IInstance instance = CreateInstanceWithEvent(); IMember eventMember = instance.ComponentChildren.OfType<IMember>().First(); Assert.IsNotNull(eventMember, "An eventMember was not created"); } [Test, Description("Tests to see if the instance return by " + "CreateLinkedInstance() is equal to the instance created by " + "CreateLinkedToInstance().")] public void LinkedInstanceTest() { IInstance linkedInstance = CreateLinkedInstance(); IInstance actualLinkedToInstance = CreateLinkedToInstance(); Assert.AreEqual(actualLinkedToInstance.TheInstance, linkedInstance.TheInstance); } [Test, Description("Tests to see if the instance return by " + "CreateTypedInstance() is an instance of type " + "KeyValuePair<Int32, ArrayList>.")] public void TypedInstanceTest() { IInstance instance = CreateTypedInstance(); Assert.AreEqual(typeof(Dictionary<Int32, Nullable<Single>>), instance.Type); } /// <summary> /// Creates an <see cref="IInstance"/> that contains an /// <see cref="IComponent"/> that has a constructor. This method should /// not return the same <see cref="IInstance"/> more than once. /// </summary> /// <returns>The IInstance to be tested.</returns> protected abstract IInstance CreateInstanceWithConstructor(); /// <summary> /// Creates an <see cref="IInstance"/> that contains an /// <see cref="IComponent"/> that has a method. This method should not /// return the same <see cref="IInstance"/> more than once. /// </summary> /// <returns>The IInstance to be tested.</returns> protected abstract IInstance CreateInstanceWithMethod(); /// <summary> /// Creates an <see cref="IInstance"/> that contains an /// <see cref="IComponent"/> that has a property. This method should not /// return the same <see cref="IInstance"/> more than once. /// </summary> /// <returns>The IInstance to be tested.</returns> protected abstract IInstance CreateInstanceWithProperty(); /// <summary> /// Creates an <see cref="IInstance"/> that contains an /// <see cref="IComponent"/> that has a field. This method should not /// return the same <see cref="IInstance"/> more than once. /// </summary> /// <returns>The IInstance to be tested.</returns> protected abstract IInstance CreateInstanceWithField(); /// <summary> /// Creates an <see cref="IInstance"/> that contains an /// <see cref="IComponent"/> that has a event. This method should not /// return the same <see cref="IInstance"/> more than once. /// </summary> /// <returns>The IInstance to be tested.</returns> protected abstract IInstance CreateInstanceWithEvent(); /// <summary> /// Creates an <see cref="IInstance"/> that is to be tested to ensure it /// properly links to the <see cref="IInstance"/> created by /// <see cref="CreateLinkedToInstance"/>. This method will always create /// a new <see cref="IInstance"/> and never return the same instance /// twice. The <see cref="IInstance"/> created should have a name that /// is different from the <see cref="IInstance"/> created by /// <see cref="CreateLinkedToInstance"/>. /// </summary> /// <returns>The instance that is to be tested.</returns> protected abstract IInstance CreateLinkedInstance(); /// <summary> /// Creates an <see cref="IInstance"/> that is to be tested to ensure /// it properly links from the <see cref="IInstance"/> created by /// <see cref="CreateLinkedInstance"/>. This method will always create /// a new <see cref="IInstance"/> and never return the same instance /// twice. /// </summary> /// <returns>The instance that is to be tested.</returns> protected abstract IInstance CreateLinkedToInstance(); /// <summary> /// Creates an <see cref="IInstance"/> that is to be tested to ensure /// it is of type <see cref="Dictionary{TKey,TValue}"/> where the /// key type is of <see cref="int"/> and the value type is of /// <see cref="Nullable{T}"/>. The <see cref="Nullable{T}"/>'s type /// parameter should be of type <see cref="Single"/>. This method will /// always create a new <see cref="IInstance"/> and never return the /// same instance twice. /// </summary> /// <returns>The instance that is to be tested.</returns> protected abstract IInstance CreateTypedInstance(); /// <summary> /// The name that is expected by the /// <see cref="NamedTests.NameIsExpected()"/> test method. If the value /// returned is an empty string, then the test is ignored. /// </summary> protected override string ExpectedName { get { return "test_name"; } } } /// <summary> /// A type used to test some functionality of <see cref="IInstance"/>s. /// </summary> public class TestType { public TestType() { } public TestType(string y) : this(0.0f, y) { } public TestType(float x, string y) { X = x; Y = y; } public event EventHandler SomeEvent; public void SomeEventHandler(object sender, EventArgs e) { X = 0; } public float X; public void SetChild(TestType child) { Child = child; } public TestType Child { get { return ChildField; } set { ChildField = value; } } public TestType ChildField; public string Y { get; set; } public int SomeProperty { get; set; } public void SomeMethod(float x) { X = x; if (SomeEvent != null) SomeEvent(this, EventArgs.Empty); } } }