]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add test checking for multiple container fills, mark StorageFillComponent as obsolete...
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Mon, 24 Nov 2025 07:51:14 +0000 (08:51 +0100)
committerGitHub <noreply@github.com>
Mon, 24 Nov 2025 07:51:14 +0000 (07:51 +0000)
add test, obsolete storagefill

Content.IntegrationTests/Tests/Storage/StorageTest.cs [new file with mode: 0644]
Content.IntegrationTests/Tests/StorageTest.cs [deleted file]
Content.Shared/Storage/Components/StorageFillComponent.cs

diff --git a/Content.IntegrationTests/Tests/Storage/StorageTest.cs b/Content.IntegrationTests/Tests/Storage/StorageTest.cs
new file mode 100644 (file)
index 0000000..95d9490
--- /dev/null
@@ -0,0 +1,263 @@
+#nullable enable
+using System.Collections.Generic;
+using System.Linq;
+using Content.Shared.Containers;
+using Content.Shared.Item;
+using Content.Shared.Prototypes;
+using Content.Shared.Storage;
+using Content.Shared.Storage.Components;
+using Content.Shared.Storage.EntitySystems;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Prototypes;
+
+namespace Content.IntegrationTests.Tests.Storage;
+
+public sealed class StorageTest
+{
+    /// <summary>
+    /// Can an item store more than itself weighs.
+    /// In an ideal world this test wouldn't need to exist because sizes would be recursive.
+    /// </summary>
+    [Test]
+    public async Task StorageSizeArbitrageTest()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var protoManager = server.ResolveDependency<IPrototypeManager>();
+        var entMan = server.ResolveDependency<IEntityManager>();
+
+        var itemSys = entMan.System<SharedItemSystem>();
+
+        await server.WaitAssertion(() =>
+        {
+            foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
+            {
+                if (!proto.TryGetComponent<StorageComponent>("Storage", out var storage) ||
+                    storage.Whitelist != null ||
+                    storage.MaxItemSize == null ||
+                    !proto.TryGetComponent<ItemComponent>("Item", out var item))
+                    continue;
+
+                Assert.That(itemSys.GetSizePrototype(storage.MaxItemSize.Value).Weight,
+                    Is.LessThanOrEqualTo(itemSys.GetSizePrototype(item.Size).Weight),
+                    $"Found storage arbitrage on {proto.ID}");
+            }
+        });
+        await pair.CleanReturnAsync();
+    }
+
+    [Test]
+    public async Task TestStorageFillPrototypes()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var protoManager = server.ResolveDependency<IPrototypeManager>();
+
+        await server.WaitAssertion(() =>
+        {
+            Assert.Multiple(() =>
+            {
+                foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
+                {
+                    if (!proto.TryGetComponent<StorageFillComponent>("StorageFill", out var storage))
+                        continue;
+
+                    foreach (var entry in storage.Contents)
+                    {
+                        Assert.That(entry.Amount, Is.GreaterThan(0), $"Specified invalid amount of {entry.Amount} for prototype {proto.ID}");
+                        Assert.That(entry.SpawnProbability, Is.GreaterThan(0), $"Specified invalid probability of {entry.SpawnProbability} for prototype {proto.ID}");
+                    }
+                }
+            });
+        });
+        await pair.CleanReturnAsync();
+    }
+
+    [Test]
+    public async Task TestSufficientSpaceForFill()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var entMan = server.ResolveDependency<IEntityManager>();
+        var protoMan = server.ResolveDependency<IPrototypeManager>();
+        var compFact = server.ResolveDependency<IComponentFactory>();
+        var id = compFact.GetComponentName<StorageFillComponent>();
+
+        var itemSys = entMan.System<SharedItemSystem>();
+
+        var allSizes = protoMan.EnumeratePrototypes<ItemSizePrototype>().ToList();
+        allSizes.Sort();
+
+        await Assert.MultipleAsync(async () =>
+        {
+            foreach (var (proto, fill) in pair.GetPrototypesWithComponent<StorageFillComponent>())
+            {
+                if (proto.HasComponent<EntityStorageComponent>(compFact))
+                    continue;
+
+                StorageComponent? storage = null;
+                ItemComponent? item = null;
+                var size = 0;
+                await server.WaitAssertion(() =>
+                {
+                    if (!proto.TryGetComponent("Storage", out storage))
+                    {
+                        Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!");
+                        return;
+                    }
+
+                    proto.TryGetComponent("Item", out item);
+                    size = GetFillSize(fill, false, protoMan, itemSys);
+                });
+
+                if (storage == null)
+                    continue;
+
+                var maxSize = storage.MaxItemSize;
+                if (storage.MaxItemSize == null)
+                {
+                    if (item?.Size == null)
+                    {
+                        maxSize = SharedStorageSystem.DefaultStorageMaxItemSize;
+                    }
+                    else
+                    {
+                        var curIndex = allSizes.IndexOf(protoMan.Index(item.Size));
+                        var index = Math.Max(0, curIndex - 1);
+                        maxSize = allSizes[index].ID;
+                    }
+                }
+
+                if (maxSize == null)
+                    continue;
+
+                Assert.That(size, Is.LessThanOrEqualTo(storage.Grid.GetArea()), $"{proto.ID} storage fill is too large.");
+
+                foreach (var entry in fill.Contents)
+                {
+                    if (entry.PrototypeId == null)
+                        continue;
+
+                    if (!protoMan.TryIndex<EntityPrototype>(entry.PrototypeId, out var fillItem))
+                        continue;
+
+                    ItemComponent? entryItem = null;
+                    await server.WaitPost(() =>
+                    {
+                        fillItem.TryGetComponent("Item", out entryItem);
+                    });
+
+                    if (entryItem == null)
+                        continue;
+
+                    Assert.That(protoMan.Index(entryItem.Size).Weight,
+                        Is.LessThanOrEqualTo(protoMan.Index(maxSize.Value).Weight),
+                        $"Entity {proto.ID} has storage-fill item, {entry.PrototypeId}, that is too large");
+                }
+            }
+        });
+
+        await pair.CleanReturnAsync();
+    }
+
+    [Test]
+    public async Task TestSufficientSpaceForEntityStorageFill()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var entMan = server.ResolveDependency<IEntityManager>();
+        var protoMan = server.ResolveDependency<IPrototypeManager>();
+        var compFact = server.ResolveDependency<IComponentFactory>();
+        var id = compFact.GetComponentName<StorageFillComponent>();
+
+        var itemSys = entMan.System<SharedItemSystem>();
+
+        foreach (var (proto, fill) in pair.GetPrototypesWithComponent<StorageFillComponent>())
+        {
+            if (proto.HasComponent<StorageComponent>(compFact))
+                continue;
+
+            await server.WaitAssertion(() =>
+            {
+                if (!proto.TryGetComponent("EntityStorage", out EntityStorageComponent? entStorage))
+                    Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!");
+
+                if (entStorage == null)
+                    return;
+
+                var size = GetFillSize(fill, true, protoMan, itemSys);
+                Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity),
+                    $"{proto.ID} storage fill is too large.");
+            });
+        }
+        await pair.CleanReturnAsync();
+    }
+
+    private int GetEntrySize(EntitySpawnEntry entry, bool getCount, IPrototypeManager protoMan, SharedItemSystem itemSystem)
+    {
+        if (entry.PrototypeId == null)
+            return 0;
+
+        if (!protoMan.TryIndex<EntityPrototype>(entry.PrototypeId, out var proto))
+        {
+            Assert.Fail($"Unknown prototype: {entry.PrototypeId}");
+            return 0;
+        }
+
+        if (getCount)
+            return entry.Amount;
+
+
+        if (proto.TryGetComponent<ItemComponent>("Item", out var item))
+            return itemSystem.GetItemShape(item).GetArea() * entry.Amount;
+
+        Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}");
+        return 0;
+    }
+
+    private int GetFillSize(StorageFillComponent fill, bool getCount, IPrototypeManager protoMan, SharedItemSystem itemSystem)
+    {
+        var totalSize = 0;
+        var groups = new Dictionary<string, int>();
+        foreach (var entry in fill.Contents)
+        {
+            var size = GetEntrySize(entry, getCount, protoMan, itemSystem);
+
+            if (entry.GroupId == null)
+                totalSize += size;
+            else
+                groups[entry.GroupId] = Math.Max(size, groups.GetValueOrDefault(entry.GroupId));
+        }
+
+        return totalSize + groups.Values.Sum();
+    }
+
+    /// <summary>
+    /// Tests that prototypes are not using multiple container fill components at the same time.
+    /// </summary>
+    [Test]
+    public async Task NoMultipleContainerFillsTest()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var compFact = pair.Server.ResolveDependency<IComponentFactory>();
+
+        Assert.Multiple(() =>
+        {
+            foreach (var (proto, fill) in pair.GetPrototypesWithComponent<EntityTableContainerFillComponent>())
+            {
+                Assert.That(!proto.HasComponent<StorageFillComponent>(compFact), $"Prototype {proto.ID} has both {nameof(EntityTableContainerFillComponent)} and {nameof(StorageFillComponent)}.");
+                Assert.That(!proto.HasComponent<ContainerFillComponent>(compFact), $"Prototype {proto.ID} has both {nameof(EntityTableContainerFillComponent)} and {nameof(ContainerFillComponent)}.");
+            }
+
+            foreach (var (proto, fill) in pair.GetPrototypesWithComponent<ContainerFillComponent>())
+            {
+                Assert.That(!proto.HasComponent<StorageFillComponent>(compFact), $"Prototype {proto.ID} has both {nameof(ContainerFillComponent)} and {nameof(StorageFillComponent)}.");
+            }
+        });
+        await pair.CleanReturnAsync();
+    }
+}
diff --git a/Content.IntegrationTests/Tests/StorageTest.cs b/Content.IntegrationTests/Tests/StorageTest.cs
deleted file mode 100644 (file)
index 13ddc56..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-#nullable enable
-using System.Collections.Generic;
-using System.Linq;
-using Content.Server.Storage.Components;
-using Content.Shared.Item;
-using Content.Shared.Prototypes;
-using Content.Shared.Storage;
-using Content.Shared.Storage.Components;
-using Content.Shared.Storage.EntitySystems;
-using Robust.Shared.GameObjects;
-using Robust.Shared.Prototypes;
-
-namespace Content.IntegrationTests.Tests
-{
-    [TestFixture]
-    public sealed class StorageTest
-    {
-        /// <summary>
-        /// Can an item store more than itself weighs.
-        /// In an ideal world this test wouldn't need to exist because sizes would be recursive.
-        /// </summary>
-        [Test]
-        public async Task StorageSizeArbitrageTest()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoManager = server.ResolveDependency<IPrototypeManager>();
-            var entMan = server.ResolveDependency<IEntityManager>();
-
-            var itemSys = entMan.System<SharedItemSystem>();
-
-            await server.WaitAssertion(() =>
-            {
-                foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
-                {
-                    if (!proto.TryGetComponent<StorageComponent>("Storage", out var storage) ||
-                        storage.Whitelist != null ||
-                        storage.MaxItemSize == null ||
-                        !proto.TryGetComponent<ItemComponent>("Item", out var item))
-                        continue;
-
-                    Assert.That(itemSys.GetSizePrototype(storage.MaxItemSize.Value).Weight,
-                        Is.LessThanOrEqualTo(itemSys.GetSizePrototype(item.Size).Weight),
-                        $"Found storage arbitrage on {proto.ID}");
-                }
-            });
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task TestStorageFillPrototypes()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoManager = server.ResolveDependency<IPrototypeManager>();
-
-            await server.WaitAssertion(() =>
-            {
-                Assert.Multiple(() =>
-                {
-                    foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
-                    {
-                        if (!proto.TryGetComponent<StorageFillComponent>("StorageFill", out var storage))
-                            continue;
-
-                        foreach (var entry in storage.Contents)
-                        {
-                            Assert.That(entry.Amount, Is.GreaterThan(0), $"Specified invalid amount of {entry.Amount} for prototype {proto.ID}");
-                            Assert.That(entry.SpawnProbability, Is.GreaterThan(0), $"Specified invalid probability of {entry.SpawnProbability} for prototype {proto.ID}");
-                        }
-                    }
-                });
-            });
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task TestSufficientSpaceForFill()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var entMan = server.ResolveDependency<IEntityManager>();
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-            var compFact = server.ResolveDependency<IComponentFactory>();
-            var id = compFact.GetComponentName<StorageFillComponent>();
-
-            var itemSys = entMan.System<SharedItemSystem>();
-
-            var allSizes = protoMan.EnumeratePrototypes<ItemSizePrototype>().ToList();
-            allSizes.Sort();
-
-            await Assert.MultipleAsync(async () =>
-            {
-                foreach (var (proto, fill) in pair.GetPrototypesWithComponent<StorageFillComponent>())
-                {
-                    if (proto.HasComponent<EntityStorageComponent>(compFact))
-                        continue;
-
-                    StorageComponent? storage = null;
-                    ItemComponent? item = null;
-                    var size = 0;
-                    await server.WaitAssertion(() =>
-                    {
-                        if (!proto.TryGetComponent("Storage", out storage))
-                        {
-                            Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!");
-                            return;
-                        }
-
-                        proto.TryGetComponent("Item", out item);
-                        size = GetFillSize(fill, false, protoMan, itemSys);
-                    });
-
-                    if (storage == null)
-                        continue;
-
-                    var maxSize = storage.MaxItemSize;
-                    if (storage.MaxItemSize == null)
-                    {
-                        if (item?.Size == null)
-                        {
-                            maxSize = SharedStorageSystem.DefaultStorageMaxItemSize;
-                        }
-                        else
-                        {
-                            var curIndex = allSizes.IndexOf(protoMan.Index(item.Size));
-                            var index = Math.Max(0, curIndex - 1);
-                            maxSize = allSizes[index].ID;
-                        }
-                    }
-
-                    if (maxSize == null)
-                        continue;
-
-                    Assert.That(size, Is.LessThanOrEqualTo(storage.Grid.GetArea()), $"{proto.ID} storage fill is too large.");
-
-                    foreach (var entry in fill.Contents)
-                    {
-                        if (entry.PrototypeId == null)
-                            continue;
-
-                        if (!protoMan.TryIndex<EntityPrototype>(entry.PrototypeId, out var fillItem))
-                            continue;
-
-                        ItemComponent? entryItem = null;
-                        await server.WaitPost(() =>
-                        {
-                            fillItem.TryGetComponent("Item", out entryItem);
-                        });
-
-                        if (entryItem == null)
-                            continue;
-
-                        Assert.That(protoMan.Index(entryItem.Size).Weight,
-                            Is.LessThanOrEqualTo(protoMan.Index(maxSize.Value).Weight),
-                            $"Entity {proto.ID} has storage-fill item, {entry.PrototypeId}, that is too large");
-                    }
-                }
-            });
-
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task TestSufficientSpaceForEntityStorageFill()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var entMan = server.ResolveDependency<IEntityManager>();
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-            var compFact = server.ResolveDependency<IComponentFactory>();
-            var id = compFact.GetComponentName<StorageFillComponent>();
-
-            var itemSys = entMan.System<SharedItemSystem>();
-
-            foreach (var (proto, fill) in pair.GetPrototypesWithComponent<StorageFillComponent>())
-            {
-                if (proto.HasComponent<StorageComponent>(compFact))
-                    continue;
-
-                await server.WaitAssertion(() =>
-                {
-                    if (!proto.TryGetComponent("EntityStorage", out EntityStorageComponent? entStorage))
-                        Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!");
-
-                    if (entStorage == null)
-                        return;
-
-                    var size = GetFillSize(fill, true, protoMan, itemSys);
-                    Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity),
-                        $"{proto.ID} storage fill is too large.");
-                });
-            }
-            await pair.CleanReturnAsync();
-        }
-
-        private int GetEntrySize(EntitySpawnEntry entry, bool getCount, IPrototypeManager protoMan, SharedItemSystem itemSystem)
-        {
-            if (entry.PrototypeId == null)
-                return 0;
-
-            if (!protoMan.TryIndex<EntityPrototype>(entry.PrototypeId, out var proto))
-            {
-                Assert.Fail($"Unknown prototype: {entry.PrototypeId}");
-                return 0;
-            }
-
-            if (getCount)
-                return entry.Amount;
-
-
-            if (proto.TryGetComponent<ItemComponent>("Item", out var item))
-                return itemSystem.GetItemShape(item).GetArea() * entry.Amount;
-
-            Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}");
-            return 0;
-        }
-
-        private int GetFillSize(StorageFillComponent fill, bool getCount, IPrototypeManager protoMan, SharedItemSystem itemSystem)
-        {
-            var totalSize = 0;
-            var groups = new Dictionary<string, int>();
-            foreach (var entry in fill.Contents)
-            {
-                var size = GetEntrySize(entry, getCount, protoMan, itemSystem);
-
-                if (entry.GroupId == null)
-                    totalSize += size;
-                else
-                    groups[entry.GroupId] = Math.Max(size, groups.GetValueOrDefault(entry.GroupId));
-            }
-
-            return totalSize + groups.Values.Sum();
-        }
-    }
-}
index e112368a4961aab702568d520657101fd04b1c17..22ae32c4a8a5721f996b6aaa789fd35e9101cc50 100644 (file)
@@ -3,8 +3,9 @@ using Robust.Shared.GameStates;
 
 namespace Content.Shared.Storage.Components;
 
-// TODO:
-// REPLACE THIS WITH CONTAINERFILL
+// Don't remove before December 2026.
+// A lot of forks still use this for their prototypes.
+[Obsolete("Use ContainerFillComponent or EntityTableContainerFillComponent instead")]
 [RegisterComponent, NetworkedComponent, Access(typeof(SharedStorageSystem))]
 public sealed partial class StorageFillComponent : Component
 {