Add a test that puts all components on an entity and checks for no exceptions (#1815)
* Add test that puts all components on an entity and checks for no exceptions Also fix all the exceptions that happened because of this * Add comments to the test * Fix nullable errors * Fix more nullable errors * More nullable error fixes * Unignore basic actor component * Fix more nullable errors * NULLABLE ERROR * Add string interpolation * Merge if checks * Remove redundant pragma warning disable 649 * Address reviews * Remove null wrappers around TryGetComponent * Merge conflict fixes * APC battery component error fix * Fix power test * Fix atmos mapgrid usages
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Robust.Server.Interfaces.Maps;
|
||||
@@ -11,6 +14,7 @@ using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Logger = Robust.Shared.Log.Logger;
|
||||
|
||||
namespace Content.IntegrationTests.Tests
|
||||
{
|
||||
@@ -30,7 +34,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var pauseMan = server.ResolveDependency<IPauseManager>();
|
||||
var prototypes = new List<EntityPrototype>();
|
||||
IMapGrid grid = default;
|
||||
IEntity testEntity = null;
|
||||
IEntity testEntity;
|
||||
|
||||
//Build up test environment
|
||||
server.Post(() =>
|
||||
@@ -59,7 +63,7 @@ namespace Content.IntegrationTests.Tests
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.LogS(LogLevel.Debug, "EntityTest", "Testing: " + prototype.ID);
|
||||
Logger.LogS(LogLevel.Debug, "EntityTest", $"Testing: {prototype.ID}");
|
||||
testEntity = entityMan.SpawnEntity(prototype.ID, testLocation);
|
||||
server.RunTicks(2);
|
||||
Assert.That(testEntity.Initialized);
|
||||
@@ -69,8 +73,8 @@ namespace Content.IntegrationTests.Tests
|
||||
//Fail any exceptions thrown on spawn
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogS(LogLevel.Error, "EntityTest", "Entity '" + prototype.ID + "' threw: " + e.Message);
|
||||
//Assert.Fail();
|
||||
Logger.LogS(LogLevel.Error, "EntityTest", $"Entity '{prototype.ID}' threw: {e.Message}");
|
||||
Assert.Fail();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -101,5 +105,125 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
await client.WaitIdleAsync();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task AllComponentsOneEntityDeleteTest()
|
||||
{
|
||||
var skipComponents = new[]
|
||||
{
|
||||
"DebugExceptionOnAdd", // Debug components that explicitly throw exceptions
|
||||
"DebugExceptionExposeData",
|
||||
"DebugExceptionInitialize",
|
||||
"DebugExceptionStartup",
|
||||
"Map", // We aren't testing a map entity in this test
|
||||
"MapGrid"
|
||||
};
|
||||
|
||||
var testEntity = @"
|
||||
- type: entity
|
||||
id: AllComponentsOneEntityDeleteTestEntity";
|
||||
|
||||
var server = StartServerDummyTicker();
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapLoader = server.ResolveDependency<IMapLoader>();
|
||||
var pauseManager = server.ResolveDependency<IPauseManager>();
|
||||
var componentFactory = server.ResolveDependency<IComponentFactory>();
|
||||
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
|
||||
|
||||
IMapGrid grid = default;
|
||||
|
||||
server.Post(() =>
|
||||
{
|
||||
// Load test entity
|
||||
using var reader = new StringReader(testEntity);
|
||||
prototypeManager.LoadFromStream(reader);
|
||||
|
||||
// Load test map
|
||||
var mapId = mapManager.CreateMap();
|
||||
pauseManager.AddUninitializedMap(mapId);
|
||||
grid = mapLoader.LoadBlueprint(mapId, "Maps/stationstation.yml");
|
||||
pauseManager.DoMapInitialize(mapId);
|
||||
});
|
||||
|
||||
var distinctComponents = new List<(List<Type> components, List<Type> references)>
|
||||
{
|
||||
(new List<Type>(), new List<Type>())
|
||||
};
|
||||
|
||||
// Split components into groups, ensuring that their references don't conflict
|
||||
foreach (var type in componentFactory.AllRegisteredTypes)
|
||||
{
|
||||
var registration = componentFactory.GetRegistration(type);
|
||||
|
||||
for (var i = 0; i < distinctComponents.Count; i++)
|
||||
{
|
||||
var distinct = distinctComponents[i];
|
||||
|
||||
if (distinct.references.Intersect(registration.References).Any())
|
||||
{
|
||||
// Ensure the next list if this one has conflicting references
|
||||
if (i + 1 >= distinctComponents.Count)
|
||||
{
|
||||
distinctComponents.Add((new List<Type>(), new List<Type>()));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the component and its references if no conflicting references were found
|
||||
distinct.components.Add(type);
|
||||
distinct.references.AddRange(registration.References);
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
Assert.That(distinctComponents, Is.Not.Empty);
|
||||
|
||||
server.Assert(() =>
|
||||
{
|
||||
Assert.DoesNotThrow(() =>
|
||||
{
|
||||
foreach (var distinct in distinctComponents)
|
||||
{
|
||||
var testLocation = new GridCoordinates(new Vector2(0, 0), grid);
|
||||
var entity = entityManager.SpawnEntity("AllComponentsOneEntityDeleteTestEntity", testLocation);
|
||||
|
||||
Assert.That(entity.Initialized);
|
||||
|
||||
foreach (var type in distinct.components)
|
||||
{
|
||||
var component = (Component) componentFactory.GetComponent(type);
|
||||
|
||||
// If the entity already has this component, if it was ensured or added by another
|
||||
if (entity.HasComponent(component.GetType()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this component is ignored
|
||||
if (skipComponents.Contains(component.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
component.Owner = entity;
|
||||
|
||||
Logger.LogS(LogLevel.Debug, "EntityTest", $"Adding component: {component.Name}");
|
||||
|
||||
entityManager.ComponentManager.AddComponent(entity, component);
|
||||
}
|
||||
|
||||
server.RunTicks(48); // Run one full second on the server
|
||||
|
||||
entityManager.DeleteEntity(entity.Uid);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user