Skip to content

Commit

Permalink
Merge pull request #679 from starforcraft/feat/GH-248/detectortests
Browse files Browse the repository at this point in the history
Detector gametest
  • Loading branch information
raoulvdberge authored Sep 2, 2024
2 parents e689ccc + ae2412c commit f05e10a
Show file tree
Hide file tree
Showing 3 changed files with 281 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.refinedmods.refinedstorage.api.network.impl.node.detector.DetectorAmountStrategyImpl;
import com.refinedmods.refinedstorage.api.network.impl.node.detector.DetectorMode;
import com.refinedmods.refinedstorage.api.network.impl.node.detector.DetectorNetworkNode;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
import com.refinedmods.refinedstorage.common.Platform;
import com.refinedmods.refinedstorage.common.api.RefinedStorageApi;
import com.refinedmods.refinedstorage.common.api.support.network.InWorldNetworkNodeContainer;
Expand All @@ -22,7 +23,6 @@
import java.util.Optional;
import javax.annotation.Nullable;

import com.google.common.util.concurrent.RateLimiter;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
Expand All @@ -40,12 +40,13 @@
public class DetectorBlockEntity extends AbstractBaseNetworkNodeContainerBlockEntity<DetectorNetworkNode>
implements NetworkNodeExtendedMenuProvider<SingleAmountData> {
private static final Logger LOGGER = LoggerFactory.getLogger(DetectorBlockEntity.class);
private static final int POWERED_CHANGE_TICK_RATE = 20;

private static final String TAG_AMOUNT = "amount";
private static final String TAG_MODE = "mode";

private final FilterWithFuzzyMode filter;
private final RateLimiter poweredChangeRateLimiter = RateLimiter.create(1);
private int poweredChangeTicks;

private double amount;

Expand Down Expand Up @@ -109,6 +110,10 @@ private void propagateAmount() {
mainNetworkNode.setAmount(normalizedAmount);
}

void setConfiguredResource(final ResourceKey configuredResource) {
mainNetworkNode.setConfiguredResource(configuredResource);
}

boolean isFuzzyMode() {
return filter.isFuzzyMode();
}
Expand Down Expand Up @@ -165,8 +170,9 @@ public void updateActiveness(final BlockState state, @Nullable final BooleanProp
super.updateActiveness(state, activenessProperty);
final boolean powered = mainNetworkNode.isActive() && mainNetworkNode.isActivated();
final boolean needToUpdatePowered = state.getValue(DetectorBlock.POWERED) != powered;
if (level != null && needToUpdatePowered && poweredChangeRateLimiter.tryAcquire()) {
if (level != null && needToUpdatePowered && poweredChangeTicks++ % POWERED_CHANGE_TICK_RATE == 0) {
level.setBlockAndUpdate(getBlockPos(), state.setValue(DetectorBlock.POWERED, powered));
poweredChangeTicks = 0;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
package com.refinedmods.refinedstorage.common.detector;

import com.refinedmods.refinedstorage.api.network.impl.node.detector.DetectorMode;
import com.refinedmods.refinedstorage.api.resource.ResourceAmount;
import com.refinedmods.refinedstorage.common.util.IdentifierUtil;

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.minecraft.world.level.block.RedStoneWireBlock;
import net.neoforged.neoforge.gametest.GameTestHolder;
import net.neoforged.neoforge.gametest.PrefixGameTestTemplate;

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.detector.DetectorTestPlots.preparePlot;
import static net.minecraft.world.item.Items.DIAMOND_CHESTPLATE;
import static net.minecraft.world.item.Items.DIRT;
import static net.minecraft.world.item.Items.STONE;

@GameTestHolder(IdentifierUtil.MOD_ID)
@PrefixGameTestTemplate(false)
public final class DetectorTest {
private DetectorTest() {
}

@GameTest(template = "empty_15x15")
public static void shouldNotEmitRedstone(final GameTestHelper helper) {
preparePlot(helper, Direction.DOWN, (detector, pos, sequence) -> {
// Arrange
sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
}));

// Assert
sequence
.thenWaitUntil(storageContainsExactly(
helper,
pos
))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenSucceed();
});
}

@GameTest(template = "empty_15x15")
public static void shouldEmitRedstoneUnder(final GameTestHelper helper) {
preparePlot(helper, Direction.DOWN, (detector, pos, sequence) -> {
// Arrange
sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
insert(helper, network, DIRT, 10);
insert(helper, network, STONE, 15);
}));

// Act
detector.setConfiguredResource(asResource(DIRT));
detector.setMode(DetectorMode.UNDER);
detector.setAmount(5);

// Assert
sequence
.thenWaitUntil(storageContainsExactly(
helper,
pos,
new ResourceAmount(asResource(DIRT), 10),
new ResourceAmount(asResource(STONE), 15)
))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(4))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(5))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(6))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(10))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(15))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 15))
.thenSucceed();
});
}

@GameTest(template = "empty_15x15")
public static void shouldUseEqualModeByDefault(final GameTestHelper helper) {
preparePlot(helper, Direction.DOWN, (detector, pos, sequence) -> {
// Arrange
sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
insert(helper, network, DIRT, 10);
insert(helper, network, STONE, 15);
}));

// Act
final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500);
detector.setConfiguredResource(asResource(DIRT));
detector.setAmount(9);

// Assert
sequence
.thenWaitUntil(storageContainsExactly(
helper,
pos,
new ResourceAmount(asResource(DIRT), 10),
new ResourceAmount(asResource(STONE), 15)
))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(8))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(10))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 15))
.thenExecute(() -> {
detector.setConfiguredResource(asResource(damagedDiamondChestplate));
detector.setAmount(1);
})
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(networkIsAvailable(helper, pos, network ->
insert(helper, network, asResource(damagedDiamondChestplate), 1)))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 15))
.thenSucceed();
});
}

@GameTest(template = "empty_15x15")
public static void shouldEmitRedstoneEquals(final GameTestHelper helper) {
preparePlot(helper, Direction.DOWN, (detector, pos, sequence) -> {
// Arrange
sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
insert(helper, network, DIRT, 10);
insert(helper, network, STONE, 15);
}));

// Act
final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500);
detector.setConfiguredResource(asResource(DIRT));
detector.setMode(DetectorMode.EQUAL);
detector.setAmount(9);

// Assert
sequence
.thenWaitUntil(storageContainsExactly(
helper,
pos,
new ResourceAmount(asResource(DIRT), 10),
new ResourceAmount(asResource(STONE), 15)
))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(8))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(10))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 15))
.thenExecute(() -> {
detector.setConfiguredResource(asResource(damagedDiamondChestplate));
detector.setAmount(1);
})
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(networkIsAvailable(helper, pos, network ->
insert(helper, network, asResource(damagedDiamondChestplate), 1)))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 15))
.thenSucceed();
});
}

@GameTest(template = "empty_15x15")
public static void shouldEmitRedstoneAbove(final GameTestHelper helper) {
preparePlot(helper, Direction.DOWN, (detector, pos, sequence) -> {
// Arrange
sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
insert(helper, network, DIRT, 10);
insert(helper, network, STONE, 15);
}));

// Act
detector.setConfiguredResource(asResource(DIRT));
detector.setMode(DetectorMode.ABOVE);
detector.setAmount(15);

// Assert
sequence
.thenWaitUntil(storageContainsExactly(
helper,
pos,
new ResourceAmount(asResource(DIRT), 10),
new ResourceAmount(asResource(STONE), 15)
))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(16))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(14))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(10))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(5))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 15))
.thenSucceed();
});
}

@GameTest(template = "empty_15x15")
public static void shouldEmitRedstoneFuzzy(final GameTestHelper helper) {
preparePlot(helper, Direction.DOWN, (detector, pos, sequence) -> {
// Arrange
final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500);

sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
insert(helper, network, DIRT, 10);
insert(helper, network, asResource(DIAMOND_CHESTPLATE.getDefaultInstance()), 1);
insert(helper, network, asResource(damagedDiamondChestplate), 1);
}));

// Act
detector.setFuzzyMode(true);
detector.setConfiguredResource(asResource(DIAMOND_CHESTPLATE.getDefaultInstance()));
detector.setMode(DetectorMode.EQUAL);
detector.setAmount(1);

// Assert
sequence
.thenWaitUntil(storageContainsExactly(
helper,
pos,
new ResourceAmount(asResource(DIRT), 10),
new ResourceAmount(asResource(DIAMOND_CHESTPLATE.getDefaultInstance()), 1),
new ResourceAmount(asResource(damagedDiamondChestplate), 1)
))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 0))
.thenExecute(() -> detector.setAmount(2))
.thenWaitUntil(() -> helper.assertBlockProperty(pos.north(), RedStoneWireBlock.POWER, 15))
.thenSucceed();
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.refinedmods.refinedstorage.common.detector;

import com.refinedmods.refinedstorage.common.storage.FluidStorageVariant;
import com.refinedmods.refinedstorage.common.storage.ItemStorageVariant;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.gametest.framework.GameTestHelper;
import net.minecraft.gametest.framework.GameTestSequence;
import net.minecraft.world.level.block.Blocks;
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 DetectorTestPlots {
private DetectorTestPlots() {
}

static void preparePlot(final GameTestHelper helper,
final Direction direction,
final TriConsumer<DetectorBlockEntity, BlockPos, GameTestSequence> consumer) {
helper.setBlock(ZERO.above(), RSBLOCKS.getCreativeController().getDefault());
helper.setBlock(ZERO.above().above(), RSBLOCKS.getItemStorageBlock(ItemStorageVariant.ONE_K));
helper.setBlock(
ZERO.above().above().north(),
RSBLOCKS.getFluidStorageBlock(FluidStorageVariant.SIXTY_FOUR_B)
);
helper.setBlock(ZERO.above().above().above().north(), Blocks.REDSTONE_WIRE);
final BlockPos detectorPos = ZERO.above().above().above();
helper.setBlock(detectorPos, RSBLOCKS.getDetector().getDefault().rotated(direction));
consumer.accept(
requireBlockEntity(helper, detectorPos, DetectorBlockEntity.class),
detectorPos,
helper.startSequence()
);
}
}

0 comments on commit f05e10a

Please sign in to comment.