protected ICFunc CreateRoutine(string functionName, ICFunc parent = null)
        {
            ICFunc retVal = Substitute.For <ICFunc>();

            retVal.FunctionName.Returns(functionName);
            if (parent != null)
            {
                retVal.HasUpdater.Returns(true);
                retVal.IsUpdatedBy(Arg.Is <object>(parent)).Returns(true);
            }
            return(retVal);
        }
        public void ParentRelationshipIsUpdated()
        {
            ICFunc         routineA = CreateRoutine("A");
            ICFunc         routineB = CreateRoutine("B");
            ITimelineEntry a        = timelineDataUnderTest.Add(routineA);
            ITimelineEntry b        = timelineDataUnderTest.Add(routineB);

            routineB.IsUpdatedBy(Arg.Is <object>(routineA)).Returns(true);
            routineB.HasUpdater.Returns(true);
            Assume.That(b.Parent == null);

            timelineDataUnderTest.Update();

            Assert.AreSame(a, b.Parent);
        }
        public void WhenEntryIsAdded_IEnumeratorContainsExpectedParentChildRelationships(
            [Range(1, 4)] int expectedRootEntries,
            [Range(0, 3)] int expectedChildEntries,
            [Range(0, 2)] int expectedGrandChildEntries
            )
        {
            Dictionary <ITimelineEntry, Dictionary <ITimelineEntry, List <ITimelineEntry> > > dict = new Dictionary <ITimelineEntry, Dictionary <ITimelineEntry, List <ITimelineEntry> > >();

            for (int i = 0; i < expectedRootEntries; i++)
            {
                ICFunc parent    = CreateRoutine("parent" + i);
                var    rootEntry = timelineDataUnderTest.Add(parent);
                dict.Add(rootEntry, new Dictionary <ITimelineEntry, List <ITimelineEntry> >());

                for (int j = 0; j < expectedChildEntries; j++)
                {
                    ICFunc child      = CreateRoutine("child" + j, parent);
                    var    childEntry = timelineDataUnderTest.Add(child);
                    dict[rootEntry].Add(childEntry, new List <ITimelineEntry>());

                    for (int k = 0; k < expectedGrandChildEntries; k++)
                    {
                        ICFunc grandChild = CreateRoutine("grandChild", child);
                        grandChild.HasUpdater.Returns(true);
                        grandChild.IsUpdatedBy(Arg.Is <object>(child)).Returns(true);
                        var grandChildEntry = timelineDataUnderTest.Add(grandChild);
                        dict[rootEntry][childEntry].Add(grandChildEntry);
                    }
                }
            }

            timelineDataUnderTest.Update();

            Assert.AreEqual(expectedRootEntries, timelineDataUnderTest.Count());
            int index = 0;

            foreach (var item in timelineDataUnderTest)
            {
                Assert.Contains(item, ((ICollection)dict.Keys));
                Assert.IsNull(item.Parent);
                Assert.AreEqual(expectedChildEntries, item.Children.Count());

                int childIndex = 0;
                foreach (var child in item.Children)
                {
                    Assert.Contains(child, ((ICollection)dict[item].Keys));
                    Assert.AreSame(item, child.Parent);
                    Assert.AreEqual(expectedGrandChildEntries, child.Children.Count());

                    int grandChildIndex = 0;
                    foreach (var grandChild in child.Children)
                    {
                        Assert.Contains(grandChild, ((ICollection)dict[item][child]));
                        Assert.AreSame(child, grandChild.Parent);
                        Assert.AreEqual(0, grandChild.Children.Count());
                        grandChildIndex++;
                    }
                    childIndex++;
                }
                index++;
            }
        }