using System; using System.Collections.Generic; using System.Linq; using Moq; using NUnit.Framework; using Robust.Server.Configuration; using Robust.Shared.Configuration; using Robust.Shared.ContentPack; using Robust.Shared.Exceptions; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Network; using Robust.Shared.Profiling; using Robust.Shared.Reflection; using Robust.Shared.Replays; using Robust.Shared.Timing; namespace Robust.UnitTesting.Shared.GameObjects { [TestFixture] [TestOf(typeof(EntitySystemManager))] internal sealed class EntitySystemManagerOrderTest { private sealed class Counter { public int X; } [Reflect(false)] private abstract class TestSystemBase : IEntitySystem { public Counter? Counter; public int LastUpdate; public virtual IEnumerable UpdatesAfter => Enumerable.Empty(); public virtual IEnumerable UpdatesBefore => Enumerable.Empty(); public bool UpdatesOutsidePrediction => true; public void Initialize() { } public void Shutdown() { } public void Update(float frameTime) { LastUpdate = Counter!.X++; } public void FrameUpdate(float frameTime) { } } // Expected update order is is A -> D -> C -> B [Reflect(false)] private sealed class TestSystemA : TestSystemBase { } [Reflect(false)] private sealed class TestSystemB : TestSystemBase { public override IEnumerable UpdatesAfter => new[] {typeof(TestSystemA)}; } [Reflect(false)] private sealed class TestSystemC : TestSystemBase { public override IEnumerable UpdatesBefore => new[] {typeof(TestSystemB)}; } [Reflect(false)] private sealed class TestSystemD : TestSystemBase { public override IEnumerable UpdatesAfter => new[] {typeof(TestSystemA)}; public override IEnumerable UpdatesBefore => new[] {typeof(TestSystemC)}; } [Test] public void Test() { var deps = new DependencyCollection(); deps.Register(); deps.Register(); deps.Register(); deps.RegisterInstance(new Mock().Object); deps.Register(); deps.Register(); deps.Register(); deps.Register(); deps.Register(); deps.RegisterInstance(new Mock().Object); deps.Register(); deps.RegisterInstance(new Mock().Object); // WHEN WILL THE SUFFERING END deps.RegisterInstance(new Mock().Object); var reflectionMock = new Mock(); reflectionMock.Setup(p => p.GetAllChildren(false)) .Returns(new[] { typeof(TestSystemA), typeof(TestSystemB), typeof(TestSystemC), typeof(TestSystemD), }); deps.RegisterInstance(reflectionMock.Object); deps.BuildGraph(); IoCManager.InitThread(deps, true); var systems = deps.Resolve(); systems.Initialize(); var counter = new Counter(); systems.GetEntitySystem().Counter = counter; systems.GetEntitySystem().Counter = counter; systems.GetEntitySystem().Counter = counter; systems.GetEntitySystem().Counter = counter; systems.TickUpdate(1, noPredictions: false); Assert.That(counter.X, Is.EqualTo(4)); Assert.That(systems.GetEntitySystem().LastUpdate, Is.EqualTo(0)); Assert.That(systems.GetEntitySystem().LastUpdate, Is.EqualTo(3)); Assert.That(systems.GetEntitySystem().LastUpdate, Is.EqualTo(2)); Assert.That(systems.GetEntitySystem().LastUpdate, Is.EqualTo(1)); } [TearDown] public void TearDown() { IoCManager.Clear(); } } }