From b3fdcf8b8b7c9a90421f449ed7daa432dfc27525 Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Sat, 20 Apr 2024 17:56:53 +0900 Subject: [PATCH 1/8] Refactor tests --- Tests/Runtime/AgentDispatcherTest.cs | 99 ++++++++++++++-------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/Tests/Runtime/AgentDispatcherTest.cs b/Tests/Runtime/AgentDispatcherTest.cs index 77b3445..6e90e98 100644 --- a/Tests/Runtime/AgentDispatcherTest.cs +++ b/Tests/Runtime/AgentDispatcherTest.cs @@ -3,15 +3,21 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Threading.Tasks; +using Cysharp.Threading.Tasks.Triggers; using DeNA.Anjin.Agents; using DeNA.Anjin.Settings; using DeNA.Anjin.Utilities; using NUnit.Framework; -using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestTools; +#if UNITY_EDITOR +using UnityEditor.SceneManagement; +#endif + +#pragma warning disable CS0618 // Type or member is obsolete namespace DeNA.Anjin { @@ -19,18 +25,12 @@ namespace DeNA.Anjin [SuppressMessage("ApiDesign", "RS0030")] public class AgentDispatcherTest { - [SetUp] - public void SetUp() - { - Assume.That(GameObject.Find(nameof(DoNothingAgent)), Is.Null); - } + private IAgentDispatcher _dispatcher; [TearDown] - public async Task TearDown() + public void TearDown() { - var testAgentObject = GameObject.Find(nameof(DoNothingAgent)); - Object.Destroy(testAgentObject); - await Task.Delay(100); + SceneManager.activeSceneChanged -= _dispatcher.DispatchByScene; } private static AutopilotSettings CreateAutopilotSettings() @@ -47,80 +47,81 @@ private static DoNothingAgent CreateDoNothingAgent(string name = nameof(DoNothin return doNothingAgent; } + private void SetUpDispatcher(AutopilotSettings settings) + { + var logger = new ConsoleLogger(Debug.unityLogger.logHandler); + var randomFactory = new RandomFactory(0); + + _dispatcher = new AgentDispatcher(settings, logger, randomFactory); + SceneManager.activeSceneChanged += _dispatcher.DispatchByScene; + } + private const string TestScenePath = "Packages/com.dena.anjin/Tests/TestScenes/Buttons.unity"; - private static Scene LoadTestScene() + private static async Task LoadTestSceneAsync(string path) { - return EditorSceneManager.LoadSceneInPlayMode( - TestScenePath, +#if UNITY_EDITOR + await EditorSceneManager.LoadSceneAsyncInPlayMode(path, new LoadSceneParameters(LoadSceneMode.Single)); +#endif } [Test] - public void DispatchByScene_DispatchAgentBySceneAgentMaps() + public async Task DispatchByScene_DispatchAgentBySceneAgentMaps() { - const string ActualAgentName = nameof(DoNothingAgent); - + const string AgentName = "Mapped Agent"; var settings = CreateAutopilotSettings(); settings.sceneAgentMaps.Add(new SceneAgentMap { - scenePath = TestScenePath, agent = CreateDoNothingAgent() + scenePath = TestScenePath, agent = CreateDoNothingAgent(AgentName) }); + SetUpDispatcher(settings); - var logger = new ConsoleLogger(Debug.unityLogger.logHandler); - var randomFactory = new RandomFactory(0); - var dispatcher = new AgentDispatcher(settings, logger, randomFactory); - dispatcher.DispatchByScene(LoadTestScene()); + await LoadTestSceneAsync(TestScenePath); - var gameObject = GameObject.Find(ActualAgentName); - Assert.That(gameObject, Is.Not.Null); + var actual = Object.FindObjectsOfType().Select(x => x.name); + Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } [Test] - public void DispatchByScene_DispatchFallbackAgent() + public async Task DispatchByScene_DispatchFallbackAgent() { - const string ActualAgentName = "Fallback"; - + const string AgentName = "Fallback Agent"; var settings = CreateAutopilotSettings(); - settings.fallbackAgent = CreateDoNothingAgent(ActualAgentName); + settings.fallbackAgent = CreateDoNothingAgent(AgentName); + SetUpDispatcher(settings); - var logger = new ConsoleLogger(Debug.unityLogger.logHandler); - var randomFactory = new RandomFactory(0); - var dispatcher = new AgentDispatcher(settings, logger, randomFactory); - dispatcher.DispatchByScene(LoadTestScene()); + await LoadTestSceneAsync(TestScenePath); - var gameObject = GameObject.Find(ActualAgentName); - Assert.That(gameObject, Is.Not.Null); + var actual = Object.FindObjectsOfType().Select(x => x.name); + Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } [Test] - public void DispatchByScene_NoSceneAgentMapsAndFallbackAgent_AgentIsNotDispatch() + public async Task DispatchByScene_NoSceneAgentMapsAndFallbackAgent_AgentIsNotDispatch() { var settings = CreateAutopilotSettings(); - var logger = new ConsoleLogger(Debug.unityLogger.logHandler); - var randomFactory = new RandomFactory(0); - var dispatcher = new AgentDispatcher(settings, logger, randomFactory); - dispatcher.DispatchByScene(LoadTestScene()); + SetUpDispatcher(settings); + + await LoadTestSceneAsync(TestScenePath); + var actual = Object.FindObjectsOfType().Select(x => x.name); + Assert.That(actual, Is.Empty); LogAssert.Expect(LogType.Warning, "Agent not found by scene: Buttons"); } [Test] - public void DispatchByScene_DispatchObserverAgent() + public async Task DispatchByScene_DispatchObserverAgent() { - const string ActualAgentName = "Observer"; - + const string AgentName = "Observer Agent"; var settings = CreateAutopilotSettings(); - settings.fallbackAgent = CreateDoNothingAgent(); - settings.observerAgent = CreateDoNothingAgent(ActualAgentName); + settings.observerAgent = CreateDoNothingAgent(AgentName); + SetUpDispatcher(settings); - var logger = new ConsoleLogger(Debug.unityLogger.logHandler); - var randomFactory = new RandomFactory(0); - var dispatcher = new AgentDispatcher(settings, logger, randomFactory); - dispatcher.DispatchByScene(LoadTestScene()); + await LoadTestSceneAsync(TestScenePath); - var gameObject = GameObject.Find(ActualAgentName); - Assert.That(gameObject, Is.Not.Null); + var actual = Object.FindObjectsOfType().Select(x => x.name); + Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } } } From b230c27ed8eb7da9591b87bc9c511ebae8850657 Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Sat, 20 Apr 2024 23:25:44 +0900 Subject: [PATCH 2/8] Refactor make add/remove scene changed event listener move to AgentDispatcher --- Runtime/AgentDispatcher.cs | 12 +++++++++--- Runtime/Autopilot.cs | 5 ++--- Tests/Runtime/AgentDispatcherTest.cs | 3 +-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Runtime/AgentDispatcher.cs b/Runtime/AgentDispatcher.cs index 1352ae3..8b93f04 100644 --- a/Runtime/AgentDispatcher.cs +++ b/Runtime/AgentDispatcher.cs @@ -14,7 +14,7 @@ namespace DeNA.Anjin /// /// Agent dispatcher interface /// - public interface IAgentDispatcher + public interface IAgentDispatcher : IDisposable { /// /// Agent dispatch by next scene @@ -30,7 +30,7 @@ public interface IAgentDispatcher void DispatchByScene(Scene scene); } - /// + /// public class AgentDispatcher : IAgentDispatcher { private readonly AutopilotSettings _settings; @@ -48,6 +48,12 @@ public AgentDispatcher(AutopilotSettings settings, ILogger logger, RandomFactory _settings = settings; _logger = logger; _randomFactory = randomFactory; + SceneManager.activeSceneChanged += this.DispatchByScene; + } + + public void Dispose() + { + SceneManager.activeSceneChanged -= this.DispatchByScene; } /// @@ -107,7 +113,7 @@ private void DispatchAgent(AbstractAgent agent) agent.Logger = _logger; agent.Random = _randomFactory.CreateRandom(); - + try { agent.Run(token).Forget(); diff --git a/Runtime/Autopilot.cs b/Runtime/Autopilot.cs index 561f5b0..c848ff7 100644 --- a/Runtime/Autopilot.cs +++ b/Runtime/Autopilot.cs @@ -5,7 +5,6 @@ using System.Collections; using System.Threading; using Cysharp.Threading.Tasks; -using DeNA.Anjin.Reporters; using DeNA.Anjin.Settings; using DeNA.Anjin.Utilities; using UnityEngine; @@ -51,7 +50,6 @@ private void Start() _dispatcher = new AgentDispatcher(_settings, _logger, _randomFactory); _dispatcher.DispatchByScene(SceneManager.GetActiveScene()); - SceneManager.activeSceneChanged += _dispatcher.DispatchByScene; if (_settings.lifespanSec > 0) { @@ -92,13 +90,14 @@ private IEnumerator Lifespan(int timeoutSec) /// Exit code for Unity Editor /// Log message string when terminate by the log message /// Stack trace when terminate by the log message + /// Cancellation token /// A task awaits termination get completed public async UniTask TerminateAsync(ExitCode exitCode, string logString = null, string stackTrace = null, CancellationToken token = default) { if (_dispatcher != null) { - SceneManager.activeSceneChanged -= _dispatcher.DispatchByScene; + _dispatcher.Dispose(); } if (_logMessageHandler != null) diff --git a/Tests/Runtime/AgentDispatcherTest.cs b/Tests/Runtime/AgentDispatcherTest.cs index 6e90e98..a61d518 100644 --- a/Tests/Runtime/AgentDispatcherTest.cs +++ b/Tests/Runtime/AgentDispatcherTest.cs @@ -30,7 +30,7 @@ public class AgentDispatcherTest [TearDown] public void TearDown() { - SceneManager.activeSceneChanged -= _dispatcher.DispatchByScene; + _dispatcher?.Dispose(); } private static AutopilotSettings CreateAutopilotSettings() @@ -53,7 +53,6 @@ private void SetUpDispatcher(AutopilotSettings settings) var randomFactory = new RandomFactory(0); _dispatcher = new AgentDispatcher(settings, logger, randomFactory); - SceneManager.activeSceneChanged += _dispatcher.DispatchByScene; } private const string TestScenePath = "Packages/com.dena.anjin/Tests/TestScenes/Buttons.unity"; From 05f90df13a55e45bc7ea338bb500fcf344865e79 Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Sun, 21 Apr 2024 00:52:49 +0900 Subject: [PATCH 3/8] Fix not dispatch observer agent case Conditions: Specify observer agent and not specify fallback agent. --- Runtime/AgentDispatcher.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Runtime/AgentDispatcher.cs b/Runtime/AgentDispatcher.cs index 8b93f04..e7ac7f0 100644 --- a/Runtime/AgentDispatcher.cs +++ b/Runtime/AgentDispatcher.cs @@ -85,17 +85,21 @@ public void DispatchByScene(Scene scene) if (!agent) { - if (!_settings.fallbackAgent) + if (_settings.fallbackAgent) + { + _logger.Log($"Use fallback agent. scene: {scene.path}"); + agent = _settings.fallbackAgent; + } + else { _logger.Log(LogType.Warning, $"Agent not found by scene: {scene.name}"); - return; } - - _logger.Log($"Use fallback agent. scene: {scene.path}"); - agent = _settings.fallbackAgent; } - DispatchAgent(agent); + if (agent) + { + DispatchAgent(agent); + } if (_settings.observerAgent != null) { From 6c932ec0ee55b232b471e4489f3af7c79721bce8 Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Sun, 21 Apr 2024 01:20:53 +0900 Subject: [PATCH 4/8] Fix duplicate agent creation when reactivating scene --- Runtime/AgentDispatcher.cs | 23 +++++-------- Tests/Runtime/AgentDispatcherTest.cs | 49 +++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/Runtime/AgentDispatcher.cs b/Runtime/AgentDispatcher.cs index e7ac7f0..0e64898 100644 --- a/Runtime/AgentDispatcher.cs +++ b/Runtime/AgentDispatcher.cs @@ -19,9 +19,9 @@ public interface IAgentDispatcher : IDisposable /// /// Agent dispatch by next scene /// - /// Current scene - /// Next transition scene - void DispatchByScene(Scene current, Scene next); + /// + /// + void DispatchByScene(Scene next, LoadSceneMode mode); /// /// Agent dispatch by current scene @@ -48,28 +48,21 @@ public AgentDispatcher(AutopilotSettings settings, ILogger logger, RandomFactory _settings = settings; _logger = logger; _randomFactory = randomFactory; - SceneManager.activeSceneChanged += this.DispatchByScene; + SceneManager.sceneLoaded += this.DispatchByScene; } public void Dispose() { - SceneManager.activeSceneChanged -= this.DispatchByScene; + SceneManager.sceneLoaded -= this.DispatchByScene; } - /// - /// Dispatch agent mapped to Scene `next` - /// - /// - /// - public void DispatchByScene(Scene current, Scene next) + /// + public void DispatchByScene(Scene next, LoadSceneMode mode) { DispatchByScene(next); } - /// - /// Dispatch agent mapped to Scene - /// - /// + /// public void DispatchByScene(Scene scene) { AbstractAgent agent = null; diff --git a/Tests/Runtime/AgentDispatcherTest.cs b/Tests/Runtime/AgentDispatcherTest.cs index a61d518..494a9cc 100644 --- a/Tests/Runtime/AgentDispatcherTest.cs +++ b/Tests/Runtime/AgentDispatcherTest.cs @@ -1,10 +1,11 @@ -// Copyright (c) 2023 DeNA Co., Ltd. +// Copyright (c) 2023-2024 DeNA Co., Ltd. // This software is released under the MIT License. using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; +using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks.Triggers; using DeNA.Anjin.Agents; using DeNA.Anjin.Settings; @@ -27,6 +28,15 @@ public class AgentDispatcherTest { private IAgentDispatcher _dispatcher; + [SetUp] + public void SetUp() + { + foreach (var agent in Object.FindObjectsOfType()) + { + Object.Destroy(agent); + } + } + [TearDown] public void TearDown() { @@ -56,13 +66,19 @@ private void SetUpDispatcher(AutopilotSettings settings) } private const string TestScenePath = "Packages/com.dena.anjin/Tests/TestScenes/Buttons.unity"; + private const string TestScenePath2 = "Packages/com.dena.anjin/Tests/TestScenes/Error.unity"; - private static async Task LoadTestSceneAsync(string path) + private static async UniTask LoadTestSceneAsync(string path, LoadSceneMode mode = LoadSceneMode.Single) { + Scene scene = default; #if UNITY_EDITOR - await EditorSceneManager.LoadSceneAsyncInPlayMode(path, - new LoadSceneParameters(LoadSceneMode.Single)); + scene = EditorSceneManager.LoadSceneInPlayMode(path, new LoadSceneParameters(mode)); + while (!scene.isLoaded) + { + await Task.Yield(); + } #endif + return scene; } [Test] @@ -122,5 +138,30 @@ public async Task DispatchByScene_DispatchObserverAgent() var actual = Object.FindObjectsOfType().Select(x => x.name); Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } + + [Test] + public async Task DispatchByScene_ReActivateScene_NotCreateDuplicateAgents() + { + const string AgentName = "Mapped Agent"; + var settings = CreateAutopilotSettings(); + settings.sceneAgentMaps.Add(new SceneAgentMap + { + scenePath = TestScenePath, agent = CreateDoNothingAgent(AgentName) + }); + SetUpDispatcher(settings); + + var scene = await LoadTestSceneAsync(TestScenePath); + + var agents = Object.FindObjectsOfType().Select(x => x.name); + Assume.That(agents, Is.EquivalentTo(new[] { AgentName })); + + var additiveScene = await LoadTestSceneAsync(TestScenePath2, LoadSceneMode.Additive); + SceneManager.SetActiveScene(additiveScene); + + SceneManager.SetActiveScene(scene); // Re-activate + + var actual = Object.FindObjectsOfType().Select(x => x.name); + Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); + } } } From faf185c9d084c048249423f37f57dec22a62d9d3 Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Mon, 22 Apr 2024 15:35:10 +0900 Subject: [PATCH 5/8] Mod event listener method to private --- Runtime/AgentDispatcher.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Runtime/AgentDispatcher.cs b/Runtime/AgentDispatcher.cs index 0e64898..21d3519 100644 --- a/Runtime/AgentDispatcher.cs +++ b/Runtime/AgentDispatcher.cs @@ -16,13 +16,6 @@ namespace DeNA.Anjin /// public interface IAgentDispatcher : IDisposable { - /// - /// Agent dispatch by next scene - /// - /// - /// - void DispatchByScene(Scene next, LoadSceneMode mode); - /// /// Agent dispatch by current scene /// @@ -56,8 +49,7 @@ public void Dispose() SceneManager.sceneLoaded -= this.DispatchByScene; } - /// - public void DispatchByScene(Scene next, LoadSceneMode mode) + private void DispatchByScene(Scene next, LoadSceneMode mode) { DispatchByScene(next); } From bc8bcd202f43b718b215e819e590f5cbc9c210fb Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Mon, 22 Apr 2024 18:12:00 +0900 Subject: [PATCH 6/8] Refactor tests --- Tests/Runtime/AgentDispatcherTest.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Tests/Runtime/AgentDispatcherTest.cs b/Tests/Runtime/AgentDispatcherTest.cs index 494a9cc..0c39324 100644 --- a/Tests/Runtime/AgentDispatcherTest.cs +++ b/Tests/Runtime/AgentDispatcherTest.cs @@ -81,6 +81,12 @@ private static async UniTask LoadTestSceneAsync(string path, LoadSceneMod return scene; } + private static IEnumerable FindAliveAgentNames() + { + return Object.FindObjectsOfType().Select(x => x.name); + // Note: AsyncDestroyTrigger is a component attached to the GameObject when binding agent by GetCancellationTokenOnDestroy. + } + [Test] public async Task DispatchByScene_DispatchAgentBySceneAgentMaps() { @@ -94,7 +100,7 @@ public async Task DispatchByScene_DispatchAgentBySceneAgentMaps() await LoadTestSceneAsync(TestScenePath); - var actual = Object.FindObjectsOfType().Select(x => x.name); + var actual = FindAliveAgentNames(); Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } @@ -108,7 +114,7 @@ public async Task DispatchByScene_DispatchFallbackAgent() await LoadTestSceneAsync(TestScenePath); - var actual = Object.FindObjectsOfType().Select(x => x.name); + var actual = FindAliveAgentNames(); Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } @@ -120,7 +126,7 @@ public async Task DispatchByScene_NoSceneAgentMapsAndFallbackAgent_AgentIsNotDis await LoadTestSceneAsync(TestScenePath); - var actual = Object.FindObjectsOfType().Select(x => x.name); + var actual = FindAliveAgentNames(); Assert.That(actual, Is.Empty); LogAssert.Expect(LogType.Warning, "Agent not found by scene: Buttons"); } @@ -135,7 +141,7 @@ public async Task DispatchByScene_DispatchObserverAgent() await LoadTestSceneAsync(TestScenePath); - var actual = Object.FindObjectsOfType().Select(x => x.name); + var actual = FindAliveAgentNames(); Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } @@ -152,7 +158,7 @@ public async Task DispatchByScene_ReActivateScene_NotCreateDuplicateAgents() var scene = await LoadTestSceneAsync(TestScenePath); - var agents = Object.FindObjectsOfType().Select(x => x.name); + var agents = FindAliveAgentNames(); Assume.That(agents, Is.EquivalentTo(new[] { AgentName })); var additiveScene = await LoadTestSceneAsync(TestScenePath2, LoadSceneMode.Additive); @@ -160,7 +166,7 @@ public async Task DispatchByScene_ReActivateScene_NotCreateDuplicateAgents() SceneManager.SetActiveScene(scene); // Re-activate - var actual = Object.FindObjectsOfType().Select(x => x.name); + var actual = FindAliveAgentNames(); Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); } } From 5cc6137703bd1db44097cb31167cc9c93f51993c Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Tue, 23 Apr 2024 06:43:23 +0900 Subject: [PATCH 7/8] Fix tests using spy agent --- Tests/Runtime/AgentDispatcherTest.cs | 48 ++++++++----------- .../Runtime/TestDoubles/SpyAliveCountAgent.cs | 33 +++++++++++++ .../TestDoubles/SpyAliveCountAgent.cs.meta | 3 ++ 3 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs create mode 100644 Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs.meta diff --git a/Tests/Runtime/AgentDispatcherTest.cs b/Tests/Runtime/AgentDispatcherTest.cs index 0c39324..cb5f19b 100644 --- a/Tests/Runtime/AgentDispatcherTest.cs +++ b/Tests/Runtime/AgentDispatcherTest.cs @@ -9,6 +9,7 @@ using Cysharp.Threading.Tasks.Triggers; using DeNA.Anjin.Agents; using DeNA.Anjin.Settings; +using DeNA.Anjin.TestDoubles; using DeNA.Anjin.Utilities; using NUnit.Framework; using UnityEngine; @@ -50,11 +51,11 @@ private static AutopilotSettings CreateAutopilotSettings() return testSettings; } - private static DoNothingAgent CreateDoNothingAgent(string name = nameof(DoNothingAgent)) + private static SpyAliveCountAgent CreateSpyAliveCountAgent(string name = nameof(DoNothingAgent)) { - var doNothingAgent = ScriptableObject.CreateInstance(); - doNothingAgent.name = name; - return doNothingAgent; + var agent = ScriptableObject.CreateInstance(); + agent.name = name; + return agent; } private void SetUpDispatcher(AutopilotSettings settings) @@ -81,12 +82,6 @@ private static async UniTask LoadTestSceneAsync(string path, LoadSceneMod return scene; } - private static IEnumerable FindAliveAgentNames() - { - return Object.FindObjectsOfType().Select(x => x.name); - // Note: AsyncDestroyTrigger is a component attached to the GameObject when binding agent by GetCancellationTokenOnDestroy. - } - [Test] public async Task DispatchByScene_DispatchAgentBySceneAgentMaps() { @@ -94,14 +89,15 @@ public async Task DispatchByScene_DispatchAgentBySceneAgentMaps() var settings = CreateAutopilotSettings(); settings.sceneAgentMaps.Add(new SceneAgentMap { - scenePath = TestScenePath, agent = CreateDoNothingAgent(AgentName) + scenePath = TestScenePath, agent = CreateSpyAliveCountAgent(AgentName) }); SetUpDispatcher(settings); await LoadTestSceneAsync(TestScenePath); - var actual = FindAliveAgentNames(); - Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); + var gameObject = GameObject.Find(AgentName); + Assert.That(gameObject, Is.Not.Null); + Assert.That(SpyAliveCountAgent.AliveInstances, Is.EqualTo(1)); } [Test] @@ -109,13 +105,14 @@ public async Task DispatchByScene_DispatchFallbackAgent() { const string AgentName = "Fallback Agent"; var settings = CreateAutopilotSettings(); - settings.fallbackAgent = CreateDoNothingAgent(AgentName); + settings.fallbackAgent = CreateSpyAliveCountAgent(AgentName); SetUpDispatcher(settings); await LoadTestSceneAsync(TestScenePath); - var actual = FindAliveAgentNames(); - Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); + var gameObject = GameObject.Find(AgentName); + Assert.That(gameObject, Is.Not.Null); + Assert.That(SpyAliveCountAgent.AliveInstances, Is.EqualTo(1)); } [Test] @@ -126,9 +123,8 @@ public async Task DispatchByScene_NoSceneAgentMapsAndFallbackAgent_AgentIsNotDis await LoadTestSceneAsync(TestScenePath); - var actual = FindAliveAgentNames(); - Assert.That(actual, Is.Empty); LogAssert.Expect(LogType.Warning, "Agent not found by scene: Buttons"); + Assert.That(SpyAliveCountAgent.AliveInstances, Is.EqualTo(0)); } [Test] @@ -136,13 +132,14 @@ public async Task DispatchByScene_DispatchObserverAgent() { const string AgentName = "Observer Agent"; var settings = CreateAutopilotSettings(); - settings.observerAgent = CreateDoNothingAgent(AgentName); + settings.observerAgent = CreateSpyAliveCountAgent(AgentName); SetUpDispatcher(settings); await LoadTestSceneAsync(TestScenePath); - var actual = FindAliveAgentNames(); - Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); + var gameObject = GameObject.Find(AgentName); + Assert.That(gameObject, Is.Not.Null); + Assert.That(SpyAliveCountAgent.AliveInstances, Is.EqualTo(1)); } [Test] @@ -152,22 +149,19 @@ public async Task DispatchByScene_ReActivateScene_NotCreateDuplicateAgents() var settings = CreateAutopilotSettings(); settings.sceneAgentMaps.Add(new SceneAgentMap { - scenePath = TestScenePath, agent = CreateDoNothingAgent(AgentName) + scenePath = TestScenePath, agent = CreateSpyAliveCountAgent(AgentName) }); SetUpDispatcher(settings); var scene = await LoadTestSceneAsync(TestScenePath); - - var agents = FindAliveAgentNames(); - Assume.That(agents, Is.EquivalentTo(new[] { AgentName })); + Assume.That(SpyAliveCountAgent.AliveInstances, Is.EqualTo(1)); var additiveScene = await LoadTestSceneAsync(TestScenePath2, LoadSceneMode.Additive); SceneManager.SetActiveScene(additiveScene); SceneManager.SetActiveScene(scene); // Re-activate - var actual = FindAliveAgentNames(); - Assert.That(actual, Is.EquivalentTo(new[] { AgentName })); + Assert.That(SpyAliveCountAgent.AliveInstances, Is.EqualTo(1)); // Not create duplicate agents } } } diff --git a/Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs b/Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs new file mode 100644 index 0000000..1f449f0 --- /dev/null +++ b/Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2023-2024 DeNA Co., Ltd. +// This software is released under the MIT License. + +using System.Threading; +using Cysharp.Threading.Tasks; +using DeNA.Anjin.Agents; +using UnityEngine; + +namespace DeNA.Anjin.TestDoubles +{ + /// + /// Spy agent that count the number of alive instances. + /// + [AddComponentMenu("")] + // ReSharper disable once RequiredBaseTypesIsNotInherited + public class SpyAliveCountAgent : AbstractAgent + { + public static int AliveInstances { get; private set; } + + public override async UniTask Run(CancellationToken token) + { + AliveInstances++; + try + { + await UniTask.WaitWhile(() => true, cancellationToken: token); // Wait indefinitely + } + finally + { + AliveInstances--; + } + } + } +} diff --git a/Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs.meta b/Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs.meta new file mode 100644 index 0000000..d169139 --- /dev/null +++ b/Tests/Runtime/TestDoubles/SpyAliveCountAgent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a45a8161cc09438b9b33c7a670e39335 +timeCreated: 1713821110 \ No newline at end of file From 4d8988375871d10a2e36971112b97eab5a1cb201 Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Tue, 23 Apr 2024 06:46:40 +0900 Subject: [PATCH 8/8] Fix using directive --- Tests/Runtime/AgentDispatcherTest.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Tests/Runtime/AgentDispatcherTest.cs b/Tests/Runtime/AgentDispatcherTest.cs index cb5f19b..9d88356 100644 --- a/Tests/Runtime/AgentDispatcherTest.cs +++ b/Tests/Runtime/AgentDispatcherTest.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Threading.Tasks; using Cysharp.Threading.Tasks; -using Cysharp.Threading.Tasks.Triggers; using DeNA.Anjin.Agents; using DeNA.Anjin.Settings; using DeNA.Anjin.TestDoubles;