using System; using System.Linq; using System.Utility; using Chernobyl.Attribution; using Chernobyl.Collections.Generic.Event; using Chernobyl.Reflection; using Chernobyl.Values; using NUnit.Framework; namespace Chernobyl.Dependency { public abstract class GetAttributeTests { [Test, Description("ParameterException is thrown when more than one " + "IStorageAttribute is specified on a parameter.")] public virtual void ParameterExceptionWhenMultipleIStorageAttributeOnParameter() { Assert.Throws(() => GetFirstParameter(MultiStorageMethod)); } [Test, Description("ParameterException is thrown when no IKeyAttributes is " + "specified on a parameter.")] public virtual void ParameterExceptionWhenNoIKeyAttributeOnParameter() { Assert.Throws(() => GetFirstParameter(NoKeyMethod)); } [Test, Description("ParameterException is thrown when more than one " + "IKeyAttributes is specified on a parameter.")] public virtual void ParameterExceptionWhenMoreThanOneIKeyAttributeOnParameter() { Assert.Throws(() => GetFirstParameter(MultiKeyMethod)); } [Test, Description("Parameter is received when immediately provided.")] public virtual void ParameterProvidedImmediately() { const string expected = "Bob"; var expectedValue = new BasicContainer(expected); StaticStorageAttribute.Default.Container.Remove(FirstNameId); StaticStorageAttribute.Default.Container.Add(FirstNameId, expectedValue); var value = GetFirstParameter(SingleParameterMethod); value.Request((sender, args) => { args.NewValue.Require().IsEqualTo(expected, "first parameter"); Assert.Pass(); }); Assert.Fail("Value was not received"); } [Test, Description("Parameter is received when late provided.")] public virtual void ParameterProvidedLate() { const string expected = "Bob"; var expectedValue = new DynamicContainer(); StaticStorageAttribute.Default.Container.Remove(FirstNameId); StaticStorageAttribute.Default.Container.Add(FirstNameId, expectedValue.NotNull()); var value = GetFirstParameter(SingleParameterMethod); var valueSet = new DynamicContainer(false); value.Request((sender, args) => { args.NewValue.Require().IsEqualTo(expected, "first parameter"); Assert.True(valueSet.Value, "Value should not have been received yet."); Assert.Pass(); }); valueSet.Value = true; expectedValue.Value = expected; Assert.Fail("Value was not retrieved"); } #region Utilty /// /// The name of the method. /// public const string MultiStorageMethod = "MultiStorage"; public void MultiStorage([Get, StaticStorage, StorageAttribute, Guid(SetAttributeTests.Ids.Hello)]string param) { } /// /// The name of the method. /// public const string NoKeyMethod = "NoKey"; public void NoKey([Get]string param) { } /// /// The name of the method. /// public const string MultiKeyMethod = "MultiKey"; public void MultiKey([Get, Guid(SetAttributeTests.Ids.FirstName), Guid(SetAttributeTests.Ids.Hello)]string param) { } /// /// The name of the method. /// public const string SingleParameterMethod = "SingleParameter"; public void SingleParameter([Get, Guid(SetAttributeTests.Ids.FirstName)] string param) {} /// /// Utility method to help with testing. Creates the tested instance /// using and then uses it and the /// specified method to get the parameter value. /// /// The name of the method whose first parameter is /// to be retrieved. /// The parameter requested. IValue GetFirstParameter(string method) { var get = CreateGetAttribute(); var methodInfo = GetType().GetMethod(method); return get.Get(methodInfo.GetParameters().First()); } /// /// A used for testing /// purposes. /// public class StorageAttribute : Attribute, IStorageAttribute> { /// /// The container the instance(s) are to be stored. /// public IEventDictionary> Container { get { return StaticContainer; } } /// /// The backing field to . /// static readonly IEventDictionary> StaticContainer = new DecoratingEventDictionary>(); } static readonly Guid FirstNameId = new Guid(SetAttributeTests.Ids.FirstName); #endregion #region Overridables /// /// Returns the instance to be tested. /// /// The instance to be tested. public abstract IGetAttribute CreateGetAttribute(); #endregion } }