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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user