using System.Collections; using NUnit.Framework; using NightclubArcadia.Interaction; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestTools; using Yarn.Unity; namespace NightclubArcadia.PlayMode.Tests { /// /// The level must survive being loaded BEFORE the systems it depends on. /// /// BootstrapTests only covers the happy order — Bootstrap loads Systems, then the /// level, so by the time an interactor needs the dialogue runner it is already there. /// The Editor does not guarantee that. Open the level on its own, press Play, and /// nothing in it can reach the runner. Resolving in Awake and caching the result /// produced exactly that, permanently, for the whole session: /// /// [SceneServices] Bartender: could not resolve dialogueRunner /// /// DialogueInteractor resolves at the point of use and caches only success, so load /// order stops mattering. This is the test that holds that. /// public class SceneOrderTests { const string Systems = "Systems"; const string Level = "SC101_ConferenceHall"; [UnityTearDown] public IEnumerator TearDown() { yield return SceneManager.LoadSceneAsync("Bootstrap", LoadSceneMode.Single); } [UnityTest] public IEnumerator LevelLoadedBeforeSystems_InteractorsStillResolveTheRunner() { yield return SceneManager.LoadSceneAsync(Level, LoadSceneMode.Single); for (var i = 0; i < 2; i++) { yield return null; } var interactors = Object.FindObjectsByType( FindObjectsInactive.Include, FindObjectsSortMode.None); Assert.IsNotEmpty(interactors, "Expected interactors in the level scene"); // Non-vacuity: with only the level loaded there must genuinely be no runner // to find. If this ever fails, the dependency stopped being cross-scene and // the rest of this test proves nothing. Assert.IsNull(Object.FindFirstObjectByType(FindObjectsInactive.Include), "A DialogueRunner exists with only the level loaded, so this test is no " + "longer exercising cross-scene resolution. Rewrite it before trusting it."); yield return SceneManager.LoadSceneAsync(Systems, LoadSceneMode.Additive); for (var i = 0; i < 2; i++) { yield return null; } foreach (var interactor in interactors) { Assert.IsNotNull(interactor.ResolvedRunner, $"'{interactor.name}' could not reach the DialogueRunner when the level " + "loaded before Systems. Cross-scene resolution must not depend on load order."); } } } }