public IEnumerator DisableGameObjectBehavior() { // Given DisableGameObjectBehavior, TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .DisableAutomaticAudioHandling() .Disable("TestObject"))) .Build(); // When we serialize and deserialize a training with it string serialized = JsonTrainingSerializer.Serialize(training1); ICourse training2 = JsonTrainingSerializer.Deserialize(serialized); DisableGameObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as DisableGameObjectBehavior; DisableGameObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as DisableGameObjectBehavior; // Then it's target training scene object is still the same. Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator BuildingUseTest() { // Given a usable property and a builder for a training with Use default step GameObject usableGo = new GameObject("Usable"); TrainingSceneObject usable = usableGo.AddComponent <TrainingSceneObject>(); usableGo.AddComponent <UsableProperty>(); usable.ChangeUniqueName("Usable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(DefaultSteps.Use("TestUseStep", "Usable"))); // When you build a training with it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then it has a step with an UsedCondition Assert.True(step != null); Assert.True(step.Data.Name == "TestUseStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() is UsedCondition); Assert.True(ReferenceEquals((step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as UsedCondition).Data.UsableProperty.Value.SceneObject, usable)); // Cleanup Object.DestroyImmediate(usableGo); return(null); }
public IEnumerator LockObjectBehavior() { // Given a training with LockObjectBehavior TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .DisableAutomaticAudioHandling() .AddBehavior(new LockObjectBehavior(trainingSceneObject)))) .Build(); // When we serialize and deserialize it ICourse training2 = JsonTrainingSerializer.Deserialize(JsonTrainingSerializer.Serialize(training1)); // Then that's behavior target is still the same. LockObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as LockObjectBehavior; LockObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as LockObjectBehavior; Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); // Cleanup TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator BuildingGrabTest() { // Given a `GrabbableProperty` and a builder for a training with a Grab default step GameObject go = new GameObject("TestGrabbable"); TrainingSceneObject to = go.AddComponent <TrainingSceneObject>(); go.AddComponent <GrabbableProperty>(); to.ChangeUniqueName("Grabbable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(DefaultSteps.Grab("TestGrabStep", "Grabbable"))); // When we build a training from it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; //Then it should has a stap with a GrabbedCondition which refers to the `GrabbableProperty`. Assert.True(step != null); Assert.True(step.Data.Name == "TestGrabStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); GrabbedCondition condition = step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as GrabbedCondition; Assert.True(ReferenceEquals(to, condition.Data.GrabbableProperty.Value.SceneObject)); // Cleanup Object.DestroyImmediate(go); yield return(null); }
public IEnumerator UnlockObjectBehavior() { // Given a training with UnlockObjectBehavior TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddBehavior(new UnlockObjectBehavior(trainingSceneObject)))) .Build(); // When we serialize and deserialize it ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); UnlockObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as UnlockObjectBehavior; UnlockObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as UnlockObjectBehavior; // Then that behavior's target should not change. Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); // Cleanup TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator BuildingTouchTest() { // Given you have a touchable property and a builder for a training with Touch default step GameObject touchableGo = new GameObject("Touchable"); TrainingSceneObject touchable = touchableGo.AddComponent <TrainingSceneObject>(); touchableGo.AddComponent <DummyTouchableProperty>(); touchable.ChangeUniqueName("Touchable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(InteractionDefaultSteps.Touch("TestTouchStep", "Touchable"))); // When you build a training with it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then it has a step with a TouchCOndition Assert.True(step != null); Assert.True(step.Data.Name == "TestTouchStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() is TouchedCondition); Assert.True(ReferenceEquals((step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as TouchedCondition).Data.TouchableProperty.Value.SceneObject, touchable)); // Cleanup Object.DestroyImmediate(touchableGo); 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 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 HighlightTest() { // Given we have a training scene object and a builder for a training with a step with highlight that object GameObject go = new GameObject("Highlightable"); EnableHighlightProperty highlightable = go.AddComponent <EnableHighlightProperty>(); highlightable.SceneObject.ChangeUniqueName("Highlightable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(new BasicCourseStepBuilder("TestHighlightStep") .Highlight("Highlightable"))); // When we build a training from it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then we have a step with VRTKObjectHighlight behavior. Assert.True(step != null); Assert.True(step.Data.Name == "TestHighlightStep"); Assert.True(step.Data.Behaviors.Data.Behaviors.First() is HighlightObjectBehavior); Assert.True(ReferenceEquals((step.Data.Behaviors.Data.Behaviors.First() as HighlightObjectBehavior).Data.ObjectToHighlight.Value, highlightable)); // Cleanup Object.DestroyImmediate(go); return(null); }
public IEnumerator ObjectInRangeCondition() { // Given a training with ObjectInRangeCondition, TrainingSceneObject testObjectToo = TestingUtils.CreateSceneObject("TestObjectToo"); TransformInRangeDetectorProperty detector = testObjectToo.gameObject.AddComponent <TransformInRangeDetectorProperty>(); TrainingSceneObject testObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new ObjectInRangeCondition(testObject, detector, 1.5f)))) .Build(); // When we serialize and deserialize it ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); // Then that condition's target, detector and range should stay unchanged. ObjectInRangeCondition condition1 = training1.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as ObjectInRangeCondition; ObjectInRangeCondition condition2 = training2.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as ObjectInRangeCondition; Assert.IsNotNull(condition1); Assert.IsNotNull(condition2); Assert.AreEqual(condition1.Data.Range, condition2.Data.Range); Assert.AreEqual(condition1.Data.Target.Value, condition2.Data.Target.Value); Assert.AreEqual(condition1.Data.DistanceDetector.Value, condition2.Data.DistanceDetector.Value); // Cleanup TestingUtils.DestroySceneObject(testObjectToo); TestingUtils.DestroySceneObject(testObject); return(null); }
public IEnumerator EnableGameObjectBehavior() { // Given EnableGameObjectBehavior, TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicCourseStepBuilder("Step") .Enable("TestObject"))) .Build(); // When we serialize and deserialize a training course with it ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); EnableGameObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as EnableGameObjectBehavior; EnableGameObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as EnableGameObjectBehavior; // Then it's target training scene object is still the same. Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator BehaviorSequence() { // Given a training with a behaviors sequence BehaviorSequence sequence = new BehaviorSequence(true, new List <IBehavior> { new DelayBehavior(0f), new EmptyBehaviorMock() }); ICourse course = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddBehavior(sequence))) .Build(); // When we serialize and deserialize it ICourse deserializedCourse = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(course)); BehaviorSequence deserializedSequence = deserializedCourse.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as BehaviorSequence; // Then the values stay the same. Assert.IsNotNull(deserializedSequence); Assert.AreEqual(sequence.Data.PlaysOnRepeat, deserializedSequence.Data.PlaysOnRepeat); List <IBehavior> behaviors = sequence.Data.Behaviors; List <IBehavior> deserializedBehaviors = deserializedSequence.Data.Behaviors; Assert.AreEqual(behaviors.First().GetType(), deserializedBehaviors.First().GetType()); Assert.AreEqual(behaviors.Last().GetType(), deserializedBehaviors.Last().GetType()); Assert.AreEqual(behaviors.Count, deserializedBehaviors.Count); yield break; }
public IEnumerator BuildingSnapZonePutTest() { // Given a snap zone and snappable property and a builder for a training with a PutIntoSnapZone default step GameObject snapZoneGo = new GameObject("SnapZone"); TrainingSceneObject snapZone = snapZoneGo.AddComponent <TrainingSceneObject>(); snapZoneGo.AddComponent <DummySnapZoneProperty>(); snapZone.ChangeUniqueName("SnapZone"); GameObject putGo = new GameObject("Puttable"); TrainingSceneObject objectToPut = putGo.AddComponent <TrainingSceneObject>(); putGo.AddComponent <DummySnappableProperty>(); objectToPut.ChangeUniqueName("ToPut"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(InteractionDefaultSteps.PutIntoSnapZone("TestSnapZonePutStep", "SnapZone", "ToPut"))); // When you build a training with it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then it has a step with a SnappedCondition Assert.True(step != null); Assert.True(step.Data.Name == "TestSnapZonePutStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() is SnappedCondition); Assert.True(ReferenceEquals((step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as SnappedCondition).Data.Target.Value.SceneObject, objectToPut)); // Cleanup Object.DestroyImmediate(snapZoneGo); Object.DestroyImmediate(putGo); return(null); }
public IEnumerator BaseTraining() { // Given base training ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step"))) .Build(); JsonTrainingSerializer.Serialize(training1); // When we serialize and deserialize it ICourse training2 = JsonTrainingSerializer.Deserialize(JsonTrainingSerializer.Serialize(training1)); // Then it should still be base training, have the same name and the first chapter with the same name. Assert.AreEqual(typeof(Course), training1.GetType()); Assert.AreEqual(training1.GetType(), training2.GetType()); Assert.AreEqual(training1.Data.Name, "Training"); Assert.AreEqual(training1.Data.Name, training2.Data.Name); Assert.AreEqual(training1.Data.FirstChapter.Data.Name, "Chapter"); Assert.AreEqual(training1.Data.FirstChapter.Data.Name, training2.Data.FirstChapter.Data.Name); return(null); }
public IEnumerator TextToSpeechAudio() { // Given we have TextToSpeechAudio instance, TextToSpeechAudio audio = new TextToSpeechAudio(new LocalizedString("TestPath")); ICourse course = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .DisableAutomaticAudioHandling() .AddBehavior(new PlayAudioBehavior(audio, BehaviorExecutionStages.Activation)))) .Build(); // When we serialize and deserialize a training with it, ICourse testCourse = JsonTrainingSerializer.Deserialize(JsonTrainingSerializer.Serialize(course)); // Then the text to generate sound from should be the same. IAudioData data1 = ((PlayAudioBehavior)course.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First()).Data.AudioData; IAudioData data2 = ((PlayAudioBehavior)testCourse.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First()).Data.AudioData; string audioPath1 = TestingUtils.GetField <LocalizedString>(data1, "text").Key; string audioPath2 = TestingUtils.GetField <LocalizedString>(data2, "text").Key; Assert.AreEqual(data1.GetType(), data2.GetType()); Assert.AreEqual(audioPath1, "TestPath"); Assert.AreEqual(audioPath1, audioPath2); return(null); }
public IEnumerator MoveObjectBehavior() { // Given training with MoveObjectBehavior TrainingSceneObject moved = TestingUtils.CreateSceneObject("moved"); TrainingSceneObject positionProvider = TestingUtils.CreateSceneObject("positionprovider"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddBehavior(new MoveObjectBehavior(moved, positionProvider, 24.7f)))) .Build(); // When that training is serialized and deserialzied ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); // Then we should have two identical move object behaviors MoveObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as MoveObjectBehavior; MoveObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as MoveObjectBehavior; Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.IsFalse(ReferenceEquals(behavior1, behavior2)); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); Assert.AreEqual(behavior1.Data.PositionProvider.Value, behavior2.Data.PositionProvider.Value); Assert.AreEqual(behavior1.Data.Duration, behavior2.Data.Duration); // Cleanup created game objects. TestingUtils.DestroySceneObject(moved); TestingUtils.DestroySceneObject(positionProvider); return(null); }
public void BuildingIntroTest() { // Given a builder with a predefined Intro step LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(Creator.Tests.Builder.DefaultSteps.Intro("TestIntroStep"))); // When we build a training from it, IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then a training with an Intro step is created. Assert.True(step != null); Assert.True(step.Data.Name == "TestIntroStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Any() == false); }
public IEnumerator AudioFlagsCleanupTest() { // Given a builder for a training LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(new BasicCourseStepBuilder("TestStep") .AddAudioSuccess(new LocalizedString("Path1")) .AddAudioDescription(new LocalizedString("Path1")) .AddAudioHint(new LocalizedString("Path2")))); // When we are building two trainings from it builder.Build(); builder.Build(); // Then it throws no exceptions. If internal builder information wasn't reset properly, then InvalidOperationException will be thrown. Not having any asserts is intended. return(null); }
public IEnumerator Step() { // Given we have a training with a step ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new TimeoutCondition(2.5f)))) .Build(); // When we serialize and deserialize it ICourse training2 = JsonTrainingSerializer.Deserialize((JsonTrainingSerializer.Serialize(training1))); // Then that step's name should still be the same. Assert.AreEqual(training1.Data.FirstChapter.Data.FirstStep.Data.Name, training2.Data.FirstChapter.Data.FirstStep.Data.Name); return(null); }
public void ReuseBuilderTest() { // Given a builder LinearTrainingBuilder builder = new LinearTrainingBuilder("1") .AddChapter(new LinearChapterBuilder("1.1") .AddStep(new BasicStepBuilder("1.1.1"))) .AddChapter(new LinearChapterBuilder("1.2") .AddStep(new BasicStepBuilder("1.2.1")) .AddStep(new BasicStepBuilder("1.2.2")) .AddStep(new BasicStepBuilder("1.2.3"))) .AddChapter(new LinearChapterBuilder("1.3") .AddStep(new BasicStepBuilder("1.3.1"))); // When we build two trainings from it ICourse training1 = builder.Build(); ICourse training2 = builder.Build(); Assert.True(training1.Data.Chapters.Count == training2.Data.Chapters.Count, "Both trainings should have the same length"); // Then two different instances of the training are created, // which have the same composition of chapters and steps, // but there is not a single step or chapter instance that is shared between two trainings. for (int i = 0; i < 3; i++) { IChapter chapter1 = training1.Data.Chapters[i]; IChapter chapter2 = training2.Data.Chapters[i]; Assert.False(ReferenceEquals(chapter1, chapter2)); Assert.True(chapter1.Data.Name == chapter2.Data.Name); IStep step1 = chapter1.Data.FirstStep; IStep step2 = chapter2.Data.FirstStep; while (step1 != null) { Assert.False(ReferenceEquals(step1, step2)); Assert.True(step1.Data.Name == step2.Data.Name); step1 = step1.Data.Transitions.Data.Transitions.First().Data.TargetStep; step2 = step2.Data.Transitions.Data.Transitions.First().Data.TargetStep; } Assert.True(step2 == null, "If we are here, step1 is null. If step1 is null, step2 has to be null, too."); } }
public IEnumerator FastForwardInactiveCourse() { // Given a training course Course course = new LinearTrainingBuilder("Training Course") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new EndlessConditionMock()))) .Build(); course.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode); // When you mark it to fast-forward, course.LifeCycle.MarkToFastForward(); // Then it doesn't autocomplete because it weren't activated yet. Assert.AreEqual(Stage.Inactive, course.LifeCycle.Stage); yield break; }
public IEnumerator Step() { // Given we have a training with a step ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new AutoCompletedCondition()))) .Build(); // When we serialize and deserialize it ICourse training2 = Serializer.CourseFromByteArray((Serializer.CourseToByteArray(training1))); // Then that step's name should still be the same. Assert.AreEqual(training1.Data.FirstChapter.Data.FirstStep.Data.Name, training2.Data.FirstChapter.Data.FirstStep.Data.Name); return(null); }
public void MultipleChaptersTest() { // Given a builder of a training with three chapters with one, three, and one steps LinearTrainingBuilder builder = new LinearTrainingBuilder("1") .AddChapter(new LinearChapterBuilder("1.1") .AddStep(new BasicStepBuilder("1.1.1"))) .AddChapter(new LinearChapterBuilder("1.2") .AddStep(new BasicStepBuilder("1.2.1")) .AddStep(new BasicStepBuilder("1.2.2")) .AddStep(new BasicStepBuilder("1.2.3"))) .AddChapter(new LinearChapterBuilder("1.3") .AddStep(new BasicStepBuilder("1.3.1"))); // When we build a training from it ICourse course = builder.Build(); // Then it has exactly three chapters in it with one, three, and one steps, // `NextChapter` properties are properly assigned, // and every chapter has expected composition of steps. IChapter chapter = course.Data.FirstChapter; Assert.True(chapter.Data.Name == "1.1"); IStep step = chapter.Data.FirstStep; Assert.True(chapter.Data.FirstStep.Data.Name == "1.1.1"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.TargetStep == null); chapter = course.Data.Chapters[1]; Assert.True(chapter.Data.Name == "1.2"); step = chapter.Data.FirstStep; Assert.True(step.Data.Name == "1.2.1"); step = step.Data.Transitions.Data.Transitions.First().Data.TargetStep; Assert.True(step.Data.Name == "1.2.2"); step = step.Data.Transitions.Data.Transitions.First().Data.TargetStep; Assert.True(step.Data.Name == "1.2.3"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.TargetStep == null); chapter = course.Data.Chapters[2]; Assert.True(chapter.Data.Name == "1.3"); step = chapter.Data.FirstStep; Assert.True(step.Data.Name == "1.3.1"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.TargetStep == null); Assert.AreEqual(3, course.Data.Chapters.Count); }
public void SimplestTrainingBuilderTest() { // Given a builder of a training with one chapter with one step LinearTrainingBuilder builder = new LinearTrainingBuilder("Training1") .AddChapter(new LinearChapterBuilder("Chapter1.1") .AddStep(new BasicStepBuilder("Step1.1.1")) ); // When we build a training from it ICourse course = builder.Build(); // Then it consists of exactly one chapter and one step, and their names are the same as expected Assert.True(course.Data.Name == "Training1"); Assert.True(course.Data.FirstChapter.Data.Name == "Chapter1.1"); Assert.True(course.Data.FirstChapter.Data.FirstStep.Data.Name == "Step1.1.1"); Assert.True(course.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.Count == 1); Assert.True(course.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.TargetStep == null); Assert.AreEqual(1, course.Data.Chapters.Count); }
public IEnumerator FastForwardActivatingCourse() { // Given an activated training Course course = new LinearTrainingBuilder("Training Course") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new EndlessConditionMock()))) .Build(); CourseRunner.Initialize(course); CourseRunner.Run(); // When you mark it to fast-forward, course.LifeCycle.MarkToFastForward(); // Then it finishes activation. Assert.AreEqual(Stage.Active, course.LifeCycle.Stage); yield break; }
public IEnumerator CallAddAudioHintTwiceTest() { TestDelegate test = () => { // Given a builder with two .AddAudioHint calls LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(new BasicCourseStepBuilder("TestStep") .AddAudioHint(new LocalizedString("Path1")) .AddAudioHint(new LocalizedString("Path2")))); // When we build a training from it builder.Build(); }; //Then an exception should be thrown out, as having two audio hints is not allowed. Assert.Throws <InvalidOperationException>(test); return(null); }
public IEnumerator Condition() { // Given a training which has a step with a condition ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new TimeoutCondition(2.5f)))) .Build(); // When we serialize and deserialize it ICourse training2 = JsonTrainingSerializer.Deserialize((JsonTrainingSerializer.Serialize(training1))); // Then that condition's name should not change. ICondition condition1 = training1.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.Conditions.First(); ICondition condition2 = training2.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.Conditions.First(); Assert.AreEqual(condition1.GetType(), condition2.GetType()); return(null); }
public IEnumerator DelayBehavior() { // Given we have a training with a delayed activation behavior, ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddBehavior(new DelayBehavior(7f)))) .Build(); // When we serialize and deserialize it, byte[] serialized = Serializer.CourseToByteArray(training1); ICourse training2 = Serializer.CourseFromByteArray(serialized); // Then that delayed behaviors should have the same target behaviors and delay time. DelayBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as DelayBehavior; DelayBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as DelayBehavior; Assert.AreEqual(behavior1.Data.DelayTime, behavior2.Data.DelayTime); return(null); }
public IEnumerator FastForwardInactiveCourseAndActivateIt() { // Given a training Course course = new LinearTrainingBuilder("Training Course") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new EndlessConditionMock()))) .Build(); // When you mark it to fast-forward and activate it, course.LifeCycle.MarkToFastForward(); CourseRunner.Initialize(course); CourseRunner.Run(); yield return(null); // Then it autocompletes. Assert.AreEqual(Stage.Inactive, course.LifeCycle.Stage); yield break; }
public IEnumerator Transition() { // Given a training with more than one step ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("FirstStep") .DisableAutomaticAudioHandling()) .AddStep(new BasicStepBuilder("SecondStep") .DisableAutomaticAudioHandling())) .Build(); // When we serialize and deserialize it string serialized = JsonTrainingSerializer.Serialize(training1); ICourse training2 = JsonTrainingSerializer.Deserialize(serialized); // Then transition from the first step should lead to the same step as before. Assert.AreEqual(training1.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.TargetStep.Data.Name, training2.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.TargetStep.Data.Name); return(null); }