using System; using System.Collections.Generic; using System.Linq; using System.Utility; using NUnit.Framework; namespace Chernobyl.Values { /// /// Tests for the type. /// public class CompositeTests : ValueTests, IEnumerable> { [Test, Description("Ensures the Composite throws an ArgumentNullException " + "when given a null constructor argument.")] public virtual void ConstructorArgumentNullException() { Assert.Throws(() => CreateComposite(null)); } [Test, Description("Ensures the Composite reports properly handles " + "cases where there are several items.")] public virtual void SeveralItemsTest() { var containers = new[] { new DynamicContainer(Strings[0]), new DynamicContainer(Strings[1]) }; Composite composite = CreateComposite(containers); composite.Provide += (sender, args) => { // Check the number of items. args.NewValue.Count().IsEqualTo(containers.Length, "Composite count"); // Check each of the values. for (int i = 0; i < containers.Length; i++) { args.NewValue.ElementAt(i).IsEqualTo(containers[i].Value, "Composite " + "item at index " + i); } Assert.Pass(); }; Assert.Fail("The IValue.Provide event on Composite was not raised."); } [Test, Description("Ensures the Composite reports properly handles " + "cases where there are several items.")] public virtual void NoItemsTest() { Composite composite = CreateComposite(Enumerable.Empty>()); composite.Provide += (sender, args) => { // Check the number of items. args.NewValue.Count().IsEqualTo(0, "Composite count"); Assert.Pass(); }; Assert.Fail("The IValue.Provide event on Composite was not raised."); } //---------------------------------------------------------------------- // Change Tests //---------------------------------------------------------------------- [Test, Description("A test to ensure that setting the internal value of " + "IValue to the value it is already set at raises the " + "IValue.Provide event if the IValue is not ready. " + "Override this test if it is not applicable.")] [Ignore("Test not required since Composite is only made ready when " + "all IValue instance's it holds are made ready.")] public override void ProvideRaisedWhenValueIsNotChangedButIsMadeReady() {} //---------------------------------------------------------------------- // Utility //---------------------------------------------------------------------- /// /// Creates a new instance of the type to be tested. /// /// The instance to be given to the constructor. /// /// The instance to be tested. /// protected virtual Composite CreateComposite(IEnumerable> values) { return new Composite(values); } protected override Wrapper CreateValue() { var containers = new[] { new DynamicContainer(ReadyValue[0]), // Set the second value to null so that we can later make it // ready by setting it to non-null. new DynamicContainer(null) }; return new CompositeWrapper( CreateComposite(new[] { containers[0], containers[1].NotNull() }), containers, ReadyValue, FinalValue); } /// /// Strings used for testing purposes. /// protected static readonly string[] Strings = { "Apple", "Pear", "Grape" }; protected static readonly string[] ReadyValue = { Strings[0], null }; protected static readonly string[] FinalValue = { Strings[2], Strings[1] }; class CompositeWrapper : Wrapper { public CompositeWrapper(Composite testInstance, IEnumerable> containers, IEnumerable readyValue, IEnumerable finalValue) : base(testInstance, readyValue, finalValue) { _containers = containers; } public override void MakeReady() { // Changing the second container from null to non-null will make // the type ready. Note that we use the "FinalValue" here. This // is because ChangeValue only changes one of the values. The // check that verifies the value assumes both have become the // FinalValue. _containers.ElementAt(1).Value = FinalValue.ElementAt(1); } public override void ChangeValue() { _containers.First().Value = Strings[2]; } public override void FakeChangeValue() { _containers.First().Value = _containers.First().Value; } IEnumerable> _containers; } } }