diff --git a/refinedstorage-neoforge/build.gradle.kts b/refinedstorage-neoforge/build.gradle.kts index 039e35ba7..f004283d9 100644 --- a/refinedstorage-neoforge/build.gradle.kts +++ b/refinedstorage-neoforge/build.gradle.kts @@ -19,6 +19,7 @@ val commonResources by configurations.existing dependencies { testCompileOnly(libs.apiguardian) + testCompileOnly(project(":refinedstorage-common")) compileOnly(project(":refinedstorage-common")) compileOnly(project(":refinedstorage-common-api")) diff --git a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/GameTestUtil.java b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/GameTestUtil.java index 09b901952..ea15f2a27 100644 --- a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/GameTestUtil.java +++ b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/GameTestUtil.java @@ -277,6 +277,14 @@ public static Runnable storageContainsExactly(final GameTestHelper helper, }); } + public static Runnable storageIsEmpty(final GameTestHelper helper, + final BlockPos networkPos) { + return networkIsAvailable(helper, networkPos, network -> { + final StorageNetworkComponent storage = network.getComponent(StorageNetworkComponent.class); + helper.assertTrue(storage.getStored() == 0, "Storage is not empty"); + }); + } + private static ResourceList toResourceList(final ResourceAmount... resources) { return toResourceList(Arrays.asList(resources)); } @@ -343,13 +351,13 @@ public static void removeItemFromChest(final GameTestHelper helper, public static void prepareInterface(final GameTestHelper helper, final BlockPos pos, - final ResourceAmount... resource) { + final ResourceAmount... resources) { helper.setBlock(pos, RSBLOCKS.getInterface()); final var interfaceBlockEntity = requireBlockEntity(helper, pos, InterfaceBlockEntity.class); final ExportedResourcesContainer exportedResources = interfaceBlockEntity.getExportedResources(); - for (int i = 0; i < resource.length; i++) { - exportedResources.set(i, resource[i]); + for (int i = 0; i < resources.length; i++) { + exportedResources.set(i, resources[i]); } } @@ -362,9 +370,9 @@ public static void addFluidToInterface(final GameTestHelper helper, exportedResources.insert(resource.resource(), resource.amount(), Action.EXECUTE); } - public static void removeFluidToInterface(final GameTestHelper helper, - final BlockPos pos, - final ResourceAmount resource) { + public static void removeFluidFromInterface(final GameTestHelper helper, + final BlockPos pos, + final ResourceAmount resource) { final var interfaceBlockEntity = requireBlockEntity(helper, pos, InterfaceBlockEntity.class); final ExportedResourcesContainer exportedResources = interfaceBlockEntity.getExportedResources(); diff --git a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/exporter/ExporterTest.java b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/exporter/ExporterTest.java index 8046674ba..db7a2808c 100644 --- a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/exporter/ExporterTest.java +++ b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/exporter/ExporterTest.java @@ -186,8 +186,8 @@ public static void shouldExportFluidWithStackUpgrade(final GameTestHelper helper })); // Act - exporter.addUpgradeItem(RSITEMS.getStackUpgrade()); exporter.setFilters(List.of(asResource(WATER))); + exporter.addUpgradeItem(RSITEMS.getStackUpgrade()); // Assert sequence diff --git a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/diskinterface/DiskInterfaceTest.java b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/diskinterface/DiskInterfaceTest.java new file mode 100644 index 000000000..4618f6bd4 --- /dev/null +++ b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/diskinterface/DiskInterfaceTest.java @@ -0,0 +1,313 @@ +package com.refinedmods.refinedstorage.common.storage.diskinterface; + +import com.refinedmods.refinedstorage.api.network.impl.node.storagetransfer.StorageTransferMode; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.filter.FilterMode; +import com.refinedmods.refinedstorage.common.util.IdentifierUtil; + +import java.util.Set; + +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import static com.refinedmods.refinedstorage.common.GameTestUtil.RSITEMS; +import static com.refinedmods.refinedstorage.common.GameTestUtil.asResource; +import static com.refinedmods.refinedstorage.common.GameTestUtil.getItemAsDamaged; +import static com.refinedmods.refinedstorage.common.GameTestUtil.insert; +import static com.refinedmods.refinedstorage.common.GameTestUtil.networkIsAvailable; +import static com.refinedmods.refinedstorage.common.GameTestUtil.storageContainsExactly; +import static com.refinedmods.refinedstorage.common.GameTestUtil.storageIsEmpty; +import static com.refinedmods.refinedstorage.common.storage.diskinterface.DiskInterfaceTestPlots.addDiskToDiskInterface; +import static com.refinedmods.refinedstorage.common.storage.diskinterface.DiskInterfaceTestPlots.isDiskInOutputWithAmount; +import static com.refinedmods.refinedstorage.common.storage.diskinterface.DiskInterfaceTestPlots.preparePlot; +import static net.minecraft.world.item.Items.DIAMOND_CHESTPLATE; +import static net.minecraft.world.item.Items.DIRT; + +@GameTestHolder(IdentifierUtil.MOD_ID) +@PrefixGameTestTemplate(false) +public final class DiskInterfaceTest { + private DiskInterfaceTest() { + } + + @GameTest(template = "empty_15x15") + public static void shouldInsertItemsIntoNetwork(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 64); + })); + + // Act + diskInterface.setTransferMode(StorageTransferMode.INSERT_INTO_NETWORK); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 64) + )) + .thenExecute(() -> addDiskToDiskInterface( + helper, + pos, + new ResourceAmount(asResource(DIRT), 10))) + .thenIdle(9 * 10) + .thenExecute(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 74) + )) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 0)) + .thenSucceed(); + }); + } + + @GameTest(template = "empty_15x15") + public static void shouldInsertItemsIntoNetworkWithStackUpgrade(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 64); + })); + + // Act + diskInterface.setTransferMode(StorageTransferMode.INSERT_INTO_NETWORK); + diskInterface.addUpgradeItem(RSITEMS.getStackUpgrade()); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 64) + )) + .thenExecute(() -> addDiskToDiskInterface( + helper, + pos, + new ResourceAmount(asResource(DIRT), 64))) + .thenIdle(9) + .thenExecute(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 128) + )) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 0)) + .thenSucceed(); + }); + } + + @GameTest(template = "empty_15x15") + public static void shouldInsertItemsIntoNetworkBlocklist(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 64); + })); + + // Act + final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500); + + diskInterface.setTransferMode(StorageTransferMode.INSERT_INTO_NETWORK); + diskInterface.setFuzzyMode(false); + diskInterface.setFilters(Set.of(asResource(damagedDiamondChestplate))); + diskInterface.setFilterMode(FilterMode.BLOCK); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 64) + )) + .thenExecute(() -> addDiskToDiskInterface( + helper, + pos, + new ResourceAmount(asResource(DIRT), 5), + new ResourceAmount(asResource(damagedDiamondChestplate), 1) + )) + .thenIdle(9 * 6) + .thenExecute(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 69) + )) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 1)) + .thenSucceed(); + }); + } + + @GameTest(template = "empty_15x15") + public static void shouldInsertItemsIntoNetworkFuzzyBlocklist(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 64); + })); + + // Act + final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500); + + diskInterface.setTransferMode(StorageTransferMode.INSERT_INTO_NETWORK); + diskInterface.setFuzzyMode(true); + diskInterface.setFilters(Set.of(asResource(DIAMOND_CHESTPLATE.getDefaultInstance()))); + diskInterface.setFilterMode(FilterMode.BLOCK); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 64) + )) + .thenExecute(() -> addDiskToDiskInterface( + helper, + pos, + new ResourceAmount(asResource(DIRT), 5), + new ResourceAmount(asResource(damagedDiamondChestplate), 1), + new ResourceAmount(asResource(DIAMOND_CHESTPLATE.getDefaultInstance()), 1) + )) + .thenIdle(9 * 7) + .thenExecute(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 69) + )) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 2)) + .thenSucceed(); + }); + } + + @GameTest(template = "empty_15x15") + public static void shouldExtractItemsFromNetwork(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 10); + })); + + // Act + diskInterface.setTransferMode(StorageTransferMode.EXTRACT_FROM_NETWORK); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 10) + )) + .thenExecute(() -> addDiskToDiskInterface(helper, pos)) + .thenIdle(9 * 10) + .thenExecute(storageIsEmpty(helper, pos)) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 10)) + .thenSucceed(); + }); + } + + @GameTest(template = "empty_15x15") + public static void shouldExtractItemsFromNetworkWithStackUpgrade(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 64); + })); + + // Act + diskInterface.setTransferMode(StorageTransferMode.EXTRACT_FROM_NETWORK); + diskInterface.addUpgradeItem(RSITEMS.getStackUpgrade()); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 64) + )) + .thenExecute(() -> addDiskToDiskInterface(helper, pos)) + .thenIdle(9) + .thenExecute(storageIsEmpty(helper, pos)) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 64)) + .thenSucceed(); + }); + } + + @GameTest(template = "empty_15x15") + public static void shouldExtractItemsFromNetworkBlocklist(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500); + + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 5); + insert(helper, network, asResource(damagedDiamondChestplate), 1); + })); + + // Act + diskInterface.setTransferMode(StorageTransferMode.EXTRACT_FROM_NETWORK); + diskInterface.setFuzzyMode(false); + diskInterface.setFilters(Set.of(asResource(damagedDiamondChestplate))); + diskInterface.setFilterMode(FilterMode.BLOCK); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 5), + new ResourceAmount(asResource(damagedDiamondChestplate), 1) + )) + .thenExecute(() -> addDiskToDiskInterface(helper, pos)) + .thenIdle(9 * 6) + .thenExecute(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(damagedDiamondChestplate), 1) + )) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 5)) + .thenSucceed(); + }); + } + + @GameTest(template = "empty_15x15") + public static void shouldExtractItemsFromNetworkFuzzyBlocklist(final GameTestHelper helper) { + preparePlot(helper, Direction.NORTH, (diskInterface, pos, sequence) -> { + final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500); + + // Arrange + sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> { + insert(helper, network, DIRT, 5); + insert(helper, network, asResource(damagedDiamondChestplate), 1); + insert(helper, network, DIAMOND_CHESTPLATE, 1); + })); + + // Act + diskInterface.setTransferMode(StorageTransferMode.EXTRACT_FROM_NETWORK); + diskInterface.setFuzzyMode(true); + diskInterface.setFilters(Set.of(asResource(DIAMOND_CHESTPLATE.getDefaultInstance()))); + diskInterface.setFilterMode(FilterMode.BLOCK); + + // Assert + sequence + .thenWaitUntil(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(DIRT), 5), + new ResourceAmount(asResource(damagedDiamondChestplate), 1), + new ResourceAmount(asResource(DIAMOND_CHESTPLATE), 1) + )) + .thenExecute(() -> addDiskToDiskInterface(helper, pos)) + .thenIdle(9 * 7) + .thenExecute(storageContainsExactly( + helper, + pos, + new ResourceAmount(asResource(damagedDiamondChestplate), 1), + new ResourceAmount(asResource(DIAMOND_CHESTPLATE), 1) + )) + .thenExecute(() -> isDiskInOutputWithAmount(helper, pos, 5)) + .thenSucceed(); + }); + } +} diff --git a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/diskinterface/DiskInterfaceTestPlots.java b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/diskinterface/DiskInterfaceTestPlots.java new file mode 100644 index 000000000..d09b68a14 --- /dev/null +++ b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/diskinterface/DiskInterfaceTestPlots.java @@ -0,0 +1,89 @@ +package com.refinedmods.refinedstorage.common.storage.diskinterface; + +import com.refinedmods.refinedstorage.api.core.Action; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.storage.Storage; +import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; +import com.refinedmods.refinedstorage.common.api.storage.PlayerActor; +import com.refinedmods.refinedstorage.common.content.Items; +import com.refinedmods.refinedstorage.common.storage.ItemStorageVariant; +import com.refinedmods.refinedstorage.common.support.FilteredContainer; +import com.refinedmods.refinedstorage.common.support.direction.BiDirection; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTestAssertException; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.gametest.framework.GameTestSequence; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.GameType; +import org.apache.commons.lang3.function.TriConsumer; + +import static com.refinedmods.refinedstorage.common.GameTestUtil.RSBLOCKS; +import static com.refinedmods.refinedstorage.common.GameTestUtil.requireBlockEntity; +import static net.minecraft.core.BlockPos.ZERO; + +final class DiskInterfaceTestPlots { + private DiskInterfaceTestPlots() { + } + + static void preparePlot(final GameTestHelper helper, + final Direction direction, + final TriConsumer consumer) { + helper.setBlock(ZERO.above(), RSBLOCKS.getCreativeController().getDefault()); + helper.setBlock(ZERO.above().above(), RSBLOCKS.getItemStorageBlock(ItemStorageVariant.ONE_K)); + final BlockPos diskInterfacePos = ZERO.above().above().above(); + helper.setBlock(diskInterfacePos, RSBLOCKS.getDiskInterface().getDefault() + .rotated(BiDirection.forDirection(direction))); + consumer.accept( + requireBlockEntity(helper, diskInterfacePos, AbstractDiskInterfaceBlockEntity.class), + diskInterfacePos, + helper.startSequence() + ); + } + + static void addDiskToDiskInterface(final GameTestHelper helper, + final BlockPos diskInterfacePos, + final ResourceAmount... resources) { + final ItemStack diskItem = new ItemStack(Items.INSTANCE.getItemStorageDisk(ItemStorageVariant.SIXTY_FOUR_K)); + diskItem.inventoryTick(helper.getLevel(), helper.makeMockPlayer(GameType.SURVIVAL), 0, false); + + final Storage storage = getStorageFromDisk(helper, diskItem); + if (resources.length > 0) { + final PlayerActor actor = new PlayerActor(helper.makeMockPlayer(GameType.SURVIVAL)); + for (final ResourceAmount resource : resources) { + if (resource != null) { + storage.insert(resource.resource(), resource.amount(), Action.EXECUTE, actor); + } + } + } + + final var diskInterfaceBlockEntity = requireBlockEntity(helper, diskInterfacePos, + AbstractDiskInterfaceBlockEntity.class); + final FilteredContainer diskInterfaceContainer = diskInterfaceBlockEntity.getDiskInventory(); + diskInterfaceContainer.addItem(diskItem); + } + + static void isDiskInOutputWithAmount(final GameTestHelper helper, + final BlockPos diskInterfacePos, + final int storedAmount) { + final var diskInterfaceBlockEntity = requireBlockEntity(helper, diskInterfacePos, + AbstractDiskInterfaceBlockEntity.class); + final FilteredContainer diskInterfaceContainer = diskInterfaceBlockEntity.getDiskInventory(); + + final ItemStack diskItem = diskInterfaceContainer.getItem(3); + final Storage storage = getStorageFromDisk(helper, diskItem); + + helper.assertTrue(!diskItem.isEmpty(), "Could not find a Storage Disk in the output slot"); + helper.assertTrue(storage.getStored() == storedAmount, "Expected Storage Disk stored amount " + + storedAmount + ", but was " + storage.getStored()); + } + + private static Storage getStorageFromDisk(final GameTestHelper helper, + final ItemStack diskItem) { + return RefinedStorageApi.INSTANCE + .getStorageContainerItemHelper() + .resolveStorage(RefinedStorageApi.INSTANCE.getStorageRepository(helper.getLevel()), diskItem) + .orElseThrow(() -> new GameTestAssertException("Couldn't find SerializableStorage from Storage Disk")); + } +} diff --git a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/externalstorage/ExternalStorageFluidTest.java b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/externalstorage/ExternalStorageFluidTest.java index 0a91639cd..f61a9ba3d 100644 --- a/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/externalstorage/ExternalStorageFluidTest.java +++ b/refinedstorage-neoforge/src/test/java/com/refinedmods/refinedstorage/common/storage/externalstorage/ExternalStorageFluidTest.java @@ -19,7 +19,7 @@ import static com.refinedmods.refinedstorage.common.GameTestUtil.interfaceContainsExactly; import static com.refinedmods.refinedstorage.common.GameTestUtil.networkIsAvailable; import static com.refinedmods.refinedstorage.common.GameTestUtil.prepareInterface; -import static com.refinedmods.refinedstorage.common.GameTestUtil.removeFluidToInterface; +import static com.refinedmods.refinedstorage.common.GameTestUtil.removeFluidFromInterface; import static com.refinedmods.refinedstorage.common.GameTestUtil.storageContainsExactly; import static com.refinedmods.refinedstorage.common.storage.externalstorage.ExternalStorageTestPlots.preparePlot; import static net.minecraft.world.item.Items.STONE; @@ -223,7 +223,7 @@ public static void shouldPropagateExternalFluidExtractions(final GameTestHelper new ResourceAmount(asResource(WATER), Platform.INSTANCE.getBucketAmount()), new ResourceAmount(asResource(LAVA), Platform.INSTANCE.getBucketAmount() * 2) )) - .thenExecute(() -> removeFluidToInterface( + .thenExecute(() -> removeFluidFromInterface( helper, pos.east(), new ResourceAmount(asResource(LAVA), Platform.INSTANCE.getBucketAmount() * 2) @@ -272,7 +272,7 @@ public static void shouldPropagatePartialExternalFluidExtractions(final GameTest new ResourceAmount(asResource(WATER), Platform.INSTANCE.getBucketAmount()), new ResourceAmount(asResource(LAVA), Platform.INSTANCE.getBucketAmount() * 2) )) - .thenExecute(() -> removeFluidToInterface( + .thenExecute(() -> removeFluidFromInterface( helper, pos.east(), new ResourceAmount(asResource(LAVA), Platform.INSTANCE.getBucketAmount())