Пример #1
0
        public IEnumerator OtherPropertyLockedAfterManualUnlockFinished()
        {
            // Given a scene object with two independent lockable properties which are not referenced by any condition.
            ISceneObject         o1        = TestingUtils.CreateSceneObject("o1");
            LockablePropertyMock property  = o1.GameObject.AddComponent <LockablePropertyMock>();
            LockablePropertyMock property2 = o1.GameObject.AddComponent <LockablePropertyMock>();

            EndlessConditionMock condition = new EndlessConditionMock();

            Step step2 = new BasicStepBuilder("step").AddCondition(new EndlessConditionMock()).Build();
            Step step  = new BasicStepBuilder("step").AddCondition(condition).Build();

            step.Data.Transitions.Data.Transitions[0].Data.TargetStep = step2;

            property.SetLocked(true);
            property2.SetLocked(true);

            // When we manually unlock one property for one step.
            LockHandling.Unlock(step.Data, new List <LockablePropertyData>());
            step.Data.Transitions.Data.Transitions.First().Autocomplete();
            step.Data.Transitions.Data.Transitions.First().Data.IsCompleted = true;
            LockHandling.Lock(step.Data, new List <LockablePropertyData> {
                new LockablePropertyData(property)
            });

            // Then the other property stays locked after the step was completed.
            Assert.IsTrue(property2.IsLocked);

            yield return(null);
        }
        public IEnumerator GameObjectIsEnabledAfterActivation()
        {
            // Given an active training scene object and a training with enable game object behavior,
            TrainingSceneObject toEnable = TestingUtils.CreateSceneObject("toEnable");

            toEnable.GameObject.SetActive(false);

            EndlessConditionMock trigger = new EndlessConditionMock();

            ICourse course = new LinearTrainingBuilder("Training")
                             .AddChapter(new LinearChapterBuilder("Chapter")
                                         .AddStep(new BasicCourseStepBuilder("Step")
                                                  .Enable(toEnable)
                                                  .AddCondition(trigger)))
                             .Build();

            course.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            CourseRunner.Initialize(course);
            CourseRunner.Run();

            // When the behavior is activated
            CourseRunner.Initialize(course);
            CourseRunner.Run();

            yield return(new WaitUntil(() => course.Data.FirstChapter.Data.Steps[0].LifeCycle.Stage == Stage.Active));

            // Then the training scene object is enabled.
            Assert.True(toEnable.GameObject.activeSelf);

            // Cleanup
            TestingUtils.DestroySceneObject(toEnable);

            yield break;
        }
Пример #3
0
        public IEnumerator FastForwardActive()
        {
            // Given a step,
            IBehavior  behavior   = new EndlessBehaviorMock();
            ICondition condition  = new EndlessConditionMock();
            Transition transition = new Transition();
            IStep      step       = new Step("Step");

            transition.Data.Conditions.Add(condition);
            step.Data.Behaviors.Data.Behaviors.Add(behavior);
            step.Data.Transitions.Data.Transitions.Add(transition);
            step.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            step.LifeCycle.Activate();

            // When you fast-forward it,
            step.LifeCycle.MarkToFastForward();

            // Then everything is completed.
            Assert.AreEqual(Stage.Active, step.LifeCycle.Stage);
            Assert.AreEqual(Stage.Active, behavior.LifeCycle.Stage);
            Assert.AreEqual(Stage.Active, condition.LifeCycle.Stage);

            yield break;
        }
Пример #4
0
        public IEnumerator UnlockedAfterManualUnlockStarted()
        {
            // Given a scene object with a lockable property which is not referenced by any condition.
            ISceneObject         o1       = TestingUtils.CreateSceneObject("o1");
            LockablePropertyMock property = o1.GameObject.AddComponent <LockablePropertyMock>();

            EndlessConditionMock condition = new EndlessConditionMock();

            Step step2 = new BasicStepBuilder("step").AddCondition(new EndlessConditionMock()).Build();
            Step step  = new BasicStepBuilder("step").AddCondition(condition).Build();

            step.Data.Transitions.Data.Transitions[0].Data.TargetStep = step2;

            property.SetLocked(true);

            // When we include the property into the manualUnlocked list of the UnlockPropertiesForStepData method.
            LockHandling.Unlock(step.Data, new List <LockablePropertyData> {
                new LockablePropertyData(property)
            });

            // Then the property is not locked.
            Assert.IsFalse(property.IsLocked);

            yield return(null);
        }
Пример #5
0
        public IEnumerator ActivateTest()
        {
            // Setup Step with event listener for checking states.
            Step step = new Step("Step1");
            EndlessConditionMock conditionMock = new EndlessConditionMock(); // add condition to prevent step from auto-completing on activation

            Transition transition = new Transition();

            transition.Data.Conditions.Add(conditionMock);
            step.Data.Transitions.Data.Transitions.Add(transition);
            step.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            // Activate should work on simple steps.
            step.LifeCycle.Activate();

            while (step.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                step.Update();
            }

            // Chapter should be active now.
            Assert.AreEqual(Stage.Active, step.LifeCycle.Stage, "Step was not activated");
        }
Пример #6
0
        public IEnumerator StepWithInitiallyCompletedConditionResetsCondition()
        {
            // Given a step with an already completed condition,
            Step       step      = new Step("Step1");
            ICondition condition = new EndlessConditionMock();

            condition.Autocomplete();
            Transition transition = new Transition();

            transition.Data.Conditions.Add(condition);
            step.Data.Transitions.Data.Transitions.Add(transition);
            step.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            // When it is activated,
            step.LifeCycle.Activate();

            while (condition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                step.Update();
            }

            // Then the condition is reset to not completed.
            Assert.IsFalse(condition.IsCompleted);

            yield return(null);
        }
Пример #7
0
        public IEnumerator ConditionsActivateOnlyAfterBehaviors()
        {
            Step step = new Step("Step1");
            EndlessConditionMock conditionMock = new EndlessConditionMock();
            EndlessBehaviorMock  behaviorMock  = new EndlessBehaviorMock();
            Transition           transition    = new Transition();

            transition.Data.Conditions.Add(conditionMock);
            step.Data.Transitions.Data.Transitions.Add(transition);
            step.Data.Behaviors.Data.Behaviors.Add(behaviorMock);
            step.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            step.LifeCycle.Activate();

            while (behaviorMock.LifeCycle.Stage != Stage.Activating)
            {
                Assert.AreEqual(Stage.Activating, step.LifeCycle.Stage);
                Assert.AreEqual(Stage.Inactive, conditionMock.LifeCycle.Stage);
                yield return(null);

                step.Update();
            }

            behaviorMock.LifeCycle.MarkToFastForwardStage(Stage.Activating);

            while (conditionMock.LifeCycle.Stage != Stage.Active)
            {
                Assert.AreEqual(Stage.Activating, step.LifeCycle.Stage);
                yield return(null);

                step.Update();
            }
        }
        public IEnumerator GameObjectStaysDisabled()
        {
            // Given an active training scene object and a training course with disable game object behavior,
            TrainingSceneObject  toDisable = TestingUtils.CreateSceneObject("ToDisable");
            EndlessConditionMock trigger   = new EndlessConditionMock();

            ICourse course = new LinearTrainingBuilder("Course")
                             .AddChapter(new LinearChapterBuilder("Chapter")
                                         .AddStep(new BasicCourseStepBuilder("Step")
                                                  .Disable(toDisable))
                                         .AddStep(new BasicCourseStepBuilder("Step")
                                                  .AddCondition(trigger)))
                             .Build();

            course.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            // When the behavior is activated and after the step is completed
            CourseRunner.Initialize(course);
            CourseRunner.Run();

            yield return(new WaitUntil(() => course.Data.FirstChapter.Data.Steps[1].LifeCycle.Stage == Stage.Active));

            trigger.Autocomplete();

            yield return(new WaitUntil(() => course.Data.FirstChapter.Data.Steps[1].LifeCycle.Stage == Stage.Inactive));

            // Then the training scene object stays disabled.
            Assert.False(toDisable.GameObject.activeSelf);

            // Cleanup.
            TestingUtils.DestroySceneObject(toDisable);

            yield break;
        }
Пример #9
0
        public IEnumerator InactiveConditionDoesntPreventCompletion()
        {
            EndlessConditionMock notOptional = new EndlessConditionMock();

            // Given an activating transition with a condition,
            Transition transition = new Transition();

            transition.Data.Conditions.Add(new OptionalEndlessConditionMock());
            transition.Data.Conditions.Add(notOptional);
            transition.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            transition.LifeCycle.Activate();

            while (transition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                transition.Update();
            }

            // When the condition is skipped and the second condition is completed,
            transition.Configure(new Mode("Test", new WhitelistTypeRule <IOptional>().Add <OptionalEndlessConditionMock>()));

            notOptional.Autocomplete();

            yield return(null);

            transition.Update();

            // Then the transition is completed.
            Assert.IsTrue(transition.IsCompleted);

            yield break;
        }
Пример #10
0
        public IEnumerator FastForwardBranchingChapter()
        {
            // Given a chapter with a step branching to three transitions,
            Step                 branchingStep       = new Step("Branching Step");
            Chapter              chapter             = new Chapter("Chapter", branchingStep);
            Transition           firstTransition     = new Transition();
            Transition           secondTransition    = new Transition();
            Transition           thirdTransition     = new Transition();
            EndlessConditionMock firstConditionMock  = new EndlessConditionMock();
            EndlessConditionMock secondConditionMock = new EndlessConditionMock();
            EndlessConditionMock thirdConditionMock  = new EndlessConditionMock();

            firstTransition.Data.Conditions.Add(firstConditionMock);
            secondTransition.Data.Conditions.Add(secondConditionMock);
            thirdTransition.Data.Conditions.Add(thirdConditionMock);
            branchingStep.Data.Transitions.Data.Transitions.Add(firstTransition);
            branchingStep.Data.Transitions.Data.Transitions.Add(secondTransition);
            branchingStep.Data.Transitions.Data.Transitions.Add(thirdTransition);

            chapter.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);
            chapter.LifeCycle.Activate();

            yield return(null);

            chapter.Update();

            // When it's marked to be fast-forwarded,
            chapter.LifeCycle.MarkToFastForward();

            // Then only the first transition completes.
            Assert.IsTrue(firstTransition.IsCompleted);
            Assert.IsFalse(secondTransition.IsCompleted);
            Assert.IsFalse(thirdTransition.IsCompleted);
        }
Пример #11
0
        public IEnumerator StepWithCondition()
        {
            Step step = new Step("Step1");
            EndlessConditionMock conditionMock = new EndlessConditionMock();
            Transition           transition    = new Transition();

            transition.Data.Conditions.Add(conditionMock);
            step.Data.Transitions.Data.Transitions.Add(transition);
            step.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            step.LifeCycle.Activate();

            while (step.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                step.Update();
            }

            Stage stepInitialStage              = step.LifeCycle.Stage;
            Stage conditionInitialStage         = conditionMock.LifeCycle.Stage;
            bool  conditionIsCompletedInitially = conditionMock.IsCompleted;

            conditionMock.Autocomplete();

            bool conditionIsCompleted = conditionMock.IsCompleted;

            step.LifeCycle.Deactivate();

            while (step.LifeCycle.Stage != Stage.Inactive)
            {
                yield return(null);

                step.Update();
            }

            Stage stepStageInEnd            = step.LifeCycle.Stage;
            Stage conditionStageInEnd       = conditionMock.LifeCycle.Stage;
            bool  conditionIsCompletedInEnd = conditionMock.IsCompleted;

            // Check states were correct
            Assert.AreEqual(Stage.Active, stepInitialStage, "Step should be active initially");
            Assert.AreEqual(Stage.Active, conditionInitialStage, "Condition should be active initially");
            Assert.IsFalse(conditionIsCompletedInitially, "Condition should not completed initially");

            Assert.IsTrue(conditionIsCompleted, "Condition should be completed now");

            Assert.AreEqual(Stage.Inactive, stepStageInEnd, "Step should be inactive in the end");
            Assert.AreEqual(Stage.Inactive, conditionStageInEnd, "Condition should not be active in the end");
            Assert.IsTrue(conditionIsCompletedInEnd, "Condition should be completed in the end");

            yield return(null);
        }
Пример #12
0
        public IEnumerator FastForwardLoopingChapter()
        {
            // Given a chapter with a looping step,
            Step       loopingStep       = new Step("Looping Step");
            Chapter    chapter           = new Chapter("Chapter", loopingStep);
            Transition loopingTransition = new Transition();

            loopingTransition.Data.TargetStep = loopingStep;
            Transition           endTransition = new Transition();
            EndlessConditionMock conditionMock = new EndlessConditionMock();

            endTransition.Data.Conditions.Add(conditionMock);
            loopingStep.Data.Transitions.Data.Transitions.Add(loopingTransition);
            loopingStep.Data.Transitions.Data.Transitions.Add(endTransition);

            chapter.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);
            chapter.LifeCycle.Activate();

            int loops = 0;

            while (loops < 2)
            {
                while (loopingStep.LifeCycle.Stage != Stage.Active)
                {
                    Assert.AreEqual(Stage.Activating, chapter.LifeCycle.Stage);
                    yield return(null);

                    chapter.Update();
                }


                while (loopingStep.LifeCycle.Stage != Stage.Inactive)
                {
                    Assert.AreEqual(Stage.Activating, chapter.LifeCycle.Stage);
                    yield return(null);

                    chapter.Update();
                }

                loops++;
            }

            // When it's marked to be fast-forwarded,
            chapter.LifeCycle.MarkToFastForward();

            // Then it completes.
            Assert.AreEqual(Stage.Active, chapter.LifeCycle.Stage);
            Assert.AreEqual(Stage.Inactive, loopingStep.LifeCycle.Stage);
        }
Пример #13
0
        public static TestLinearChapterBuilder SetupChapterBuilder(int steps = 3, bool addTriggerConditions = true)
        {
            TestLinearChapterBuilder builder = new TestLinearChapterBuilder("Chapter1");

            for (int i = 0; i < steps; i++)
            {
                builder.AddStep("Step" + (i + 1));
                if (addTriggerConditions)
                {
                    EndlessConditionMock conditionMock = new EndlessConditionMock();
                    builder.Steps[i].Data.Transitions.Data.Transitions.First().Data.Conditions.Add(conditionMock);
                    builder.StepTriggerConditions.Add(conditionMock);
                }
            }
            return(builder);
        }
Пример #14
0
        public IEnumerator MultiConditionTransitionFinishes()
        {
            // Given a transition with two conditions,
            EndlessConditionMock condition1 = new EndlessConditionMock();
            EndlessConditionMock condition2 = new EndlessConditionMock();
            Transition           transition = new Transition();

            transition.Data.Conditions.Add(condition1);
            transition.Data.Conditions.Add(condition2);
            transition.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            // After it is activated and the conditions are completed,
            transition.LifeCycle.Activate();

            yield return(null);

            transition.Update();

            condition1.Autocomplete();

            Assert.IsTrue(condition1.IsCompleted);
            Assert.IsFalse(condition2.IsCompleted);
            Assert.IsFalse(transition.IsCompleted);

            condition2.Autocomplete();

            Assert.IsTrue(condition1.IsCompleted);
            Assert.IsTrue(condition2.IsCompleted);
            Assert.IsFalse(transition.IsCompleted);

            while (transition.IsCompleted == false)
            {
                yield return(null);

                transition.Update();
            }

            // Then and only then the transition is completed.
            Assert.IsTrue(transition.IsCompleted);
        }
Пример #15
0
        public IEnumerator FastForwardInactive()
        {
            // Given a step,
            IBehavior  behavior   = new EndlessBehaviorMock();
            ICondition condition  = new EndlessConditionMock();
            Transition transition = new Transition();
            IStep      step       = new Step("Step");

            transition.Data.Conditions.Add(condition);
            step.Data.Behaviors.Data.Behaviors.Add(behavior);
            step.Data.Transitions.Data.Transitions.Add(transition);
            step.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            // When you fast-forward it,
            step.LifeCycle.MarkToFastForward();

            // Then it doesn't change it's activation state, as well as its contents.
            Assert.AreEqual(Stage.Inactive, step.LifeCycle.Stage);
            Assert.AreEqual(Stage.Inactive, behavior.LifeCycle.Stage);
            Assert.AreEqual(Stage.Inactive, condition.LifeCycle.Stage);

            yield break;
        }
Пример #16
0
        public IEnumerator LoopingStepsActivationStates()
        {
            // Given a chapter with two steps that have transitions with one condition to each other (a "loop"),
            Step step1 = new Step("First");
            Step step2 = new Step("Second");

            Chapter chapter = new Chapter("Looping Chapter", step1);

            chapter.Data.Steps.Add(step2);

            Transition transition1 = new Transition();
            Transition transition2 = new Transition();

            transition1.Data.TargetStep = step2;
            transition2.Data.TargetStep = step1;

            EndlessConditionMock condition1 = new EndlessConditionMock();
            EndlessConditionMock condition2 = new EndlessConditionMock();

            transition1.Data.Conditions.Add(condition1);
            transition2.Data.Conditions.Add(condition2);

            step1.Data.Transitions.Data.Transitions.Add(transition1);
            step2.Data.Transitions.Data.Transitions.Add(transition2);

            chapter.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            // When we activate the chapter and complete every condition,
            chapter.LifeCycle.Activate();

            while (chapter.Data.FirstStep.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            Stage chapterInitalStage = chapter.LifeCycle.Stage;
            Stage step1InitialStage  = step1.LifeCycle.Stage;
            Stage step2InitialStage  = step2.LifeCycle.Stage;

            condition1.Autocomplete();

            while (step2.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            Stage chapterStageAfterFirstComplete = chapter.LifeCycle.Stage;
            Stage step1StageAfterFirstComplete   = step1.LifeCycle.Stage;
            Stage step2StageAfterFirstComplete   = step2.LifeCycle.Stage;

            condition2.Autocomplete();

            while (step1.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            Stage chapterStageAfterSecondComplete = chapter.LifeCycle.Stage;
            Stage step1StageAfterSecondComplete   = step1.LifeCycle.Stage;
            Stage step2StageAfterSecondComplete   = step2.LifeCycle.Stage;

            // Then the first step is active again and every ActivationState after each condition completion has been correct.
            Assert.AreEqual(Stage.Activating, chapterInitalStage, "Chapter should be activating in the beginning");
            Assert.AreEqual(Stage.Active, step1InitialStage, "First Step should be active in the beginning");
            Assert.AreEqual(Stage.Inactive, step2InitialStage, "Second Step should be inactive in the beginning");

            Assert.AreEqual(Stage.Activating, chapterStageAfterFirstComplete, "Chapter should be activating after first complete");
            Assert.AreEqual(Stage.Inactive, step1StageAfterFirstComplete, "First Step should be deactivated after first complete");
            Assert.AreEqual(Stage.Active, step2StageAfterFirstComplete, "Second Step should be active after first complete");

            Assert.AreEqual(Stage.Activating, chapterStageAfterSecondComplete, "Chapter should not be activating after second complete because of the loop");
            Assert.AreEqual(Stage.Active, step1StageAfterSecondComplete, "First Step should be active after second complete because of the loop");
            Assert.AreEqual(Stage.Inactive, step2StageAfterSecondComplete, "Second Step should be deactivated after second complete because of the loop");

            yield break;
        }
Пример #17
0
        public IEnumerator FastForwardTwoStepsLoopingChapter()
        {
            // Given a chapter with two steps looping between each other,
            Step    firstStep  = new Step("First Step");
            Step    secondStep = new Step("Second Step");
            Chapter chapter    = new Chapter("Chapter", firstStep);

            chapter.Data.Steps.Add(secondStep);
            Transition firstToSecond = new Transition();

            firstToSecond.Data.TargetStep = secondStep;
            Transition secondToFirst = new Transition();

            secondToFirst.Data.TargetStep = firstStep;
            Transition           secondToEnd   = new Transition();
            EndlessConditionMock conditionMock = new EndlessConditionMock();

            secondToEnd.Data.Conditions.Add(conditionMock);
            firstStep.Data.Transitions.Data.Transitions.Add(firstToSecond);
            secondStep.Data.Transitions.Data.Transitions.Add(secondToFirst);
            secondStep.Data.Transitions.Data.Transitions.Add(secondToEnd);

            chapter.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);
            chapter.LifeCycle.Activate();

            int loops = 0;

            while (loops < 2)
            {
                while (firstStep.LifeCycle.Stage != Stage.Active)
                {
                    Assert.AreEqual(Stage.Activating, chapter.LifeCycle.Stage);
                    Assert.AreEqual(Stage.Inactive, secondStep.LifeCycle.Stage);
                    yield return(null);

                    chapter.Update();
                }


                while (firstStep.LifeCycle.Stage != Stage.Inactive)
                {
                    Assert.AreEqual(Stage.Activating, chapter.LifeCycle.Stage);
                    Assert.AreEqual(Stage.Inactive, secondStep.LifeCycle.Stage);
                    yield return(null);

                    chapter.Update();
                }

                while (secondStep.LifeCycle.Stage != Stage.Active)
                {
                    Assert.AreEqual(Stage.Activating, chapter.LifeCycle.Stage);
                    Assert.AreEqual(Stage.Inactive, firstStep.LifeCycle.Stage);
                    yield return(null);

                    chapter.Update();
                }

                while (secondStep.LifeCycle.Stage != Stage.Inactive)
                {
                    Assert.AreEqual(Stage.Activating, chapter.LifeCycle.Stage);
                    Assert.AreEqual(Stage.Inactive, firstStep.LifeCycle.Stage);
                    yield return(null);

                    chapter.Update();
                }

                loops++;
            }

            // When it's marked to be fast-forwarded,
            chapter.LifeCycle.MarkToFastForward();

            // Then it completes.
            Assert.AreEqual(Stage.Active, chapter.LifeCycle.Stage);
            Assert.AreEqual(Stage.Inactive, firstStep.LifeCycle.Stage);
            Assert.AreEqual(Stage.Inactive, secondStep.LifeCycle.Stage);
        }
Пример #18
0
        public IEnumerator LoopingStepsWithOneEndStep()
        {
            // Given a chapter with three steps
            // where the first two steps are connected to each other with two transitions with each one condition ("loop")
            // and the second step is connected to the third step with a third transition with one condition,
            Step step1 = new Step("First");
            Step step2 = new Step("Second");
            Step step3 = new Step("Third");

            Chapter chapter = new Chapter("Chapter 1", step1);

            chapter.Data.Steps.Add(step2);
            chapter.Data.Steps.Add(step3);

            Transition transition1     = new Transition();
            Transition transition2     = new Transition();
            Transition transition3     = new Transition();
            Transition transitionToEnd = new Transition();

            transition1.Data.TargetStep = step2;
            transition2.Data.TargetStep = step1;
            transition3.Data.TargetStep = step3;

            EndlessConditionMock condition1 = new EndlessConditionMock();
            EndlessConditionMock condition2 = new EndlessConditionMock();
            EndlessConditionMock condition3 = new EndlessConditionMock();

            transition1.Data.Conditions.Add(condition1);
            transition2.Data.Conditions.Add(condition2);
            transition3.Data.Conditions.Add(condition3);

            step1.Data.Transitions.Data.Transitions.Add(transition1);
            step2.Data.Transitions.Data.Transitions.Add(transition2);
            step2.Data.Transitions.Data.Transitions.Add(transition3);
            step3.Data.Transitions.Data.Transitions.Add(transitionToEnd);

            chapter.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode);

            // When we activate the chapter and complete the third condition after looping the first two steps once,
            chapter.LifeCycle.Activate();

            while (chapter.Data.FirstStep.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            condition1.Autocomplete();

            while (step2.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            condition2.Autocomplete();

            while (step1.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            condition1.Autocomplete();

            while (step2.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            condition3.Autocomplete();

            while (chapter.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                chapter.Update();
            }

            // Then the chapter and each step are deactivated.
            Assert.AreEqual(Stage.Active, chapter.LifeCycle.Stage, "Chapter should be active in the end");
            Assert.AreEqual(Stage.Inactive, step1.LifeCycle.Stage, "Step1 should not be active in the end");
            Assert.AreEqual(Stage.Inactive, step2.LifeCycle.Stage, "Step2 should not be active in the end");
            Assert.AreEqual(Stage.Inactive, step3.LifeCycle.Stage, "Step3 should not be active in the end");

            yield break;
        }