[Timeout(120_000)] // ms to complete whole game public IEnumerator TestPlayWholeGame(LevelTestData[] game) { // Arrange const float caseTimeLimit = 10; // seconds Main.instance.ignorePlayingGuides = true; Main.instance.StartGame(); yield return(null); PMWrapper.speedMultiplier = 1; // Act var inconclusive = new List <string>(); foreach (LevelTestData data in game) { Main.instance.StartLevel(data.levelIndex); PMWrapper.currentLevelIndex = data.levelIndex; yield return(null); var postSceneLoad = PostSceneLoad(); while (postSceneLoad != null && postSceneLoad.MoveNext()) { yield return(postSceneLoad.Current); } yield return(null); if (!string.IsNullOrWhiteSpace(data.levelData.levelSettings?.exampleSolutionCode)) { PMWrapper.mainCode = data.levelData.levelSettings.exampleSolutionCode; } else { Debug.LogWarning($"Level {data.levelData.id} has no example solution"); inconclusive.Add($"Level '{data.levelData.id}' ({data.scene.name}) has no example solution."); } float start = Time.time; do { IEnumerator coroutine = PlaygroundTestHelper.RunCaseAndAssert(data); while (coroutine.MoveNext()) { yield return(coroutine.Current); } Assert.IsTrue(Time.time - start < caseTimeLimit, "Compiler execution timeout! Compiler took too long to complete ALL cases in {0}.", data); } while (!Main.instance.caseHandler.allCasesCompleted); } // Assert if (inconclusive.Count > 0) { Assert.Inconclusive(string.Join("\n", inconclusive)); } // Asserting is done by assuming no exceptions & no error logs }
public IEnumerator RunCodePasses() { // Arrange const int timeoutMilliseconds = 10_000; PMWrapper.mainCode = "AnpassadFunktion()"; PMWrapper.speedMultiplier = 1; // Act return(PlaygroundTestHelper.RunCompilerWithTimeout(timeoutMilliseconds)); // Assert // Asserting is done by assuming no exceptions & no error logs }
[Timeout(60_000)] // ms to complete ALL cases for level public virtual IEnumerator TestPlayLevel(LevelTestData data) { // Arrange const float caseTimeLimit = 10; // seconds Main.instance.ignorePlayingGuides = true; Main.instance.StartGame(data.levelIndex); yield return(null); PMWrapper.speedMultiplier = 1; var postSceneLoad = PostSceneLoad(); while (postSceneLoad != null && postSceneLoad.MoveNext()) { yield return(postSceneLoad.Current); } yield return(null); // Act if (!string.IsNullOrWhiteSpace(data.levelData.levelSettings?.exampleSolutionCode)) { PMWrapper.mainCode = data.levelData.levelSettings.exampleSolutionCode; } else { Assert.Inconclusive($"Level '{data.levelData.id}' ({data.scene.name}) has no example solution."); } float start = Time.time; do { IEnumerator coroutine = PlaygroundTestHelper.RunCaseAndAssert(data); while (coroutine.MoveNext()) { yield return(coroutine.Current); } Assert.IsTrue(Time.time - start < caseTimeLimit, $"Compiler execution timeout! Compiler took too long to complete ALL cases in {data}. Waited {caseTimeLimit} seconds."); } while (!Main.instance.caseHandler.allCasesCompleted); // Asserting is done by assuming no exceptions & no error logs }
/// <summary> /// Loads the scene, opens the level, sets case, runs the case, then unloads the scene. /// Guarantees a fresh game instance between each case. /// Useful to try catch unwanted state between cases. /// <para>Argument <paramref name="data"/> can be fed using the <see cref="ValueSourceAttribute"/> in combination /// with using <see cref="PlaygroundTestHelper.GetActiveCases"/> from <see cref="PlaygroundTestHelper"/>.</para> /// <para>Note: Needs attribute <see cref="UnityTestAttribute"/> to be applied on the overridden method /// in your derived class for Unity Test Runner to find the method.</para> /// </summary> /// <param name="data">The level data. Use <see cref="PlaygroundTestHelper.GetActiveCases"/> /// from <see cref="PlaygroundTestHelper"/> to feed automatically using <see cref="ValueSourceAttribute"/>.</param> public virtual IEnumerator TestPlayCase(CaseTestData data) { if (data.caseData == null) { Assert.Inconclusive($"Level '{data.levelData.id}' ({data.scene.name}) has not a single case."); } // Arrange Main.instance.ignorePlayingGuides = true; Main.instance.ignoreNextCase = true; Main.instance.StartGame(data.levelIndex); yield return(null); PMWrapper.SwitchCase(data.caseIndex); yield return(null); var postSceneLoad = PostSceneLoad(); while (postSceneLoad != null && postSceneLoad.MoveNext()) { yield return(postSceneLoad.Current); } yield return(null); PMWrapper.speedMultiplier = 1; // Act if (!string.IsNullOrWhiteSpace(data.levelData.levelSettings.exampleSolutionCode)) { PMWrapper.mainCode = data.levelData.levelSettings.exampleSolutionCode; } else { Assert.Inconclusive($"Level '{data.levelData.id}' ({data.scene.name}) has no example solution."); } IEnumerator coroutine = PlaygroundTestHelper.RunCaseAndAssert(data); while (coroutine.MoveNext()) { yield return(coroutine.Current); } // Asserting is done by assuming no exceptions & no error logs }
public IEnumerator RunCodeErrorsAsExpected() { // Arrange const int timeoutMilliseconds = 10_000; PMWrapper.mainCode = "IckeDefinieradFunktion()"; PMWrapper.speedMultiplier = 1; // Act var coroutine = PlaygroundTestHelper.RunCompilerWithTimeout(timeoutMilliseconds); while (coroutine.MoveNext()) { yield return(coroutine.Current); } // Assert LogAssert.Expect(LogType.Exception, new Regex(".*RuntimeVariableNotDefinedException.*")); LogAssert.Expect(LogType.Exception, new Regex(".*PMRuntimeException.*")); }
static LevelTestData[] GetActiveLevels() { return(PlaygroundTestHelper.GetActiveLevels("game")); }
static CaseTestData[] GetActiveCases() { return(PlaygroundTestHelper.GetActiveCases("game")); }