From 8bfc4e3c0302c5dd81ab1891e80fb75b5f71882e Mon Sep 17 00:00:00 2001 From: Peter Klooster Date: Fri, 4 Oct 2024 13:29:02 +0200 Subject: [PATCH 1/2] Fix: pipeline breaking (hopefully) --- .../UnitTests/AgentBehaviourTests.cs | 10 ++++++++++ .../UnitTests/ClassResolverTests.cs | 6 ++++++ .../UnitTests/ConditionObserverTests.cs | 10 ++++++++++ .../UnitTests/GoapSetJobRunnerTests.cs | 13 +++++++++++++ .../UnitTests/GraphResolverTests.cs | 10 ++++++++++ .../UnitTests/SensorRunnerTests.cs | 10 ++++++++++ 6 files changed, 59 insertions(+) diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs index 0f9ec4fc..09c911ca 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs @@ -10,11 +10,21 @@ using NSubstitute; using NUnit.Framework; using UnityEngine; +using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests { public class AgentBehaviourTests { + [SetUp] + public void Setup() + { + // Unity sometimes thinks that a temporary job is leaking memory + // This is not the case, so we ignore the message + // This can trigger in any test, even the ones that don't use the Job system + LogAssert.ignoreFailingMessages = true; + } + [Test] public void OnEnable_CallsRegister() { diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs index 6909a51f..17f299db 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs @@ -7,6 +7,7 @@ using CrashKonijn.Goap.UnitTests.Support; using FluentAssertions; using NUnit.Framework; +using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests { @@ -18,6 +19,11 @@ public class ClassResolverTests public void Init() { this.factory.Setup(); + + // Unity sometimes thinks that a temporary job is leaking memory + // This is not the case, so we ignore the message + // This can trigger in any test, even the ones that don't use the Job system + LogAssert.ignoreFailingMessages = true; } [Test] diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs index cacb2fa8..215bceb2 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs @@ -3,11 +3,21 @@ using CrashKonijn.Goap.Observers; using CrashKonijn.Goap.Resolver; using NUnit.Framework; +using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests { public class ConditionObserverTests { + [SetUp] + public void Setup() + { + // Unity sometimes thinks that a temporary job is leaking memory + // This is not the case, so we ignore the message + // This can trigger in any test, even the ones that don't use the Job system + LogAssert.ignoreFailingMessages = true; + } + [Test] public void IsMet_Positive_IsPresent() { diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs index 2f749735..fe61b89e 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs @@ -7,12 +7,23 @@ using NSubstitute; using NSubstitute.ReturnsExtensions; using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; using ICondition = CrashKonijn.Goap.Interfaces.ICondition; namespace CrashKonijn.Goap.UnitTests { public class GoapSetJobRunnerTests { + [SetUp] + public void Setup() + { + // Unity sometimes thinks that a temporary job is leaking memory + // This is not the case, so we ignore the message + // This can trigger in any test, even the ones that don't use the Job system + LogAssert.ignoreFailingMessages = true; + } + [Test] public void Run_UpdatesSensorRunner() { @@ -252,6 +263,7 @@ public void Run_AgentHasCurrentGoalAndNoAction_SetsTheActionOnAgent() // Act runner.Run(); runner.Complete(); + runner.Dispose(); // Assert agent.Received(1).SetAction(action, Arg.Any>(), Arg.Any()); @@ -289,6 +301,7 @@ public void Run_AgentHasCurrentGoalAndAction_ResolvingSameActionDoesntCallSet() // Act runner.Run(); runner.Complete(); + runner.Dispose(); // Assert agent.Received(0).SetAction(Arg.Any(), Arg.Any>(), Arg.Any()); diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs index 6bfa1a7e..008915ed 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs @@ -8,6 +8,7 @@ using Unity.Collections; using Unity.Mathematics; using UnityEngine; +using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests { @@ -26,6 +27,15 @@ public TestAction(string name) } } + [SetUp] + public void Setup() + { + // Unity sometimes thinks that a temporary job is leaking memory + // This is not the case, so we ignore the message + // This can trigger in any test, even the ones that don't use the Job system + LogAssert.ignoreFailingMessages = true; + } + [Test] public void Resolve_WithNoActions_ReturnsEmptyList() { diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs index e9dbe7ea..0434ba1f 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs @@ -7,11 +7,21 @@ using NSubstitute; using NSubstitute.ReturnsExtensions; using NUnit.Framework; +using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests { public class SensorRunnerTests { + [SetUp] + public void Setup() + { + // Unity sometimes thinks that a temporary job is leaking memory + // This is not the case, so we ignore the message + // This can trigger in any test, even the ones that don't use the Job system + LogAssert.ignoreFailingMessages = true; + } + // Global [Test] public void SenseGlobal_WithPositiveWorldSense_IsPresentInStates() From d979a884906cc6662792d8c0581db0ad471f6e90 Mon Sep 17 00:00:00 2001 From: Peter Klooster Date: Fri, 4 Oct 2024 13:53:01 +0200 Subject: [PATCH 2/2] Should disable leak detection --- .../UnitTests/AgentBehaviourTests.cs | 182 +++++++------- .../UnitTests/ClassResolverTests.cs | 20 +- .../UnitTests/ConditionObserverTests.cs | 30 +-- .../UnitTests/GoapSetJobRunnerTests.cs | 149 +++++------ .../UnitTests/GraphResolverTests.cs | 231 +++++++++--------- .../UnitTests/SensorRunnerTests.cs | 105 ++++---- 6 files changed, 363 insertions(+), 354 deletions(-) diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs index 09c911ca..c273cb53 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/AgentBehaviourTests.cs @@ -9,6 +9,7 @@ using FluentAssertions; using NSubstitute; using NUnit.Framework; +using Unity.Collections; using UnityEngine; using UnityEngine.TestTools; @@ -23,8 +24,9 @@ public void Setup() // This is not the case, so we ignore the message // This can trigger in any test, even the ones that don't use the Job system LogAssert.ignoreFailingMessages = true; + NativeLeakDetection.Mode = NativeLeakDetectionMode.Disabled; } - + [Test] public void OnEnable_CallsRegister() { @@ -43,10 +45,10 @@ public void OnEnable_CallsRegister() goapSet.Received(1).Register(agent); act(); - + goapSet.Received(2).Register(agent); } - + [Test] public void OnDisable_CallsUnregister() { @@ -54,30 +56,30 @@ public void OnDisable_CallsUnregister() var goapSet = Substitute.For(); var agent = new GameObject("Agent").AddComponent(); agent.GoapSet = goapSet; - + // Act Action act = () => { agent.CallOnDisable(); }; - + // Assert goapSet.Received(0).Unregister(agent); - + act(); - + goapSet.Received(1).Unregister(agent); } - + [Test] public void Run_WithoutAction_SetsStateToNoAction() { // Arrange var agent = new GameObject("Agent").AddComponent(); - + // Act agent.Run(); - + // Assert agent.State.Should().Be(AgentState.NoAction); } @@ -92,10 +94,10 @@ public void Run_MoveBeforePerforming_WithActionAndTooMuchDistance_SetsStateToMov var action = Substitute.For(); action.Config.MoveMode.Returns(ActionMoveMode.MoveBeforePerforming); agent.SetAction(action, new List(), new PositionTarget(Vector3.up * 100f)); - + // Act agent.Run(); - + // Assert agent.State.Should().Be(AgentState.MovingToTarget); } @@ -111,10 +113,10 @@ public void Run_MoveBeforePerforming_WithActionAndTooMuchDistance_CallsMover() action.Config.MoveMode.Returns(ActionMoveMode.MoveBeforePerforming); agent.SetAction(action, new List(), new PositionTarget(Vector3.up * 100f)); agent.MockEvents(); - + // Act agent.Run(); - + // Assert agent.Events.Received(1).Move(Arg.Any()); action.Received(0).Perform(agent, Arg.Any(), Arg.Any()); @@ -126,17 +128,17 @@ public void Run_MoveBeforePerforming_WithCloseAction_CallsActionPerform() // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var action = Substitute.For(); action.Config.MoveMode.Returns(ActionMoveMode.MoveBeforePerforming); action.IsInRange(agent, Arg.Any(), Arg.Any(), Arg.Any()).Returns(true); action.Perform(agent, Arg.Any(), Arg.Any()).Returns(ActionRunState.Continue); agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); agent.MockEvents(); - + // Act agent.Run(); - + // Assert agent.Events.Received(0).Move(Arg.Any()); action.Received(1).Perform(agent, Arg.Any(), Arg.Any()); @@ -149,14 +151,14 @@ public void Run_PerformWhileMoving_WithActionAndTooMuchDistance_SetsStateToMovin // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var action = Substitute.For(); action.Config.MoveMode.Returns(ActionMoveMode.PerformWhileMoving); agent.SetAction(action, new List(), new PositionTarget(Vector3.up * 100f)); - + // Act agent.Run(); - + // Assert agent.State.Should().Be(AgentState.MovingWhilePerformingAction); } @@ -172,10 +174,10 @@ public void Run_PerformWhileMoving_WithActionAndTooMuchDistance_CallsMoverAndAct action.Config.MoveMode.Returns(ActionMoveMode.PerformWhileMoving); agent.SetAction(action, new List(), new PositionTarget(Vector3.up * 100f)); agent.MockEvents(); - + // Act agent.Run(); - + // Assert agent.Events.Received(1).Move(Arg.Any()); action.Received(1).Perform(agent, Arg.Any(), Arg.Any()); @@ -194,10 +196,10 @@ public void Run_PerformWhileMoving_WithCloseAction_CallsActionPerform() action.Perform(agent, Arg.Any(), Arg.Any()).Returns(ActionRunState.Continue); agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); agent.MockEvents(); - + // Act agent.Run(); - + // Assert agent.Events.Received(0).Move(Arg.Any()); action.Received(1).Perform(agent, Arg.Any(), Arg.Any()); @@ -212,15 +214,15 @@ public void ActionPerform_WithRunStateStop_CallsEnd() var agent = new GameObject("Agent").AddComponent(); agent.GoapSet = goapSet; agent.CallAwake(); - + var action = Substitute.For(); action.IsInRange(agent, Arg.Any(), Arg.Any(), Arg.Any()).Returns(true); action.Perform(agent, Arg.Any(), Arg.Any()).Returns(ActionRunState.Stop); agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); - + // Act agent.Run(); - + // Assert action.Received(1).Perform(agent, Arg.Any(), Arg.Any()); action.Received(1).End(agent, Arg.Any()); @@ -232,13 +234,13 @@ public void SetGoal_SetsGoal() // Arrange var goapSet = Substitute.For(); goapSet.ResolveGoal().Returns(new TestGoal()); - + var agent = new GameObject("Agent").AddComponent(); agent.GoapSet = goapSet; - + // Act agent.SetGoal(false); - + // Assert agent.CurrentGoal.Should().BeOfType(); } @@ -249,13 +251,13 @@ public void SetGoal_EnqueuesAgent() // Arrange var goapSet = Substitute.For(); goapSet.ResolveGoal().Returns(new TestGoal()); - + var agent = new GameObject("Agent").AddComponent(); agent.GoapSet = goapSet; - + // Act agent.SetGoal(false); - + // Assert goapSet.Agents.Received(1).Enqueue(agent); } @@ -266,76 +268,76 @@ public void SetGoal_CallsGoalStartEvent() // Arrange var goapSet = Substitute.For(); goapSet.ResolveGoal().Returns(new TestGoal()); - + var agent = new GameObject("Agent").AddComponent(); agent.GoapSet = goapSet; agent.MockEvents(); - + // Act agent.SetGoal(false); - + // Assert agent.Events.Received(1).GoalStart(Arg.Any()); } - + [Test] public void SetGoal_EndActionFalse_DoesntCallEnd() { // Arrange var goapSet = Substitute.For(); goapSet.ResolveGoal().Returns(new TestGoal()); - + var agent = new GameObject("Agent").AddComponent(); agent.GoapSet = goapSet; - + // Set Action property through reflection var action = Substitute.For(); agent.InsertAction(action); - + // Act agent.SetGoal(false); - + // Assert action.Received(0).End(Arg.Any(), Arg.Any()); } - + [Test] public void SetGoal_EndActionTrue_DoesCallEnd() { // Arrange var goapSet = Substitute.For(); goapSet.ResolveGoal().Returns(new TestGoal()); - + var agent = new GameObject("Agent").AddComponent(); agent.GoapSet = goapSet; - + // Set Action property through reflection var action = Substitute.For(); agent.InsertAction(action); - + // Act agent.SetGoal(true); - + // Assert action.Received(1).End(Arg.Any(), Arg.Any()); } - + [Test] public void SetAction_SetsAction() { // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var action = Substitute.For(); - + // Act agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); - + // Assert agent.CurrentAction.Should().Be(action); } - + [Test] public void SetAction_CallsEndOnOldAction() { @@ -346,108 +348,108 @@ public void SetAction_CallsEndOnOldAction() agent.CallAwake(); var action = Substitute.For(); - + // Set Action property through reflection var oldAction = Substitute.For(); agent.InsertAction(oldAction); - + // Act agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); - + // Assert oldAction.Received(1).End(agent, Arg.Any()); } - + [Test] public void SetAction_CallsGetData() { // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var action = Substitute.For(); - + // Act agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); - + // Assert action.Received(1).GetData(); } - + [Test] public void SetAction_StoresData() { // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var actionData = Substitute.For(); var action = Substitute.For(); action.GetData().Returns(actionData); - + // Act agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); - + // Assert agent.CurrentActionData.Should().Be(actionData); } - + [Test] public void SetAction_SetsDataTarget() { // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var actionData = Substitute.For(); var action = Substitute.For(); action.GetData().Returns(actionData); var target = new PositionTarget(Vector3.zero); - + // Act agent.SetAction(action, new List(), target); - + // Assert actionData.Target.Should().Be(target); } - + [Test] public void SetAction_CallsStartOnAction() { // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var action = Substitute.For(); // Act agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); - + // Assert action.Received(1).Start(agent, Arg.Any()); } - + [Test] public void SetAction_StoresPath() { // Arrange var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); - + var action = Substitute.For(); var path = new List { - Substitute.For() + Substitute.For(), }; - + // Act agent.SetAction(action, path, new PositionTarget(Vector3.zero)); - + // Assert agent.CurrentActionPath.Should().BeSameAs(path); } - + [Test] public void SetAction_CallsActionStartEvent() { @@ -457,14 +459,14 @@ public void SetAction_CallsActionStartEvent() agent.MockEvents(); var action = Substitute.For(); - + // Act agent.SetAction(action, new List(), new PositionTarget(Vector3.zero)); - + // Assert agent.Events.Received(1).ActionStart(action); } - + [Test] public void EndAction_CallsEndOnAction() { @@ -473,17 +475,17 @@ public void EndAction_CallsEndOnAction() var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); agent.GoapSet = set; - + var action = Substitute.For(); agent.InsertAction(action); - + // Act agent.EndAction(); - + // Assert action.Received(1).End(agent, Arg.Any()); } - + [Test] public void EndAction_ClearsAction() { @@ -496,11 +498,11 @@ public void EndAction_ClearsAction() // Act agent.SetAction(Substitute.For(), new List(), new PositionTarget(Vector3.zero)); agent.EndAction(); - + // Assert agent.CurrentAction.Should().BeNull(); } - + [Test] public void EndAction_ClearsActionData() { @@ -513,7 +515,7 @@ public void EndAction_ClearsActionData() // Act agent.SetAction(Substitute.For(), new List(), new PositionTarget(Vector3.zero)); agent.EndAction(); - + // Assert agent.CurrentActionData.Should().BeNull(); } @@ -526,14 +528,14 @@ public void EndAction_ShouldEnqueueAgent() var agent = new GameObject("Agent").AddComponent(); agent.CallAwake(); agent.GoapSet = set; - + // Act agent.EndAction(); - + // Assert set.Agents.Received(1).Enqueue(agent); } - + [Test] public void EndAction_CallsActionEndEvent() { @@ -549,9 +551,9 @@ public void EndAction_CallsActionEndEvent() // Act agent.EndAction(); - + // Assert agent.Events.Received(1).ActionStop(action); } } -} \ No newline at end of file +} diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs index 17f299db..d2c79f01 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ClassResolverTests.cs @@ -7,6 +7,7 @@ using CrashKonijn.Goap.UnitTests.Support; using FluentAssertions; using NUnit.Framework; +using Unity.Collections; using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests @@ -14,18 +15,19 @@ namespace CrashKonijn.Goap.UnitTests public class ClassResolverTests { private TestMockFactory factory = new(); - + [SetUp] public void Init() { this.factory.Setup(); - + // Unity sometimes thinks that a temporary job is leaking memory // This is not the case, so we ignore the message // This can trigger in any test, even the ones that don't use the Job system LogAssert.ignoreFailingMessages = true; + NativeLeakDetection.Mode = NativeLeakDetectionMode.Disabled; } - + [Test] public void Load_LoadsGoal() { @@ -33,12 +35,12 @@ public void Load_LoadsGoal() var resolver = this.factory.Get(); // Act - var result = resolver.Load(new []{ GoalConfig.Create() }); + var result = resolver.Load(new[] { GoalConfig.Create() }); // Assert result.First().Should().BeOfType(); } - + [Test] public void Load_LoadsTargetSensorConfig() { @@ -46,12 +48,12 @@ public void Load_LoadsTargetSensorConfig() var resolver = this.factory.Get(); // Act - var result = resolver.Load(new []{ new TargetSensorConfig() }); + var result = resolver.Load(new[] { new TargetSensorConfig() }); // Assert result.First().Should().BeOfType(); } - + [Test] public void Load_LoadsWorldSensorConfig() { @@ -59,10 +61,10 @@ public void Load_LoadsWorldSensorConfig() var resolver = this.factory.Get(); // Act - var result = resolver.Load(new []{ new WorldSensorConfig() }); + var result = resolver.Load(new[] { new WorldSensorConfig() }); // Assert result.First().Should().BeOfType(); } } -} \ No newline at end of file +} diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs index 215bceb2..04130c53 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ConditionObserverTests.cs @@ -3,6 +3,7 @@ using CrashKonijn.Goap.Observers; using CrashKonijn.Goap.Resolver; using NUnit.Framework; +using Unity.Collections; using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests @@ -16,8 +17,9 @@ public void Setup() // This is not the case, so we ignore the message // This can trigger in any test, even the ones that don't use the Job system LogAssert.ignoreFailingMessages = true; + NativeLeakDetection.Mode = NativeLeakDetectionMode.Disabled; } - + [Test] public void IsMet_Positive_IsPresent() { @@ -25,15 +27,15 @@ public void IsMet_Positive_IsPresent() var key = new WorldKey("world-key"); var worldData = new GlobalWorldData(); worldData.SetState(key, 1); - + var observer = new ConditionObserver(); observer.SetWorldData(worldData); - + var condition = new Condition { Comparison = Comparison.GreaterThanOrEqual, Amount = 1, - WorldKey = key + WorldKey = key, }; // Act @@ -42,7 +44,7 @@ public void IsMet_Positive_IsPresent() // Assert Assert.IsTrue(result); } - + [Test] public void IsMet_Positive_IsNotPresent() { @@ -51,12 +53,12 @@ public void IsMet_Positive_IsNotPresent() var worldData = new GlobalWorldData(); var observer = new ConditionObserver(); observer.SetWorldData(worldData); - + var condition = new Condition { Comparison = Comparison.GreaterThanOrEqual, Amount = 1, - WorldKey = key + WorldKey = key, }; // Act @@ -65,7 +67,7 @@ public void IsMet_Positive_IsNotPresent() // Assert Assert.IsFalse(result); } - + [Test] public void IsMet_Negative_IsPresent() { @@ -73,15 +75,15 @@ public void IsMet_Negative_IsPresent() var key = new WorldKey("world-key"); var worldData = new GlobalWorldData(); worldData.SetState(key, 1); - + var observer = new ConditionObserver(); observer.SetWorldData(worldData); - + var condition = new Condition { Comparison = Comparison.SmallerThan, Amount = 1, - WorldKey = key + WorldKey = key, }; // Act @@ -90,7 +92,7 @@ public void IsMet_Negative_IsPresent() // Assert Assert.IsFalse(result); } - + [Test] public void IsMet_Negative_IsNotPresent() { @@ -99,12 +101,12 @@ public void IsMet_Negative_IsNotPresent() var worldData = new GlobalWorldData(); var observer = new ConditionObserver(); observer.SetWorldData(worldData); - + var condition = new Condition { Comparison = Comparison.SmallerThanOrEqual, Amount = 0, - WorldKey = key + WorldKey = key, }; // Act diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs index fe61b89e..67f6e339 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GoapSetJobRunnerTests.cs @@ -7,7 +7,7 @@ using NSubstitute; using NSubstitute.ReturnsExtensions; using NUnit.Framework; -using UnityEngine; +using Unity.Collections; using UnityEngine.TestTools; using ICondition = CrashKonijn.Goap.Interfaces.ICondition; @@ -22,8 +22,9 @@ public void Setup() // This is not the case, so we ignore the message // This can trigger in any test, even the ones that don't use the Job system LogAssert.ignoreFailingMessages = true; + NativeLeakDetection.Mode = NativeLeakDetectionMode.Disabled; } - + [Test] public void Run_UpdatesSensorRunner() { @@ -35,17 +36,17 @@ public void Run_UpdatesSensorRunner() goapSet.GoapConfig.Returns(GoapConfig.Default); var resolver = Substitute.For(); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Dispose(); - + // Assert sensorRunner.Received(1).Update(); } - + [Test] public void Run_SensesGlobalSensors() { @@ -55,15 +56,15 @@ public void Run_SensesGlobalSensors() goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List()); goapSet.GoapConfig.Returns(GoapConfig.Default); - + var resolver = Substitute.For(); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Dispose(); - + // Assert sensorRunner.Received(1).SenseGlobal(); } @@ -75,23 +76,23 @@ public void Run_AgentHasNoCurrentGoal_DoesNotRun() var agent = Substitute.For(); agent.CurrentGoal.ReturnsNull(); agent.CurrentAction.ReturnsNull(); - + var sensorRunner = Substitute.For(); sensorRunner.SenseGlobal().Returns(new GlobalWorldData()); - + var goapSet = Substitute.For(); goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List { }); goapSet.GoapConfig.Returns(GoapConfig.Default); - + var resolver = Substitute.For(); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Dispose(); - + // Assert sensorRunner.Received(0).SenseLocal(Arg.Any(), agent); resolver.Received(0).StartResolve(Arg.Any()); @@ -102,60 +103,60 @@ public void Run_AgentHasCurrentGoalAndNoAction_Runs() { // Arrange var goal = Substitute.For(); - goal.Conditions.Returns(new CrashKonijn.Goap.Resolver.Interfaces.ICondition[] { Substitute.For() }); - + goal.Conditions.Returns(new Resolver.Interfaces.ICondition[] { Substitute.For() }); + var agent = Substitute.For(); agent.CurrentGoal.Returns(goal); agent.CurrentAction.ReturnsNull(); - + var sensorRunner = Substitute.For(); - + var goapSet = Substitute.For(); goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List { goal }); - goapSet.Agents.GetQueue().Returns(new []{ agent }); + goapSet.Agents.GetQueue().Returns(new[] { agent }); goapSet.GetActions().Returns(new List()); - + var resolver = Substitute.For(); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Dispose(); - + // Assert sensorRunner.Received(1).SenseLocal(Arg.Any(), agent); resolver.Received(1).StartResolve(Arg.Any()); } - + [Test] public void Run_AgentHasCurrentGoalAndDoesHaveAction_Runs() { // Arrange var goal = Substitute.For(); - goal.Conditions.Returns(new CrashKonijn.Goap.Resolver.Interfaces.ICondition[] { Substitute.For() }); - + goal.Conditions.Returns(new Resolver.Interfaces.ICondition[] { Substitute.For() }); + var agent = Substitute.For(); agent.CurrentGoal.Returns(goal); agent.CurrentAction.Returns(Substitute.For()); - + var sensorRunner = Substitute.For(); - + var goapSet = Substitute.For(); goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List { goal }); - goapSet.Agents.GetQueue().Returns(new []{ agent }); + goapSet.Agents.GetQueue().Returns(new[] { agent }); goapSet.GetActions().Returns(new List()); - + var resolver = Substitute.For(); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Dispose(); - + // Assert sensorRunner.Received(1).SenseLocal(Arg.Any(), agent); resolver.Received(1).StartResolve(Arg.Any()); @@ -166,30 +167,30 @@ public void Run_AgentHasCompletedGoal_CallsGoalCompleteEvent() { // Arrange var goal = Substitute.For(); - goal.Conditions.Returns(new CrashKonijn.Goap.Resolver.Interfaces.ICondition[] { Substitute.For() }); - + goal.Conditions.Returns(new Resolver.Interfaces.ICondition[] { Substitute.For() }); + var agent = Substitute.For(); agent.CurrentGoal.Returns(goal); agent.CurrentAction.ReturnsNull(); - + var sensorRunner = Substitute.For(); - + var goapSet = Substitute.For(); goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List { goal }); - goapSet.Agents.GetQueue().Returns(new []{ agent }); + goapSet.Agents.GetQueue().Returns(new[] { agent }); goapSet.GetActions().Returns(new List()); goapSet.GoapConfig.ConditionObserver.IsMet(Arg.Any()).Returns(true); - + var resolver = Substitute.For(); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Dispose(); - + // Assert sensorRunner.Received(1).SenseLocal(Arg.Any(), agent); resolver.Received(0).StartResolve(Arg.Any()); @@ -201,110 +202,110 @@ public void Run_AgentHasNotCompletedGoal_DoesntCallGoalCompleteEvent() { // Arrange var goal = Substitute.For(); - goal.Conditions.Returns(new CrashKonijn.Goap.Resolver.Interfaces.ICondition[] { Substitute.For() }); - + goal.Conditions.Returns(new Resolver.Interfaces.ICondition[] { Substitute.For() }); + var agent = Substitute.For(); agent.CurrentGoal.Returns(goal); agent.CurrentAction.ReturnsNull(); - + var sensorRunner = Substitute.For(); - + var goapSet = Substitute.For(); goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List { goal }); - goapSet.Agents.GetQueue().Returns(new []{ agent }); + goapSet.Agents.GetQueue().Returns(new[] { agent }); goapSet.GetActions().Returns(new List()); goapSet.GoapConfig.ConditionObserver.IsMet(Arg.Any()).Returns(false); - + var resolver = Substitute.For(); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Dispose(); - + // Assert sensorRunner.Received(1).SenseLocal(Arg.Any(), agent); resolver.Received(1).StartResolve(Arg.Any()); agent.Events.Received(0).GoalCompleted(agent.CurrentGoal); } - + [Test] public void Run_AgentHasCurrentGoalAndNoAction_SetsTheActionOnAgent() { // Arrange var goal = Substitute.For(); - goal.Conditions.Returns(new CrashKonijn.Goap.Resolver.Interfaces.ICondition[] { Substitute.For() }); + goal.Conditions.Returns(new Resolver.Interfaces.ICondition[] { Substitute.For() }); var action = Substitute.For(); - + var agent = Substitute.For(); agent.CurrentGoal.Returns(goal); agent.CurrentAction.ReturnsNull(); - + var sensorRunner = Substitute.For(); - + var goapSet = Substitute.For(); goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List { goal }); - goapSet.Agents.GetQueue().Returns(new []{ agent }); + goapSet.Agents.GetQueue().Returns(new[] { agent }); goapSet.GetActions().Returns(new List()); var handle = Substitute.For(); handle.Complete().Returns(new IAction[] { action }); - + var resolver = Substitute.For(); resolver.StartResolve(Arg.Any()).Returns(handle); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Complete(); runner.Dispose(); - + // Assert agent.Received(1).SetAction(action, Arg.Any>(), Arg.Any()); } - + [Test] public void Run_AgentHasCurrentGoalAndAction_ResolvingSameActionDoesntCallSet() { // Arrange var goal = Substitute.For(); - goal.Conditions.Returns(new CrashKonijn.Goap.Resolver.Interfaces.ICondition[] { Substitute.For() }); + goal.Conditions.Returns(new Resolver.Interfaces.ICondition[] { Substitute.For() }); var action = Substitute.For(); - + var agent = Substitute.For(); agent.CurrentGoal.Returns(goal); agent.CurrentAction.Returns(action); - + var sensorRunner = Substitute.For(); - + var goapSet = Substitute.For(); goapSet.SensorRunner.Returns(sensorRunner); goapSet.GetAllNodes().Returns(new List { goal }); - goapSet.Agents.GetQueue().Returns(new []{ agent }); + goapSet.Agents.GetQueue().Returns(new[] { agent }); goapSet.GetActions().Returns(new List()); var handle = Substitute.For(); handle.Complete().Returns(new IAction[] { action }); - + var resolver = Substitute.For(); resolver.StartResolve(Arg.Any()).Returns(handle); - + var runner = new GoapSetJobRunner(goapSet, resolver); - + // Act runner.Run(); runner.Complete(); runner.Dispose(); - + // Assert agent.Received(0).SetAction(Arg.Any(), Arg.Any>(), Arg.Any()); } } -} \ No newline at end of file +} diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs index 008915ed..81b31eb4 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/GraphResolverTests.cs @@ -18,15 +18,15 @@ private class TestAction : IAction { public string Name { get; } public Guid Guid { get; } = Guid.NewGuid(); - public IEffect[] Effects { get; set; } = {}; - public ICondition[] Conditions { get; set; } = {}; + public IEffect[] Effects { get; set; } = { }; + public ICondition[] Conditions { get; set; } = { }; public TestAction(string name) { this.Name = name; } } - + [SetUp] public void Setup() { @@ -34,35 +34,36 @@ public void Setup() // This is not the case, so we ignore the message // This can trigger in any test, even the ones that don't use the Job system LogAssert.ignoreFailingMessages = true; + NativeLeakDetection.Mode = NativeLeakDetectionMode.Disabled; } - + [Test] public void Resolve_WithNoActions_ReturnsEmptyList() { // Arrange var actions = Array.Empty(); var resolver = new GraphResolver(actions, new TestKeyResolver()); - + // Act var handle = resolver.StartResolve(new RunData { StartIndex = 0, - IsExecutable = new NativeArray(new [] { false }, Allocator.TempJob), - Positions = new NativeArray(new [] { float3.zero }, Allocator.TempJob), - Costs = new NativeArray(new []{ 1f }, Allocator.TempJob), - ConditionsMet = new NativeArray(new [] { false }, Allocator.TempJob), - DistanceMultiplier = 1f + IsExecutable = new NativeArray(new[] { false }, Allocator.TempJob), + Positions = new NativeArray(new[] { float3.zero }, Allocator.TempJob), + Costs = new NativeArray(new[] { 1f }, Allocator.TempJob), + ConditionsMet = new NativeArray(new[] { false }, Allocator.TempJob), + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); // Assert result.Should().BeEmpty(); } - + [Test] public void Resolve_WithOneExecutableConnection_ReturnsAction() { @@ -70,29 +71,29 @@ public void Resolve_WithOneExecutableConnection_ReturnsAction() var connection = new TestConnection("connection"); var goal = new TestAction("goal") { - Conditions = new ICondition[] { connection } + Conditions = new ICondition[] { connection }, }; var action = new TestAction("action") { - Effects = new IEffect[] { connection } + Effects = new IEffect[] { connection }, }; - + var actions = new IAction[] { goal, action }; var resolver = new GraphResolver(actions, new TestKeyResolver()); - + // Act var handle = resolver.StartResolve(new RunData { StartIndex = 0, - IsExecutable = new NativeArray(new [] { false, true }, Allocator.TempJob), - Positions = new NativeArray(new []{ float3.zero, float3.zero }, Allocator.TempJob), - Costs = new NativeArray(new []{ 1f, 1f }, Allocator.TempJob), - ConditionsMet = new NativeArray(new [] { false }, Allocator.TempJob), - DistanceMultiplier = 1f + IsExecutable = new NativeArray(new[] { false, true }, Allocator.TempJob), + Positions = new NativeArray(new[] { float3.zero, float3.zero }, Allocator.TempJob), + Costs = new NativeArray(new[] { 1f, 1f }, Allocator.TempJob), + ConditionsMet = new NativeArray(new[] { false }, Allocator.TempJob), + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); @@ -100,46 +101,46 @@ public void Resolve_WithOneExecutableConnection_ReturnsAction() result.Should().HaveCount(1); result.First().Should().Be(action); } - + [Test] public void Resolve_WithMultipleConnections_ReturnsExecutableAction() { // Arrange var connection = new TestConnection("connection"); - + var goal = new TestAction("goal") { - Conditions = new ICondition[] { connection } + Conditions = new ICondition[] { connection }, }; var firstAction = new TestAction("action1") { - Effects = new IEffect[] { connection } + Effects = new IEffect[] { connection }, }; var secondAction = new TestAction("action2") { - Effects = new IEffect[] { connection } + Effects = new IEffect[] { connection }, }; var thirdAction = new TestAction("action3") { - Effects = new IEffect[] { connection } + Effects = new IEffect[] { connection }, }; - + var actions = new IAction[] { goal, firstAction, secondAction, thirdAction }; var resolver = new GraphResolver(actions, new TestKeyResolver()); - + // Act var handle = resolver.StartResolve(new RunData { StartIndex = 0, - IsExecutable = new NativeArray(new [] { false, false, false, true }, Allocator.TempJob), - Positions = new NativeArray(new []{ float3.zero, float3.zero, float3.zero, float3.zero }, Allocator.TempJob), - Costs = new NativeArray(new []{ 1f, 1f, 1f, 1f }, Allocator.TempJob), - ConditionsMet = new NativeArray(new []{ false }, Allocator.TempJob), - DistanceMultiplier = 1f + IsExecutable = new NativeArray(new[] { false, false, false, true }, Allocator.TempJob), + Positions = new NativeArray(new[] { float3.zero, float3.zero, float3.zero, float3.zero }, Allocator.TempJob), + Costs = new NativeArray(new[] { 1f, 1f, 1f, 1f }, Allocator.TempJob), + ConditionsMet = new NativeArray(new[] { false }, Allocator.TempJob), + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); @@ -147,7 +148,7 @@ public void Resolve_WithMultipleConnections_ReturnsExecutableAction() result.Should().HaveCount(1); result.First().Should().Be(thirdAction); } - + [Test] public void Resolve_WithNestedConnections_ReturnsExecutableAction() { @@ -155,50 +156,50 @@ public void Resolve_WithNestedConnections_ReturnsExecutableAction() var connection = new TestConnection("connection"); var connection2 = new TestConnection("connection2"); var connection3 = new TestConnection("connection3"); - + var goal = new TestAction("goal") { - Conditions = new ICondition[] { connection } + Conditions = new ICondition[] { connection }, }; var action1 = new TestAction("action1") { Effects = new IEffect[] { connection }, - Conditions = new ICondition[] { connection2 } + Conditions = new ICondition[] { connection2 }, }; var action2 = new TestAction("action2") { Effects = new IEffect[] { connection }, - Conditions = new ICondition[] { connection3 } + Conditions = new ICondition[] { connection3 }, }; var action11 = new TestAction("action11") { - Effects = new IEffect[] { connection2 } + Effects = new IEffect[] { connection2 }, }; var action22 = new TestAction("action22") { - Effects = new IEffect[] { connection3 } + Effects = new IEffect[] { connection3 }, }; - + var actions = new IAction[] { goal, action1, action2, action11, action22 }; var resolver = new GraphResolver(actions, new TestKeyResolver()); var executableBuilder = resolver.GetExecutableBuilder(); var conditionBuilder = resolver.GetConditionBuilder(); executableBuilder.SetExecutable(action11, true); - + // Act var handle = resolver.StartResolve(new RunData { StartIndex = 0, IsExecutable = new NativeArray(executableBuilder.Build(), Allocator.TempJob), - Positions = new NativeArray(new []{ float3.zero, float3.zero, float3.zero, float3.zero, float3.zero }, Allocator.TempJob), - Costs = new NativeArray(new []{ 1f, 1f, 1f, 1f, 1f }, Allocator.TempJob), + Positions = new NativeArray(new[] { float3.zero, float3.zero, float3.zero, float3.zero, float3.zero }, Allocator.TempJob), + Costs = new NativeArray(new[] { 1f, 1f, 1f, 1f, 1f }, Allocator.TempJob), ConditionsMet = new NativeArray(conditionBuilder.Build(), Allocator.TempJob), - DistanceMultiplier = 1f + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); @@ -214,21 +215,21 @@ public void Resolve_ShouldIncludeLocationHeuristics() var connection = new TestConnection("connection"); var connection1 = new TestConnection("connection1"); var connection2 = new TestConnection("connection2"); - + // Act var goal = new TestAction("goal") { - Conditions = new ICondition[] { connection } + Conditions = new ICondition[] { connection }, }; var action1 = new TestAction("action1") { Effects = new IEffect[] { connection }, - Conditions = new ICondition[] { connection1 } + Conditions = new ICondition[] { connection1 }, }; var action11 = new TestAction("action11") { Effects = new IEffect[] { connection1 }, - Conditions = new ICondition[] { connection2 } + Conditions = new ICondition[] { connection2 }, }; var action111 = new TestAction("action111") { @@ -237,18 +238,18 @@ public void Resolve_ShouldIncludeLocationHeuristics() var action2 = new TestAction("action2") { Effects = new IEffect[] { connection }, - Conditions = new ICondition[] { connection2 } + Conditions = new ICondition[] { connection2 }, }; - + var actions = new IAction[] { goal, action1, action2, action11, action111 }; var resolver = new GraphResolver(actions, new TestKeyResolver()); - + var executableBuilder = resolver.GetExecutableBuilder(); - + executableBuilder .SetExecutable(action111, true) .SetExecutable(action2, true); - + var positionBuilder = resolver.GetPositionBuilder(); positionBuilder @@ -257,10 +258,10 @@ public void Resolve_ShouldIncludeLocationHeuristics() .SetPosition(action11, new float3(3, 0, 0)) .SetPosition(action111, new float3(4, 0, 0)) .SetPosition(action2, new float3(10, 0, 0)); // far away from goal - + var costBuilder = resolver.GetCostBuilder(); var conditionBuilder = resolver.GetConditionBuilder(); - + // Act var handle = resolver.StartResolve(new RunData { @@ -269,11 +270,11 @@ public void Resolve_ShouldIncludeLocationHeuristics() Positions = new NativeArray(positionBuilder.Build(), Allocator.TempJob), Costs = new NativeArray(costBuilder.Build(), Allocator.TempJob), ConditionsMet = new NativeArray(conditionBuilder.Build(), Allocator.TempJob), - DistanceMultiplier = 1f + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); @@ -289,21 +290,21 @@ public void Resolve_ShouldIncludeCostHeuristics() var connection = new TestConnection("connection"); var connection1 = new TestConnection("connection1"); var connection2 = new TestConnection("connection2"); - + // Act var goal = new TestAction("goal") { - Conditions = new ICondition[] { connection } + Conditions = new ICondition[] { connection }, }; var action1 = new TestAction("action1") { Effects = new IEffect[] { connection }, - Conditions = new ICondition[] { connection1 } + Conditions = new ICondition[] { connection1 }, }; var action11 = new TestAction("action11") { Effects = new IEffect[] { connection1 }, - Conditions = new ICondition[] { connection2 } + Conditions = new ICondition[] { connection2 }, }; var action111 = new TestAction("action111") { @@ -312,27 +313,27 @@ public void Resolve_ShouldIncludeCostHeuristics() var action2 = new TestAction("action2") { Effects = new IEffect[] { connection }, - Conditions = new ICondition[] { connection2 } + Conditions = new ICondition[] { connection2 }, }; - + var actions = new IAction[] { goal, action1, action2, action11, action111 }; var resolver = new GraphResolver(actions, new TestKeyResolver()); - + var executableBuilder = resolver.GetExecutableBuilder(); - + executableBuilder .SetExecutable(action111, true) .SetExecutable(action2, true); - + var positionBuilder = resolver.GetPositionBuilder(); var costBuilder = resolver.GetCostBuilder(); // Action 2 will be very expensive, other actions default to a cost of 1 costBuilder.SetCost(action2, 100f); - + var conditionBuilder = resolver.GetConditionBuilder(); - + // Act var handle = resolver.StartResolve(new RunData { @@ -341,11 +342,11 @@ public void Resolve_ShouldIncludeCostHeuristics() Positions = new NativeArray(positionBuilder.Build(), Allocator.TempJob), Costs = new NativeArray(costBuilder.Build(), Allocator.TempJob), ConditionsMet = new NativeArray(conditionBuilder.Build(), Allocator.TempJob), - DistanceMultiplier = 1f + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); @@ -359,20 +360,20 @@ public void Resolve_ShouldIncludeCostHeuristics() public void Resolve_ShouldUseDistanceMultiplier(bool close) { var multiplier = close ? 1f : 0.2f; - + var rootConnection = new TestConnection("Root"); var shortConnection = new TestConnection("Short"); var longConnection = new TestConnection("Long"); - + var goal = new TestAction("goal") { - Conditions = new ICondition[] { rootConnection } + Conditions = new ICondition[] { rootConnection }, }; - + var rootAction = new TestAction("action") { Effects = new IEffect[] { rootConnection }, - Conditions = new ICondition[] { shortConnection, longConnection } + Conditions = new ICondition[] { shortConnection, longConnection }, }; var closeAction = new TestAction("closeAction") { @@ -382,34 +383,34 @@ public void Resolve_ShouldUseDistanceMultiplier(bool close) { Effects = new IEffect[] { longConnection }, }; - + var actions = new IAction[] { goal, rootAction, closeAction, farAction }; var resolver = new GraphResolver(actions, new TestKeyResolver()); - + // Far action: cost 1, distance 2 (10 * 0.2f) = 3 // Close action: cost 4, distance 1 (5 * 0.2f) = 4 var executableBuilder = resolver.GetExecutableBuilder(); - + executableBuilder .SetExecutable(closeAction, true) .SetExecutable(farAction, true); - + var positionBuilder = resolver.GetPositionBuilder(); positionBuilder .SetPosition(rootAction, new Vector3(0f, 0f, 0f)) .SetPosition(closeAction, new Vector3(5f, 0f, 0f)) .SetPosition(farAction, new Vector3(10f, 0f, 0f)); - + var costBuilder = resolver.GetCostBuilder(); costBuilder .SetCost(closeAction, 4f) .SetCost(farAction, 1f); - + var conditionBuilder = resolver.GetConditionBuilder(); - + // Act var handle = resolver.StartResolve(new RunData { @@ -418,39 +419,39 @@ public void Resolve_ShouldUseDistanceMultiplier(bool close) Positions = new NativeArray(positionBuilder.Build(), Allocator.TempJob), Costs = new NativeArray(costBuilder.Build(), Allocator.TempJob), ConditionsMet = new NativeArray(conditionBuilder.Build(), Allocator.TempJob), - DistanceMultiplier = multiplier + DistanceMultiplier = multiplier, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); // Assert result.Should().HaveCount(2); - + if (close) result.Should().Equal(closeAction, rootAction); else result.Should().Equal(farAction, rootAction); } - + [Test] public void Resolve_ShouldNotResolve_CompletedCondition() { var rootConnection = new TestConnection("Root"); var completedConnection = new TestConnection("Completed"); var incompleteConnection = new TestConnection("Incomplete"); - + var goal = new TestAction("goal") { - Conditions = new ICondition[] { rootConnection } + Conditions = new ICondition[] { rootConnection }, }; - + var rootAction = new TestAction("action") { Effects = new IEffect[] { rootConnection }, - Conditions = new ICondition[] { completedConnection, incompleteConnection } + Conditions = new ICondition[] { completedConnection, incompleteConnection }, }; var completedAction = new TestAction("completedAction") { @@ -460,21 +461,21 @@ public void Resolve_ShouldNotResolve_CompletedCondition() { Effects = new IEffect[] { incompleteConnection }, }; - + var actions = new IAction[] { goal, rootAction, completedAction, incompleteAction }; var resolver = new GraphResolver(actions, new TestKeyResolver()); - + var executableBuilder = resolver.GetExecutableBuilder(); executableBuilder .SetExecutable(completedAction, true) .SetExecutable(incompleteAction, true); - + var positionBuilder = resolver.GetPositionBuilder(); var costBuilder = resolver.GetCostBuilder(); var conditionBuilder = resolver.GetConditionBuilder(); conditionBuilder.SetConditionMet(completedConnection, true); - + // Act var handle = resolver.StartResolve(new RunData { @@ -483,11 +484,11 @@ public void Resolve_ShouldNotResolve_CompletedCondition() Positions = new NativeArray(positionBuilder.Build(), Allocator.TempJob), Costs = new NativeArray(costBuilder.Build(), Allocator.TempJob), ConditionsMet = new NativeArray(conditionBuilder.Build(), Allocator.TempJob), - DistanceMultiplier = 1f + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); @@ -495,48 +496,48 @@ public void Resolve_ShouldNotResolve_CompletedCondition() result.Should().HaveCount(2); result.Should().Equal(incompleteAction, rootAction); } - + [Test] public void Resolve_ShouldNotResolve_ActionWithFalseConditionWithoutConnections() { var rootConnection = new TestConnection("Root"); var availableConnection = new TestConnection("Available"); var unavailableConnection = new TestConnection("Unavailable"); - + var goal = new TestAction("goal") { - Conditions = new ICondition[] { rootConnection } + Conditions = new ICondition[] { rootConnection }, }; - + var expensiveAction = new TestAction("expensiveAction") { Effects = new IEffect[] { rootConnection }, }; - + var unavailableAction = new TestAction("subAction") { Effects = new IEffect[] { rootConnection }, - Conditions = new ICondition[] { unavailableConnection, availableConnection } + Conditions = new ICondition[] { unavailableConnection, availableConnection }, }; - + var shouldNotResolveAction = new TestAction("shouldNotResolveAction") { Effects = new IEffect[] { availableConnection }, }; - + var actions = new IAction[] { goal, expensiveAction, unavailableAction, shouldNotResolveAction }; var resolver = new GraphResolver(actions, new TestKeyResolver()); - + var executableBuilder = resolver.GetExecutableBuilder(); executableBuilder .SetExecutable(expensiveAction, true) .SetExecutable(unavailableAction, false) .SetExecutable(shouldNotResolveAction, true); - + var positionBuilder = resolver.GetPositionBuilder(); var costBuilder = resolver.GetCostBuilder(); costBuilder.SetCost(expensiveAction, 100f); - + var conditionBuilder = resolver.GetConditionBuilder(); // Act @@ -547,11 +548,11 @@ public void Resolve_ShouldNotResolve_ActionWithFalseConditionWithoutConnections( Positions = new NativeArray(positionBuilder.Build(), Allocator.TempJob), Costs = new NativeArray(costBuilder.Build(), Allocator.TempJob), ConditionsMet = new NativeArray(conditionBuilder.Build(), Allocator.TempJob), - DistanceMultiplier = 1f + DistanceMultiplier = 1f, }); var result = handle.Complete(); - + // Cleanup resolver.Dispose(); @@ -560,4 +561,4 @@ public void Resolve_ShouldNotResolve_ActionWithFalseConditionWithoutConnections( result.Should().Equal(expensiveAction); } } -} \ No newline at end of file +} diff --git a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs index 0434ba1f..ea5561ae 100644 --- a/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs +++ b/Package/Tests/CrashKonijn.Goap.Tests/UnitTests/SensorRunnerTests.cs @@ -1,5 +1,4 @@ using CrashKonijn.Goap.Classes; -using CrashKonijn.Goap.Classes.References; using CrashKonijn.Goap.Classes.Runners; using CrashKonijn.Goap.Configs; using CrashKonijn.Goap.Interfaces; @@ -7,6 +6,7 @@ using NSubstitute; using NSubstitute.ReturnsExtensions; using NUnit.Framework; +using Unity.Collections; using UnityEngine.TestTools; namespace CrashKonijn.Goap.UnitTests @@ -20,22 +20,23 @@ public void Setup() // This is not the case, so we ignore the message // This can trigger in any test, even the ones that don't use the Job system LogAssert.ignoreFailingMessages = true; + NativeLeakDetection.Mode = NativeLeakDetectionMode.Disabled; } - + // Global [Test] public void SenseGlobal_WithPositiveWorldSense_IsPresentInStates() { // Arrange var key = new WorldKey("test"); - + var sensor = Substitute.For(); sensor.Sense().Returns((SenseValue) 1); sensor.Key.Returns(key); - + var worldSensors = new IWorldSensor[] { sensor }; var targetSensors = new ITargetSensor[] { }; - + var runner = new SensorRunner(worldSensors, targetSensors); // Act @@ -45,20 +46,20 @@ public void SenseGlobal_WithPositiveWorldSense_IsPresentInStates() data.States.Should().ContainKey(key); data.States[key].Should().Be(1); } - + [Test] public void SenseGlobal_WithNegativeWorldSense_IsPresentInStates() { // Arrange var key = new WorldKey("test"); - + var sensor = Substitute.For(); sensor.Sense().Returns((SenseValue) 0); sensor.Key.Returns(key); - + var worldSensors = new IWorldSensor[] { sensor }; var targetSensors = new ITargetSensor[] { }; - + var runner = new SensorRunner(worldSensors, targetSensors); // Act @@ -68,21 +69,21 @@ public void SenseGlobal_WithNegativeWorldSense_IsPresentInStates() data.States.Should().ContainKey(key); data.States[key].Should().Be(0); } - + [Test] public void SenseGlobal_WithPositiveTargetSense_IsPresentInTargets() { // Arrange var target = Substitute.For(); var key = new TargetKey("test"); - + var sensor = Substitute.For(); sensor.Sense().Returns(target); sensor.Key.Returns(key); - - var worldSensors = new IWorldSensor[] { }; + + var worldSensors = new IWorldSensor[] { }; var targetSensors = new ITargetSensor[] { sensor }; - + var runner = new SensorRunner(worldSensors, targetSensors); // Act @@ -92,21 +93,21 @@ public void SenseGlobal_WithPositiveTargetSense_IsPresentInTargets() data.Targets.Should().ContainKey(key); data.Targets.Should().ContainValue(target); } - + [Test] public void SenseGlobal_WithNegativeTargetSense_IsPresentInTargets() { // Arrange var target = Substitute.For(); var key = new TargetKey("test"); - + var sensor = Substitute.For(); sensor.Sense().ReturnsNull(); sensor.Key.Returns(key); - - var worldSensors = new IWorldSensor[] { }; + + var worldSensors = new IWorldSensor[] { }; var targetSensors = new ITargetSensor[] { sensor }; - + var runner = new SensorRunner(worldSensors, targetSensors); // Act @@ -116,23 +117,23 @@ public void SenseGlobal_WithNegativeTargetSense_IsPresentInTargets() data.Targets.Should().ContainKey(key); data.Targets.Should().NotContainValue(target); } - + // Local [Test] public void SenseLocal_WithPositiveWorldSense_IsPresentInStates() { // Arrange var key = new WorldKey("test"); - + var sensor = Substitute.For(); sensor.Sense(Arg.Any(), Arg.Any()).Returns((SenseValue) 1); sensor.Key.Returns(key); - + var worldSensors = new IWorldSensor[] { sensor }; var targetSensors = new ITargetSensor[] { }; - + var runner = new SensorRunner(worldSensors, targetSensors); - + var agent = Substitute.For(); agent.WorldData.Returns(new LocalWorldData()); @@ -143,20 +144,20 @@ public void SenseLocal_WithPositiveWorldSense_IsPresentInStates() data.States.Should().ContainKey(key); data.States[key].Should().Be(1); } - + [Test] public void SenseLocal_WithNegativeWorldSense_IsNotPresentInStates() { // Arrange var key = new WorldKey("test"); - + var sensor = Substitute.For(); sensor.Sense(Arg.Any(), Arg.Any()).Returns((SenseValue) 0); sensor.Key.Returns(key); - + var worldSensors = new IWorldSensor[] { sensor }; var targetSensors = new ITargetSensor[] { }; - + var runner = new SensorRunner(worldSensors, targetSensors); var agent = Substitute.For(); @@ -169,26 +170,26 @@ public void SenseLocal_WithNegativeWorldSense_IsNotPresentInStates() data.States.Should().ContainKey(key); data.States[key].Should().Be(0); } - + [Test] public void SenseLocal_WithPositiveTargetSense_IsPresentInTargets() { // Arrange var target = Substitute.For(); var key = new TargetKey("test"); - + var sensor = Substitute.For(); sensor.Sense(Arg.Any(), Arg.Any()).Returns(target); sensor.Key.Returns(key); - - var worldSensors = new IWorldSensor[] { }; + + var worldSensors = new IWorldSensor[] { }; var targetSensors = new ITargetSensor[] { sensor }; - + var runner = new SensorRunner(worldSensors, targetSensors); var agent = Substitute.For(); agent.WorldData.Returns(new LocalWorldData()); - + // Act var data = runner.SenseLocal(new GlobalWorldData(), agent); @@ -196,26 +197,26 @@ public void SenseLocal_WithPositiveTargetSense_IsPresentInTargets() data.Targets.Should().ContainKey(key); data.Targets.Should().ContainValue(target); } - + [Test] public void SenseLocal_WithNegativeTargetSense_IsPresentInTargets() { // Arrange var target = Substitute.For(); var key = new TargetKey("test"); - + var sensor = Substitute.For(); sensor.Sense(Arg.Any(), Arg.Any()).ReturnsNull(); sensor.Key.Returns(key); - - var worldSensors = new IWorldSensor[] { }; + + var worldSensors = new IWorldSensor[] { }; var targetSensors = new ITargetSensor[] { sensor }; - + var runner = new SensorRunner(worldSensors, targetSensors); var agent = Substitute.For(); agent.WorldData.Returns(new LocalWorldData()); - + // Act var data = runner.SenseLocal(new GlobalWorldData(), agent); @@ -223,21 +224,21 @@ public void SenseLocal_WithNegativeTargetSense_IsPresentInTargets() data.Targets.Should().ContainKey(key); data.Targets.Should().NotContainValue(target); } - + [Test] public void SenseLocal_ContainsGlobalTarget() { // Arrange var target = Substitute.For(); var key = new TargetKey("test"); - + var sensor = Substitute.For(); sensor.Sense().Returns(target); sensor.Key.Returns(key); - - var worldSensors = new IWorldSensor[] { }; + + var worldSensors = new IWorldSensor[] { }; var targetSensors = new ITargetSensor[] { sensor }; - + var runner = new SensorRunner(worldSensors, targetSensors); var agent = Substitute.For(); @@ -245,7 +246,7 @@ public void SenseLocal_ContainsGlobalTarget() var globalWorldData = new GlobalWorldData(); globalWorldData.Targets.Add(key, target); - + // Act var data = runner.SenseLocal(globalWorldData, agent); @@ -253,25 +254,25 @@ public void SenseLocal_ContainsGlobalTarget() data.Targets.Should().ContainKey(key); data.Targets.Should().ContainValue(target); } - + [Test] public void SenseLocal_ContainsGlobalState() { // Arrange var key = new WorldKey("test"); - + var sensor = Substitute.For(); sensor.Sense(Arg.Any(), Arg.Any()).Returns((SenseValue) 0); sensor.Key.Returns(key); - + var worldSensors = new IWorldSensor[] { }; var targetSensors = new ITargetSensor[] { }; - + var runner = new SensorRunner(worldSensors, targetSensors); var agent = Substitute.For(); agent.WorldData.Returns(new LocalWorldData()); - + var globalWorldData = new GlobalWorldData(); globalWorldData.States.Add(key, 1); @@ -283,4 +284,4 @@ public void SenseLocal_ContainsGlobalState() data.States[key].Should().Be(1); } } -} \ No newline at end of file +}