using NUnit.Framework; using BaseGames.AI; namespace BaseGames.Tests.EditMode.AI { public class BrainBuilderTests { static AiGraph BuildSample() { var b = new BrainBuilder(); b.Entry("Patrol"); b.Global().To("Dead").OnEvent(AiSignal.Died); b.State("Patrol") .To("Chase").When(c => c.Sensor.SeesPlayer(), "SeesPlayer"); b.State("Chase") .To("Patrol").When(c => c.Sensor.LostFor(2f), "LostFor(2s)"); b.State("Dead"); return b.Build(); } [Test] public void Build_SetsEntryState() { Assert.AreEqual("Patrol", BuildSample().EntryState); } [Test] public void Build_RegistersAllStates() { var g = BuildSample(); CollectionAssert.AreEquivalent( new[] { "Patrol", "Chase", "Dead" }, System.Linq.Enumerable.ToList(g.StateNames)); } [Test] public void Build_UsesExplicitConditionLabel() { var g = BuildSample(); var t = g.GetState("Patrol").Transitions[0]; Assert.AreEqual("SeesPlayer", t.Label); } [Test] public void Build_UnlabeledCondition_FallsBackToCond() { var b = new BrainBuilder(); b.Entry("A"); b.State("A").To("B").When(c => true); b.State("B"); var g = b.Build(); Assert.AreEqual("cond", g.GetState("A").Transitions[0].Label); } [Test] public void Build_GlobalTransitionsAreSeparate() { var g = BuildSample(); Assert.AreEqual(1, g.GlobalTransitions.Count); Assert.AreEqual("Dead", g.GlobalTransitions[0].Target); Assert.AreEqual(AiSignal.Died, g.GlobalTransitions[0].Event); } [Test] public void Build_UnknownTransitionTarget_Throws() { var b = new BrainBuilder(); b.Entry("A"); b.State("A").To("Nonexistent").When(c => true); Assert.Throws(() => b.Build()); } [Test] public void RequireState_Throws_WhenStateNotDeclared() { var b = new BrainBuilder(); var ex = Assert.Throws(() => b.RequireState("Ghost")); StringAssert.Contains("Ghost", ex.Message); } [Test] public void RequireState_Passes_WhenStateDeclared() { var b = new BrainBuilder(); b.State("Real"); Assert.DoesNotThrow(() => b.RequireState("Real")); } } }