using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using NUnit.Framework; using Robust.Server.Containers; using Robust.Server.GameObjects; using Robust.Server.Physics; using Robust.Shared.Configuration; using Robust.Shared.Containers; using Robust.Shared.ContentPack; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Dynamics; using Robust.Shared.Prototypes; using Robust.Shared.Reflection; using Robust.Shared.Utility; namespace Robust.UnitTesting { public enum UnitTestProject : byte { Server, Client } [Parallelizable] public abstract partial class RobustUnitTest { public virtual UnitTestProject Project => UnitTestProject.Server; [OneTimeSetUp] public void BaseSetup() { // Clear state across tests. IoCManager.InitThread(); IoCManager.Clear(); RegisterIoC(); var assemblies = new List(4); switch (Project) { case UnitTestProject.Client: assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Robust.Client")); break; case UnitTestProject.Server: assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Robust.Server")); break; default: throw new NotSupportedException($"Unknown testing project: {Project}"); } assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Robust.Shared")); assemblies.Add(Assembly.GetExecutingAssembly()); var configurationManager = IoCManager.Resolve(); configurationManager.Initialize(Project == UnitTestProject.Server); foreach (var assembly in assemblies) { configurationManager.LoadCVarsFromAssembly(assembly); } var contentAssemblies = GetContentAssemblies(); foreach (var assembly in contentAssemblies) { configurationManager.LoadCVarsFromAssembly(assembly); } configurationManager.LoadCVarsFromAssembly(typeof(RobustUnitTest).Assembly); var systems = IoCManager.Resolve(); // Required systems systems.LoadExtraSystemType(); systems.LoadExtraSystemType(); systems.LoadExtraSystemType(); systems.LoadExtraSystemType(); var entMan = IoCManager.Resolve(); var mapMan = IoCManager.Resolve(); // Required components for the engine to work var compFactory = IoCManager.Resolve(); if (!compFactory.AllRegisteredTypes.Contains(typeof(MetaDataComponent))) { compFactory.RegisterClass(); } if (!compFactory.AllRegisteredTypes.Contains(typeof(EntityLookupComponent))) { compFactory.RegisterClass(); } if (!compFactory.AllRegisteredTypes.Contains(typeof(SharedPhysicsMapComponent))) { compFactory.RegisterClass(); } if (!compFactory.AllRegisteredTypes.Contains(typeof(BroadphaseComponent))) { compFactory.RegisterClass(); } if (!compFactory.AllRegisteredTypes.Contains(typeof(FixturesComponent))) { compFactory.RegisterClass(); } if (!compFactory.AllRegisteredTypes.Contains(typeof(EntityLookupComponent))) { compFactory.RegisterClass(); } // So by default EntityManager does its own EntitySystemManager initialize during Startup. // We want to bypass this and load our own systems hence we will manually initialize it here. entMan.Initialize(); // RobustUnitTest is complete hot garbage. // This makes EventTables ignore *all* the screwed up component abuse it causes. entMan.EventBus.OnlyCallOnRobustUnitTestISwearToGodPleaseSomebodyKillThisNightmare(); mapMan.Initialize(); systems.Initialize(); IoCManager.Resolve().LoadAssemblies(assemblies); var modLoader = IoCManager.Resolve(); modLoader.Assemblies = contentAssemblies; modLoader.TryLoadModulesFrom(ResourcePath.Root, ""); entMan.Startup(); mapMan.Startup(); } [OneTimeTearDown] public void BaseTearDown() { IoCManager.Clear(); } /// /// Called after all IoC registration has been done, but before the graph has been built. /// This allows one to add new IoC types or overwrite existing ones if needed. /// protected virtual void OverrideIoC() { } protected virtual Assembly[] GetContentAssemblies() { return Array.Empty(); } } }