Add a test to check that lathe recipes are possible (#33868)
* Add a test to check that all lathes accept the materials for all their recipesy * Add check for storage limit * Track total recipe material volume * Check dynamic and emag recipes too * Move AllLatheRecipesValidTest from ResearchTest to LatheTest * Extremely minor modernization
This commit is contained in:
132
Content.IntegrationTests/Tests/Lathe/LatheTest.cs
Normal file
132
Content.IntegrationTests/Tests/Lathe/LatheTest.cs
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Shared.Lathe;
|
||||||
|
using Content.Shared.Materials;
|
||||||
|
using Content.Shared.Prototypes;
|
||||||
|
using Content.Shared.Research.Prototypes;
|
||||||
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.IntegrationTests.Tests.Lathe;
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public sealed class LatheTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public async Task TestLatheRecipeIngredientsFitLathe()
|
||||||
|
{
|
||||||
|
await using var pair = await PoolManager.GetServerClient();
|
||||||
|
var server = pair.Server;
|
||||||
|
|
||||||
|
var mapData = await pair.CreateTestMap();
|
||||||
|
|
||||||
|
var entMan = server.EntMan;
|
||||||
|
var protoMan = server.ProtoMan;
|
||||||
|
var compFactory = server.ResolveDependency<IComponentFactory>();
|
||||||
|
var materialStorageSystem = server.System<SharedMaterialStorageSystem>();
|
||||||
|
var whitelistSystem = server.System<EntityWhitelistSystem>();
|
||||||
|
|
||||||
|
await server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
// Find all the lathes
|
||||||
|
var latheProtos = protoMan.EnumeratePrototypes<EntityPrototype>()
|
||||||
|
.Where(p => !p.Abstract)
|
||||||
|
.Where(p => !pair.IsTestPrototype(p))
|
||||||
|
.Where(p => p.HasComponent<LatheComponent>());
|
||||||
|
|
||||||
|
// Find every EntityPrototype that can be inserted into a MaterialStorage
|
||||||
|
var materialEntityProtos = protoMan.EnumeratePrototypes<EntityPrototype>()
|
||||||
|
.Where(p => !p.Abstract)
|
||||||
|
.Where(p => !pair.IsTestPrototype(p))
|
||||||
|
.Where(p => p.HasComponent<PhysicalCompositionComponent>());
|
||||||
|
|
||||||
|
// Spawn all of the above material EntityPrototypes - we need actual entities to do whitelist checks
|
||||||
|
var materialEntities = new List<EntityUid>(materialEntityProtos.Count());
|
||||||
|
foreach (var materialEntityProto in materialEntityProtos)
|
||||||
|
{
|
||||||
|
materialEntities.Add(entMan.SpawnEntity(materialEntityProto.ID, mapData.GridCoords));
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
// Check each lathe individually
|
||||||
|
foreach (var latheProto in latheProtos)
|
||||||
|
{
|
||||||
|
if (!latheProto.TryGetComponent<LatheComponent>(out var latheComp, compFactory))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!latheProto.TryGetComponent<MaterialStorageComponent>(out var storageComp, compFactory))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Test which material-containing entities are accepted by this lathe
|
||||||
|
var acceptedMaterials = new HashSet<ProtoId<MaterialPrototype>>();
|
||||||
|
foreach (var materialEntity in materialEntities)
|
||||||
|
{
|
||||||
|
Assert.That(entMan.TryGetComponent<PhysicalCompositionComponent>(materialEntity, out var compositionComponent));
|
||||||
|
if (whitelistSystem.IsWhitelistFail(storageComp.Whitelist, materialEntity))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Mark the lathe as accepting each material in the entity
|
||||||
|
foreach (var (material, _) in compositionComponent.MaterialComposition)
|
||||||
|
{
|
||||||
|
acceptedMaterials.Add(material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect all the recipes assigned to this lathe
|
||||||
|
var recipes = new List<ProtoId<LatheRecipePrototype>>();
|
||||||
|
recipes.AddRange(latheComp.StaticRecipes);
|
||||||
|
recipes.AddRange(latheComp.DynamicRecipes);
|
||||||
|
if (latheProto.TryGetComponent<EmagLatheRecipesComponent>(out var emagRecipesComp, compFactory))
|
||||||
|
{
|
||||||
|
recipes.AddRange(emagRecipesComp.EmagStaticRecipes);
|
||||||
|
recipes.AddRange(emagRecipesComp.EmagDynamicRecipes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check each recipe assigned to this lathe
|
||||||
|
foreach (var recipeId in recipes)
|
||||||
|
{
|
||||||
|
Assert.That(protoMan.TryIndex(recipeId, out var recipeProto));
|
||||||
|
|
||||||
|
// Track the total material volume of the recipe
|
||||||
|
var totalQuantity = 0;
|
||||||
|
// Check each material called for by the recipe
|
||||||
|
foreach (var (materialId, quantity) in recipeProto.Materials)
|
||||||
|
{
|
||||||
|
Assert.That(protoMan.TryIndex(materialId, out var materialProto));
|
||||||
|
// Make sure the material is accepted by the lathe
|
||||||
|
Assert.That(acceptedMaterials, Does.Contain(materialId), $"Lathe {latheProto.ID} has recipe {recipeId} but does not accept any materials containing {materialId}");
|
||||||
|
totalQuantity += quantity;
|
||||||
|
}
|
||||||
|
// Make sure the recipe doesn't call for more material than the lathe can hold
|
||||||
|
if (storageComp.StorageLimit != null)
|
||||||
|
Assert.That(totalQuantity, Is.LessThanOrEqualTo(storageComp.StorageLimit), $"Lathe {latheProto.ID} has recipe {recipeId} which calls for {totalQuantity} units of materials but can only hold {storageComp.StorageLimit}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await pair.CleanReturnAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task AllLatheRecipesValidTest()
|
||||||
|
{
|
||||||
|
await using var pair = await PoolManager.GetServerClient();
|
||||||
|
|
||||||
|
var server = pair.Server;
|
||||||
|
var proto = server.ProtoMan;
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
foreach (var recipe in proto.EnumeratePrototypes<LatheRecipePrototype>())
|
||||||
|
{
|
||||||
|
if (recipe.Result == null)
|
||||||
|
Assert.That(recipe.ResultReagents, Is.Not.Null, $"Recipe '{recipe.ID}' has no result or result reagents.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await pair.CleanReturnAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -98,24 +98,4 @@ public sealed class ResearchTest
|
|||||||
|
|
||||||
await pair.CleanReturnAsync();
|
await pair.CleanReturnAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public async Task AllLatheRecipesValidTest()
|
|
||||||
{
|
|
||||||
await using var pair = await PoolManager.GetServerClient();
|
|
||||||
|
|
||||||
var server = pair.Server;
|
|
||||||
var proto = server.ResolveDependency<IPrototypeManager>();
|
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
foreach (var recipe in proto.EnumeratePrototypes<LatheRecipePrototype>())
|
|
||||||
{
|
|
||||||
if (recipe.Result == null)
|
|
||||||
Assert.That(recipe.ResultReagents, Is.Not.Null, $"Recipe '{recipe.ID}' has no result or result reagents.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await pair.CleanReturnAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user