Add role prototype validation tests (#32801)
* Add role prototype validation test * Rejig GetPrototypesWithComponent * More tests n stuff
This commit is contained in:
@@ -107,13 +107,41 @@ public sealed partial class TestPair
|
||||
/// <summary>
|
||||
/// Retrieve all entity prototypes that have some component.
|
||||
/// </summary>
|
||||
public List<EntityPrototype> GetPrototypesWithComponent<T>(
|
||||
public List<(EntityPrototype, T)> GetPrototypesWithComponent<T>(
|
||||
HashSet<string>? ignored = null,
|
||||
bool ignoreAbstract = true,
|
||||
bool ignoreTestPrototypes = true)
|
||||
where T : IComponent
|
||||
{
|
||||
var id = Server.ResolveDependency<IComponentFactory>().GetComponentName(typeof(T));
|
||||
var list = new List<(EntityPrototype, T)>();
|
||||
foreach (var proto in Server.ProtoMan.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (ignored != null && ignored.Contains(proto.ID))
|
||||
continue;
|
||||
|
||||
if (ignoreAbstract && proto.Abstract)
|
||||
continue;
|
||||
|
||||
if (ignoreTestPrototypes && IsTestPrototype(proto))
|
||||
continue;
|
||||
|
||||
if (proto.Components.TryGetComponent(id, out var cmp))
|
||||
list.Add((proto, (T)cmp));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve all entity prototypes that have some component.
|
||||
/// </summary>
|
||||
public List<EntityPrototype> GetPrototypesWithComponent(Type type,
|
||||
HashSet<string>? ignored = null,
|
||||
bool ignoreAbstract = true,
|
||||
bool ignoreTestPrototypes = true)
|
||||
{
|
||||
var id = Server.ResolveDependency<IComponentFactory>().GetComponentName(type);
|
||||
var list = new List<EntityPrototype>();
|
||||
foreach (var proto in Server.ProtoMan.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
@@ -127,7 +155,7 @@ public sealed partial class TestPair
|
||||
continue;
|
||||
|
||||
if (proto.Components.ContainsKey(id))
|
||||
list.Add(proto);
|
||||
list.Add((proto));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
95
Content.IntegrationTests/Tests/Minds/RoleTests.cs
Normal file
95
Content.IntegrationTests/Tests/Minds/RoleTests.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Roles;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Reflection;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Minds;
|
||||
|
||||
[TestFixture]
|
||||
public sealed class RoleTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Check that any prototype with a <see cref="MindRoleComponent"/> is properly configured
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task ValidateRolePrototypes()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
|
||||
var jobComp = pair.Server.ResolveDependency<IComponentFactory>().GetComponentName(typeof(JobRoleComponent));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
foreach (var (proto, comp) in pair.GetPrototypesWithComponent<MindRoleComponent>())
|
||||
{
|
||||
Assert.That(comp.AntagPrototype == null || comp.JobPrototype == null, $"Role {proto.ID} has both a job and antag prototype.");
|
||||
Assert.That(!comp.ExclusiveAntag || comp.Antag, $"Role {proto.ID} is marked as an exclusive antag, despite not being an antag.");
|
||||
Assert.That(comp.Antag || comp.AntagPrototype == null, $"Role {proto.ID} has an antag prototype, despite not being an antag.");
|
||||
|
||||
if (comp.JobPrototype != null)
|
||||
Assert.That(proto.Components.ContainsKey(jobComp), $"Role {proto.ID} is a job, despite not having a job prototype.");
|
||||
|
||||
// It is possible that this is meant to be supported? Though I would assume that it would be for
|
||||
// admin / prototype uploads, and that pre-defined roles should still check this.
|
||||
Assert.That(!comp.Antag || comp.AntagPrototype != null , $"Role {proto.ID} is an antag, despite not having a antag prototype.");
|
||||
}
|
||||
});
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that any prototype with a <see cref="JobRoleComponent"/> also has a properly configured
|
||||
/// <see cref="MindRoleComponent"/>
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task ValidateJobPrototypes()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
|
||||
var mindCompId = pair.Server.ResolveDependency<IComponentFactory>().GetComponentName(typeof(MindRoleComponent));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
foreach (var (proto, comp) in pair.GetPrototypesWithComponent<JobRoleComponent>())
|
||||
{
|
||||
if (proto.Components.TryGetComponent(mindCompId, out var mindComp))
|
||||
Assert.That(((MindRoleComponent)mindComp).JobPrototype, Is.Not.Null);
|
||||
}
|
||||
});
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that any prototype with a component that inherits from <see cref="BaseMindRoleComponent"/> also has a
|
||||
/// <see cref="MindRoleComponent"/>
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task ValidateRolesHaveMindRoleComp()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
|
||||
var refMan = pair.Server.ResolveDependency<IReflectionManager>();
|
||||
var mindCompId = pair.Server.ResolveDependency<IComponentFactory>().GetComponentName(typeof(MindRoleComponent));
|
||||
|
||||
var compTypes = refMan.GetAllChildren(typeof(BaseMindRoleComponent))
|
||||
.Append(typeof(RoleBriefingComponent))
|
||||
.Where(x => !x.IsAbstract);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
foreach (var comp in compTypes)
|
||||
{
|
||||
foreach (var proto in pair.GetPrototypesWithComponent(comp))
|
||||
{
|
||||
Assert.That(proto.Components.ContainsKey(mindCompId), $"Role {proto.ID} does not have a {nameof(MindRoleComponent)} despite having a {comp.Name}");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public sealed class PrototypeSaveTest
|
||||
|
||||
await pair.Client.WaitPost(() =>
|
||||
{
|
||||
foreach (var proto in pair.GetPrototypesWithComponent<ItemComponent>(Ignored))
|
||||
foreach (var (proto, _) in pair.GetPrototypesWithComponent<ItemComponent>(Ignored))
|
||||
{
|
||||
var dummy = pair.Client.EntMan.Spawn(proto.ID);
|
||||
pair.Client.EntMan.RunMapInit(dummy, pair.Client.MetaData(dummy));
|
||||
|
||||
@@ -94,14 +94,13 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
await Assert.MultipleAsync(async () =>
|
||||
{
|
||||
foreach (var proto in pair.GetPrototypesWithComponent<StorageFillComponent>())
|
||||
foreach (var (proto, fill) in pair.GetPrototypesWithComponent<StorageFillComponent>())
|
||||
{
|
||||
if (proto.HasComponent<EntityStorageComponent>(compFact))
|
||||
continue;
|
||||
|
||||
StorageComponent? storage = null;
|
||||
ItemComponent? item = null;
|
||||
StorageFillComponent fill = default!;
|
||||
var size = 0;
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -112,7 +111,6 @@ namespace Content.IntegrationTests.Tests
|
||||
}
|
||||
|
||||
proto.TryGetComponent("Item", out item);
|
||||
fill = (StorageFillComponent) proto.Components[id].Component;
|
||||
size = GetFillSize(fill, false, protoMan, itemSys);
|
||||
});
|
||||
|
||||
@@ -179,7 +177,7 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
var itemSys = entMan.System<SharedItemSystem>();
|
||||
|
||||
foreach (var proto in pair.GetPrototypesWithComponent<StorageFillComponent>())
|
||||
foreach (var (proto, fill) in pair.GetPrototypesWithComponent<StorageFillComponent>())
|
||||
{
|
||||
if (proto.HasComponent<StorageComponent>(compFact))
|
||||
continue;
|
||||
@@ -192,7 +190,6 @@ namespace Content.IntegrationTests.Tests
|
||||
if (entStorage == null)
|
||||
return;
|
||||
|
||||
var fill = (StorageFillComponent) proto.Components[id].Component;
|
||||
var size = GetFillSize(fill, true, protoMan, itemSys);
|
||||
Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity),
|
||||
$"{proto.ID} storage fill is too large.");
|
||||
|
||||
Reference in New Issue
Block a user