using System; using System.Collections.Generic; using System.Linq; using Chernobyl.Collections.Generic.Event; using NUnit.Framework; namespace Chernobyl.Dependency { [TestFixture, Description("Tests for the ServiceAttributeExtensions type.")] public class ServiceAttributeExtensionsTests { [Test, Description("A test that ensures the IEventCollection.Inject(T) method " + "sets a property as a service when it is attribute with the Provide " + "attribute. This test also ensures the IEventCollection.GetService(Type) " + "returns the service that was set.")] public void InjectProvideGetServiceTest() { IEventCollection services = CreateServices(); ICollection expectedCollection = new List(); TestServices testServices = new TestServices(); testServices.ProvidedService = expectedCollection; services.Inject(testServices); object collectionService = services.OfType>().First(); Assert.AreEqual(expectedCollection, collectionService, "Unexpected service " + "was retrieved."); } [Test, Description("A test that ensures the IEventCollection.Inject(T) method " + "sets a property with a service when it is attribute with the Inject " + "attribute.")] public void InjectTest() { IEventCollection services = CreateServices(); // Note that we call Inject before we add the service to ensure that // a service is properly injected even if it was added at a later // point in time. TestServices testServices = new TestServices(); services.Inject(testServices); ICollection expectedCollection = new List(); services.Add(expectedCollection); Assert.AreEqual(expectedCollection, testServices.InjectedService, "Unexpected service was retrieved."); } [Test, Description("A test that ensures the IEventCollection.Inject(T) method " + "does not inject/provide services in base classes.")] public void DontInjectBaseClassTest() { IEventCollection services = CreateServices(); ICollection expectedInjectedCollection = new List(); services.Add(expectedInjectedCollection); TestServicesDerived testServices = new TestServicesDerived(); ICollection expectedProvidedCollection = new List(); testServices.ProvidedService2 = expectedProvidedCollection; services.Inject(testServices); Assert.AreEqual(expectedInjectedCollection, testServices.InjectedService2, "Unexpected service was retrieved."); object providedService = services.OfType>().First(); Assert.AreEqual(expectedProvidedCollection, providedService, "Unexpected service was retrieved."); Assert.AreEqual(null, testServices.InjectedService, "The base class's property should not have been set."); object notProvidedService = services.OfType>().FirstOrDefault(); Assert.AreEqual(null, notProvidedService, "The base class's provided service should not have been set."); } [Test, Description("A test that ensures the IEventCollection class can handle " + "the ServiceAttribute.Type property.")] public void ServiceTypeTest() { IEventCollection services = CreateServices(); ICollection expectedInjectCollection = new List(); services.Add(expectedInjectCollection); TestServiceType testServiceType = new TestServiceType(); ICollection expectedProvideCollection = new List(); testServiceType.ProvidedService = expectedProvideCollection; services.Inject(testServiceType); Assert.AreEqual(expectedInjectCollection, testServiceType.InjectedService, "Unexpected service was retrieved."); object enumerableService = services.OfType>().First(); Assert.AreEqual(expectedProvideCollection, enumerableService, "Unexpected service " + "was retrieved."); } [Test, Description("A test that ensures the IEventCollection class can handle " + "the ServiceAttribute.Location property.")] public void ServiceLocationTest() { IEventCollection services = CreateServices(); // Create a child services instance that will contain the service // to be injected. ChildServices childServices = new ChildServices(); services.Add(childServices); GrandchildServices grandchildServices = new GrandchildServices(); childServices.Add(grandchildServices); ICollection expectedInjectService = new List(); grandchildServices.Add(expectedInjectService); // Create the test instance and it's provided services instance that // will be injected into the services class. TestServicePathing servicePathing = new TestServicePathing(); ICollection expectedProvidedService = new List(); servicePathing.ProvidedService = expectedProvidedService; services.Inject(servicePathing); // Ensure the ICollection service was injected. Assert.AreEqual(expectedInjectService, servicePathing.InjectedService, "The injected service was not the service that was expected."); // Ensure the ICollection service was provided object providedService = grandchildServices.OfType>().First(); Assert.AreEqual(expectedProvidedService, providedService, "The provided service was not the service expected."); } /// /// This class is attributed with the and /// attributes to help with testing /// classes. /// public class TestServices { [Provide] public ICollection ProvidedService { get; set; } [Inject] public ICollection InjectedService { get; set; } } /// /// This class is attributed with the and /// attributes to help with testing /// classes. This class is used to ensure the /// does not provide/inject services for base /// classes. /// public class TestServicesDerived : TestServices { [Provide] public ICollection ProvidedService2 { get; set; } [Inject] public ICollection InjectedService2 { get; set; } } /// /// This class is attributed with the and /// attributes to help with testing /// classes. This class is used to ensure the /// handles the /// property. /// public class TestServiceType { [Provide(Type = typeof(IEnumerable))] public ICollection ProvidedService { get; set; } [Inject(Type = typeof(ICollection))] public IEnumerable InjectedService { get; set; } } public class TestServicePathing { [Provide(typeof(ChildServices), typeof(GrandchildServices))] public ICollection ProvidedService { get; set; } [Inject(typeof(ChildServices), typeof(GrandchildServices))] public ICollection InjectedService { get; set; } } public class ChildServices : DecoratingEventList {} public class GrandchildServices : DecoratingEventList {} /// /// Creates the instance to test. This method /// should always return a new instance. The /// must have the number of ancestors /// specified by /// . /// /// The instance to test. protected virtual IEventCollection CreateServices() { IEventCollection grandfather = new DecoratingEventList(); IEventCollection dad = new DecoratingEventList(); IEventCollection services = new DecoratingEventList(); grandfather.Add(dad); dad.Add(services); return services; } } }