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; }
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; }
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); }
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"); }
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); }
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; }
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; }
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); }
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); }
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); }
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); }
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); }
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; }
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; }
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); }
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; }