using System; using System.Collections.Generic; using System.Linq; using Chernobyl.Values; using NUnit.Framework; namespace Chernobyl.Collections.Generic.Hierarchy { [TestFixture, Description("Tests for the Parent type.")] public class ParentTests : ValueTests, ParentTests.Hierarchy> { //---------------------------------------------------------------------- // Parent(TChild, Func>) Tests //---------------------------------------------------------------------- [Test, Description("Ensures that the Parent(TChild, Func>) " + "throws an ArgumentNullException if the first argument is null")] public void ConstructorChildFuncFirstArgumentNullException() { Assert.Throws(() => new Parent(null, hierarchy => hierarchy.Children)); } [Test, Description("Ensures that the Parent(TChild, Func>) " + "throws an ArgumentNullException if the second argument is null")] public void ConstructorChildFuncSecondArgumentNullException() { Assert.Throws(() => new Parent(new Hierarchy(), null)); } //---------------------------------------------------------------------- // IValue.Value Tests //---------------------------------------------------------------------- [Test, Description("Ensures that the Parent.Value " + "removes the child from the old parent, sets the new parent on the " + "child, and adds the child to the new parent.")] public void ValueHandlesParentingProperly() { Hierarchy oldParent = new Hierarchy(); Hierarchy child = new Hierarchy(oldParent); Hierarchy newParent = new Hierarchy(); child.Parent.Value = newParent; Assert.False(oldParent.Children.Contains(child), "The old parent still contains the child."); Assert.AreEqual(newParent, child.Parent.Value, "The child has not been re-parented to the proper parent."); Assert.True(newParent.Children.Contains(child), "The new parent does not contain the proper child."); } [Test, Description("Ensures that the Parent.Value " + "does not add the child to a parent more than once.")] public void ValueDoesNotAddChildMoreThanOnce() { Hierarchy oldParent = new Hierarchy(); Hierarchy child = new Hierarchy(oldParent); child.Parent.Value = oldParent; Assert.AreEqual(oldParent, child.Parent.Value, "The child has not been parented to the proper parent."); Assert.AreEqual(1, oldParent.Children.Count(hierarchy => hierarchy == child), "The new parent contains the child more than once."); } //---------------------------------------------------------------------- // Ready Tests //---------------------------------------------------------------------- [Test, Description("Ensures IValue.Provide is raised when the " + "IValue{T} is made ready.")] [Ignore("Parent doesn't become ready.")] public override void ProvideRaisedWhenMadeReady() {} [Test, Description("Ensures that event handlers that are added to " + "IValue.Provide are invoked when added to a ready" + "IValue.")] [Ignore("Parent doesn't become ready.")] public override void EventHandlersAddedToReadyValueAreInvokedWhenAdded() {} //---------------------------------------------------------------------- // 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("Parent doesn't become ready.")] public override void ProvideRaisedWhenValueIsNotChangedButIsMadeReady() { } //---------------------------------------------------------------------- // Utility //---------------------------------------------------------------------- protected override ValueTests, Hierarchy>.Wrapper CreateValue() { return new Wrapper(); } protected new class Wrapper : ValueTests, Hierarchy>.Wrapper { public Wrapper() : base(null, new Hierarchy(), new Hierarchy()) { _hierarchy = new Hierarchy(ReadyValue); TestInstance = _hierarchy.Parent; } public override void MakeReady() { // Not needed. Parent doesn't become ready. } public override void ChangeValue() { _hierarchy.Parent.Value = FinalValue; } public override void FakeChangeValue() { _hierarchy.Parent.Value = ReadyValue; } Hierarchy _hierarchy; } /// /// A class that is used to test parent/child relationships. /// public class Hierarchy { public Hierarchy() : this(null) { } public Hierarchy(Hierarchy parent) { Parent = new Parent(this, hierarchy => hierarchy.Children); Children = new Children(this, hierarchy => hierarchy.Parent); Parent.Value = parent; } public Parent Parent { get; private set; } public Children Children { get; private set; } } } }