diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml index b0d870283..8b6e49245 100644 --- a/config/checkstyle/checkstyle-suppressions.xml +++ b/config/checkstyle/checkstyle-suppressions.xml @@ -10,4 +10,5 @@ + diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/constructordestructor/ConstructorBlockEntity.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/constructordestructor/ConstructorBlockEntity.java index 4c870f75e..45cf2e459 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/constructordestructor/ConstructorBlockEntity.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/constructordestructor/ConstructorBlockEntity.java @@ -57,7 +57,7 @@ public ConstructorBlockEntity(final BlockPos pos, final BlockState state) { } @Override - protected void setFilters(final List filters) { + public void setFilters(final List filters) { this.tasks.clear(); this.tasks.addAll(filters.stream().map(TaskImpl::new).toList()); } diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/exporter/ExporterBlockEntity.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/exporter/ExporterBlockEntity.java index 5ea3d2f31..2b911edb6 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/exporter/ExporterBlockEntity.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/exporter/ExporterBlockEntity.java @@ -95,7 +95,7 @@ protected void setTaskExecutor(final TaskExecutor filters) { + public void setFilters(final List filters) { mainNode.setFilters(filters); } diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/AbstractDirectionalBlock.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/AbstractDirectionalBlock.java index b8f86a1c7..b61083c3c 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/AbstractDirectionalBlock.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/AbstractDirectionalBlock.java @@ -70,6 +70,10 @@ public Direction extractDirection(@Nullable final BlockState state) { return getDirectionType().extractDirection(direction); } + public BlockState rotated(final T direction) { + return defaultBlockState().setValue(getDirectionType().getProperty(), direction); + } + public static boolean doesBlockStateChangeWarrantNetworkNodeUpdate(final BlockState oldBlockState, final BlockState newBlockState) { if (!(newBlockState.getBlock() instanceof AbstractDirectionalBlock newDirectionalBlock)) { diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractSchedulingNetworkNodeContainerBlockEntity.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractSchedulingNetworkNodeContainerBlockEntity.java index df09b565f..dac1392be 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractSchedulingNetworkNodeContainerBlockEntity.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractSchedulingNetworkNodeContainerBlockEntity.java @@ -82,5 +82,5 @@ public void writeScreenOpeningData(final ServerPlayer player, final FriendlyByte protected abstract void setTaskExecutor(TaskExecutor taskExecutor); - protected abstract void setFilters(List filters); + public abstract void setFilters(List filters); } diff --git a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractUpgradeableNetworkNodeContainerBlockEntity.java b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractUpgradeableNetworkNodeContainerBlockEntity.java index 6939537ae..27f36f9ed 100644 --- a/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractUpgradeableNetworkNodeContainerBlockEntity.java +++ b/refinedstorage2-platform-common/src/main/java/com/refinedmods/refinedstorage2/platform/common/support/network/AbstractUpgradeableNetworkNodeContainerBlockEntity.java @@ -10,7 +10,6 @@ import java.util.ArrayList; import java.util.List; -import com.google.common.util.concurrent.RateLimiter; import net.minecraft.core.BlockPos; import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; @@ -33,7 +32,8 @@ public abstract class AbstractUpgradeableNetworkNodeContainerBlockEntity type, @@ -52,7 +52,7 @@ protected AbstractUpgradeableNetworkNodeContainerBlockEntity( @Override public final void doWork() { - if (rateLimiter.tryAcquire()) { + if (workTicks++ % workTickRate == 0) { super.doWork(); postDoWork(); } @@ -105,16 +105,12 @@ public void load(final CompoundTag tag) { private void configureAccordingToUpgrades() { LOGGER.debug("Reconfiguring {} for upgrades", getBlockPos()); final int amountOfSpeedUpgrades = upgradeContainer.getAmount(Items.INSTANCE.getSpeedUpgrade()); - this.rateLimiter = createRateLimiter(amountOfSpeedUpgrades); + this.workTickRate = (amountOfSpeedUpgrades + 1) * 20; this.setEnergyUsage(upgradeContainer.getEnergyUsage()); } protected abstract void setEnergyUsage(long upgradeEnergyUsage); - private static RateLimiter createRateLimiter(final int amountOfSpeedUpgrades) { - return RateLimiter.create((double) amountOfSpeedUpgrades + 1); - } - @Override public NonNullList getDrops() { final NonNullList drops = NonNullList.create(); diff --git a/refinedstorage2-platform-forge/build.gradle b/refinedstorage2-platform-forge/build.gradle index 3e5fc0444..e238e0037 100644 --- a/refinedstorage2-platform-forge/build.gradle +++ b/refinedstorage2-platform-forge/build.gradle @@ -32,4 +32,18 @@ dependencies { compileOnly "top.theillusivec4.curios:curios-neoforge:7.1.0+1.20.4:api" } +sourceSets { + test { + minecraft { + modIdentifier = 'rstest' + } + } +} + +runs { + gameTestServer { + systemProperty 'neoforge.enabledGameTestNamespaces', 'refinedstorage2_tests' + } +} + enablePublishing() diff --git a/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/ConstructorTest.java b/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/ConstructorTest.java new file mode 100644 index 000000000..076dbd5ae --- /dev/null +++ b/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/ConstructorTest.java @@ -0,0 +1,49 @@ +package com.refinedmods.refinedstorage2.platform.forge; + +import com.refinedmods.refinedstorage2.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage2.platform.common.constructordestructor.ConstructorBlockEntity; +import com.refinedmods.refinedstorage2.platform.common.storage.ItemStorageType; + +import java.util.List; + +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.gametest.EmptyTemplate; +import net.neoforged.testframework.gametest.ExtendedGameTestHelper; + +import static com.refinedmods.refinedstorage2.platform.forge.TestMod.DIRT; +import static com.refinedmods.refinedstorage2.platform.forge.TestMod.RSBLOCKS; +import static com.refinedmods.refinedstorage2.platform.forge.TestMod.itemIsInserted; +import static com.refinedmods.refinedstorage2.platform.forge.TestMod.storageMustContainExactly; +import static net.minecraft.core.BlockPos.ZERO; + +public final class ConstructorTest { + private ConstructorTest() { + } + + @GameTest + @EmptyTemplate(value = "5x5x5", floor = true) + @TestHolder(description = "Tests whether the Constructor can place a block") + public static void shouldPlaceBlock(final ExtendedGameTestHelper helper) { + // Arrange + helper.setBlock(ZERO.above(), RSBLOCKS.getCreativeController().getDefault()); + helper.setBlock(ZERO.above().above(), RSBLOCKS.getConstructor().getDefault().rotated(Direction.EAST)); + helper.setBlock( + ZERO.above().above().above(), + RSBLOCKS.getItemStorageBlock(ItemStorageType.Variant.ONE_K) + ); + + final var seq = helper.startSequence(); + seq.thenWaitUntil(itemIsInserted(helper, ZERO.above().above(), DIRT, 10)); + + // Act + helper.requireBlockEntity(ZERO.above().above(), ConstructorBlockEntity.class).setFilters(List.of(DIRT)); + + // Assert + seq.thenWaitUntil(() -> helper.assertBlockPresent(Blocks.DIRT, ZERO.above().above().east())) + .thenWaitUntil(storageMustContainExactly(helper, ZERO.above().above(), new ResourceAmount(DIRT, 9))) + .thenSucceed(); + } +} diff --git a/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/ExporterGameTest.java b/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/ExporterGameTest.java deleted file mode 100644 index b05f0b472..000000000 --- a/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/ExporterGameTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.refinedmods.refinedstorage2.platform.forge; - -import com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil; - -import net.minecraft.gametest.framework.GameTest; -import net.minecraft.gametest.framework.GameTestHelper; -import net.neoforged.neoforge.gametest.GameTestHolder; -import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; - -@GameTestHolder(IdentifierUtil.MOD_ID) -@PrefixGameTestTemplate(false) -public final class ExporterGameTest { - private ExporterGameTest() { - } - - @GameTest(template = "empty_15x15") - public static void shouldExport(final GameTestHelper test) { - System.out.println("Hello World"); - test.succeed(); - } -} diff --git a/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/TestMod.java b/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/TestMod.java new file mode 100644 index 000000000..2fdf4d06a --- /dev/null +++ b/refinedstorage2-platform-forge/src/test/java/com/refinedmods/refinedstorage2/platform/forge/TestMod.java @@ -0,0 +1,98 @@ +package com.refinedmods.refinedstorage2.platform.forge; + +import com.refinedmods.refinedstorage2.api.core.Action; +import com.refinedmods.refinedstorage2.api.network.Network; +import com.refinedmods.refinedstorage2.api.network.node.NetworkNode; +import com.refinedmods.refinedstorage2.api.network.storage.StorageNetworkComponent; +import com.refinedmods.refinedstorage2.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage2.api.storage.EmptyActor; +import com.refinedmods.refinedstorage2.platform.api.support.network.AbstractNetworkNodeContainerBlockEntity; +import com.refinedmods.refinedstorage2.platform.common.content.Blocks; +import com.refinedmods.refinedstorage2.platform.common.support.resource.ItemResource; +import com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil; + +import java.util.Arrays; +import javax.annotation.Nullable; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.GameTestAssertException; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.common.Mod; +import net.neoforged.testframework.conf.FrameworkConfiguration; +import net.neoforged.testframework.gametest.ExtendedGameTestHelper; + +@Mod(TestMod.ID) +public class TestMod { + public static final String ID = IdentifierUtil.MOD_ID + "_tests"; + + public static final ItemResource DIRT = ItemResource.ofItemStack(new ItemStack(Items.DIRT)); + public static final Blocks RSBLOCKS = Blocks.INSTANCE; + + public TestMod(final IEventBus eventBus) { + final var framework = FrameworkConfiguration.builder(new ResourceLocation(ID, "tests")) + .build() + .create(); + framework.init(eventBus, ModLoadingContext.get().getActiveContainer()); + } + + @Nullable + public static Network getNetwork(final ExtendedGameTestHelper helper, final BlockPos pos) { + try { + final var be = helper.requireBlockEntity(pos, AbstractNetworkNodeContainerBlockEntity.class); + final var field = AbstractNetworkNodeContainerBlockEntity.class.getDeclaredField("mainNode"); + field.setAccessible(true); + final NetworkNode mainNode = (NetworkNode) field.get(be); + return mainNode.getNetwork(); + } catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException e) { + throw new RuntimeException(e); + } + } + + public static Runnable itemIsInserted(final ExtendedGameTestHelper helper, + final BlockPos networkPos, + final ItemResource resource, + final long amount) { + return () -> { + final Network network = getNetwork(helper, networkPos); + helper.assertTrue(network != null && network.getComponent(StorageNetworkComponent.class) + .insert(resource, amount, Action.EXECUTE, EmptyActor.INSTANCE) == amount, + "Item couldn't be inserted" + ); + }; + } + + public static Runnable storageMustContainExactly(final ExtendedGameTestHelper helper, + final BlockPos networkPos, + final ResourceAmount... expected) { + return () -> { + final Network network = getNetwork(helper, networkPos); + helper.assertTrue(network != null, "Network is not found"); + if (network == null) { + return; + } + final StorageNetworkComponent storage = network.getComponent(StorageNetworkComponent.class); + for (final ResourceAmount expectedItem : expected) { + final boolean contains = storage.getAll() + .stream() + .anyMatch(inStorage -> inStorage.getResource().equals(expectedItem.getResource()) + && inStorage.getAmount() == expectedItem.getAmount()); + if (!contains) { + throw new GameTestAssertException("Missing from storage: " + expectedItem); + } + } + for (final ResourceAmount inStorage : storage.getAll()) { + final boolean wasExpected = Arrays.stream(expected).anyMatch( + expectedItem -> expectedItem.getResource().equals(inStorage.getResource()) + && expectedItem.getAmount() == inStorage.getAmount() + ); + if (!wasExpected) { + throw new GameTestAssertException("Unexpected in storage: " + inStorage); + } + } + }; + } +} diff --git a/refinedstorage2-platform-forge/src/test/resources/META-INF/mods.toml b/refinedstorage2-platform-forge/src/test/resources/META-INF/mods.toml new file mode 100644 index 000000000..a7c44f750 --- /dev/null +++ b/refinedstorage2-platform-forge/src/test/resources/META-INF/mods.toml @@ -0,0 +1,7 @@ +modLoader = "javafml" +loaderVersion = "[2,)" +license = "MIT" +[[mods]] +modId = "refinedstorage2" +[[mods]] +modId = "refinedstorage2_tests" \ No newline at end of file diff --git a/refinedstorage2-platform-forge/src/test/resources/data/refinedstorage2/structures/empty_15x15.nbt b/refinedstorage2-platform-forge/src/test/resources/data/refinedstorage2/structures/empty_15x15.nbt deleted file mode 100644 index bec099168..000000000 Binary files a/refinedstorage2-platform-forge/src/test/resources/data/refinedstorage2/structures/empty_15x15.nbt and /dev/null differ