Skip to content

Commit 6b9da80

Browse files
committed
Update Neo and use custom game test helpers instead of static methods in our tests
1 parent fca8280 commit 6b9da80

File tree

9 files changed

+302
-187
lines changed

9 files changed

+302
-187
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ plugins {
1818
id 'eclipse'
1919
id 'idea'
2020
id 'maven-publish'
21-
id 'net.neoforged.gradle.userdev' version '7.0.104'//https://projects.neoforged.net/neoforged/neogradle
21+
id 'net.neoforged.gradle.userdev' version '7.0.106'//https://projects.neoforged.net/neoforged/neogradle
2222
}
2323

2424
tasks.named('wrapper', Wrapper).configure {

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ minecraft_version=1.20.4
88
previous_minecraft_version=1.20.1
99
previous_minor_minecraft_version=1.20.2
1010
loader_version_range=[2,)
11-
forge_version=20.4.231
11+
forge_version=20.4.232
1212
mod_version=10.5.19
1313
#This determines the minimum version of forge required to use Mekanism
1414
# Only bump it whenever we need access to a feature in forge that is not available in earlier versions
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package mekanism.common.tests.helpers;
2+
3+
import mekanism.api.annotations.NothingNullByDefault;
4+
import mekanism.common.capabilities.Capabilities;
5+
import mekanism.common.util.WorldUtils;
6+
import net.minecraft.core.BlockPos;
7+
import net.minecraft.core.Direction;
8+
import net.minecraft.core.registries.BuiltInRegistries;
9+
import net.minecraft.gametest.framework.GameTestAssertException;
10+
import net.minecraft.gametest.framework.GameTestInfo;
11+
import net.minecraft.server.level.ChunkHolder;
12+
import net.minecraft.server.level.ChunkLevel;
13+
import net.minecraft.server.level.ChunkMap;
14+
import net.minecraft.server.level.DistanceManager;
15+
import net.minecraft.world.InteractionHand;
16+
import net.minecraft.world.InteractionResult;
17+
import net.minecraft.world.entity.player.Player;
18+
import net.minecraft.world.item.Item;
19+
import net.minecraft.world.item.ItemStack;
20+
import net.minecraft.world.item.context.UseOnContext;
21+
import net.minecraft.world.level.ChunkPos;
22+
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
23+
import net.minecraft.world.level.block.entity.BlockEntity;
24+
import net.minecraft.world.level.block.state.BlockState;
25+
import net.minecraft.world.phys.BlockHitResult;
26+
import net.neoforged.neoforge.items.IItemHandler;
27+
import net.neoforged.testframework.gametest.ExtendedGameTestHelper;
28+
29+
@NothingNullByDefault
30+
public class MekGameTestHelper extends ExtendedGameTestHelper {
31+
32+
public static final int INACCESSIBLE_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + 1;
33+
public static final int UNLOAD_LEVEL = ChunkLevel.MAX_LEVEL + 1;
34+
35+
public MekGameTestHelper(GameTestInfo info) {
36+
super(info);
37+
}
38+
39+
public ChunkMap getChunkMap() {
40+
return getLevel().getChunkSource().chunkMap;
41+
}
42+
43+
public int setChunkLoadLevel(ChunkPos relativePos, int newLevel) {
44+
long absPos = absolutePos(relativePos).toLong();
45+
DistanceManager distanceManager = getChunkMap().getDistanceManager();
46+
ChunkHolder holder = distanceManager.getChunk(absPos);
47+
int oldLevel = holder == null ? UNLOAD_LEVEL : holder.getTicketLevel();
48+
distanceManager.updateChunkScheduling(absPos, newLevel, holder, oldLevel);
49+
//Note: We purposely don't unload or load it if that changed as this method is meant for use when we don't know if
50+
// we are loading or unloading, and instead want to simulate the weird inaccessible but not unloaded state that
51+
// vanilla can get chunks into
52+
return oldLevel;
53+
}
54+
55+
public ChunkPos absolutePos(ChunkPos relativePos) {
56+
BlockPos relativeMiddle = relativePos.getMiddleBlockPosition(0);
57+
BlockPos absolutePos = absolutePos(relativeMiddle);
58+
return new ChunkPos(absolutePos);
59+
}
60+
61+
public BlockState getBlockState(int x, int y, int z) {
62+
return getBlockState(new BlockPos(x, y, z));
63+
}
64+
65+
public boolean isChunkLoaded(ChunkPos relativePos) {
66+
return WorldUtils.isChunkLoaded(getLevel(), absolutePos(relativePos));
67+
}
68+
69+
public boolean isBlockLoaded(BlockPos relativePos) {
70+
return WorldUtils.isBlockLoaded(getLevel(), absolutePos(relativePos));
71+
}
72+
73+
public void fail(String message, ChunkPos relativePos) {
74+
ChunkPos absolutePos = absolutePos(relativePos);
75+
fail(message + " at " + absolutePos.x + "," + absolutePos.z + " (relative: " + relativePos.x + "," + relativePos.z + ") (t=" + getTick() + ")");
76+
}
77+
78+
@Override
79+
public void assertContainerContains(BlockPos relativePos, Item item) {
80+
assertContainerContains(relativePos, item, 1);
81+
}
82+
83+
public void assertContainerContains(int x, int y, int z, Item item, int count) {
84+
assertContainerContains(new BlockPos(x, y, z), item, count);
85+
}
86+
87+
/**
88+
* This is similar and based off of vanilla's assertContainerContains, except supports checking for a specific amount, and checking blocks that expose item handlers.
89+
*/
90+
public void assertContainerContains(BlockPos relativePos, Item item, int count) {
91+
//TODO: Do we want to make a PR to Neo that adds this overload, even if it is as simple as only checking the count
92+
// and doesn't also add support for checking item handlers?
93+
BlockEntity blockentity = getBlockEntity(relativePos);
94+
boolean sameCount;
95+
if (blockentity instanceof BaseContainerBlockEntity containerBE) {
96+
sameCount = containerBE.countItem(item) == count;
97+
} else {
98+
IItemHandler handler = getCapability(Capabilities.ITEM.block(), relativePos, null);
99+
if (handler == null) {
100+
throw new GameTestAssertException("Expected a container or item handler at " + relativePos + ", found " + BuiltInRegistries.BLOCK_ENTITY_TYPE.getKey(blockentity.getType()));
101+
}
102+
int found = 0;
103+
for (int i = 0, slots = handler.getSlots(); i < slots; i++) {
104+
ItemStack stack = handler.getStackInSlot(i);
105+
if (stack.is(item)) {
106+
found += stack.getCount();
107+
}
108+
}
109+
sameCount = found == count;
110+
}
111+
if (!sameCount) {
112+
throw new GameTestAssertException("Container should contain: " + count + " " + item);
113+
}
114+
}
115+
116+
/**
117+
* Adds support for validating that item handlers are empty.
118+
*/
119+
@Override
120+
public void assertContainerEmpty(BlockPos relativePos) {
121+
BlockEntity blockentity = getBlockEntity(relativePos);
122+
if (blockentity instanceof BaseContainerBlockEntity containerBE) {
123+
if (!containerBE.isEmpty()) {
124+
throw new GameTestAssertException("Container should be empty");
125+
}
126+
} else {
127+
IItemHandler handler = getCapability(Capabilities.ITEM.block(), relativePos, null);
128+
if (handler != null) {
129+
for (int i = 0, slots = handler.getSlots(); i < slots; i++) {
130+
if (!handler.getStackInSlot(i).isEmpty()) {
131+
throw new GameTestAssertException("Container should be empty");
132+
}
133+
}
134+
}
135+
}
136+
}
137+
138+
public Player makeMockPlayerLookingAt(int x, int y, int z, Direction direction) {
139+
return makeMockPlayerLookingAt(new BlockPos(x, y, z), direction);
140+
}
141+
142+
public Player makeMockPlayerLookingAt(BlockPos relativePos, Direction direction) {
143+
Player player = makeMockPlayer();
144+
player.setXRot(direction == Direction.DOWN ? 90 : direction == Direction.UP ? -90 : 0);
145+
float yRot = direction.toYRot();
146+
player.setYRot(yRot);
147+
player.setYHeadRot(yRot);
148+
player.setPos(absolutePos(relativePos).getCenter().subtract(
149+
0.45 * direction.getStepX(),
150+
0.45 * direction.getStepY() + player.getEyeHeight(),
151+
0.45 * direction.getStepZ()
152+
));
153+
return player;
154+
}
155+
156+
/**
157+
* Adds support for providing a more accurate/useful Vec3 location in the hit result.
158+
*/
159+
@Override
160+
public void useOn(BlockPos relativePos, ItemStack item, Player player, Direction direction) {
161+
useOn(relativePos, item, player, direction, 1);
162+
}
163+
164+
public void useOn(BlockPos relativePos, ItemStack item, Player player, Direction direction, int times) {
165+
player.setItemInHand(InteractionHand.MAIN_HAND, item);
166+
BlockHitResult hit = createHitResult(relativePos, direction, false);
167+
UseOnContext context = new UseOnContext(getLevel(), player, InteractionHand.MAIN_HAND, item, hit);
168+
for (int i = 0; i < times; i++) {
169+
item.useOn(context);
170+
}
171+
}
172+
173+
/**
174+
* Adds support for providing a more accurate/useful Vec3 location in the hit result.
175+
*/
176+
@Override
177+
public void useBlock(BlockPos relativePos, Player player, ItemStack item, Direction direction) {
178+
player.setItemInHand(InteractionHand.MAIN_HAND, item);
179+
BlockHitResult hit = createHitResult(relativePos, direction, true);
180+
InteractionResult result = getBlockState(relativePos).use(getLevel(), player, InteractionHand.MAIN_HAND, hit);
181+
if (!result.consumesAction()) {
182+
item.useOn(new UseOnContext(getLevel(), player, InteractionHand.MAIN_HAND, item, hit));
183+
}
184+
}
185+
186+
//TODO: Do we want to PR the more accurate hit result location stuff to Neo?
187+
private BlockHitResult createHitResult(BlockPos relativePos, Direction direction, boolean inside) {
188+
BlockPos absolutePos = absolutePos(relativePos);
189+
return new BlockHitResult(absolutePos.getCenter().relative(direction, 0.5), direction, absolutePos, inside);
190+
}
191+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package mekanism.common.tests.helpers;
2+
3+
import mekanism.api.annotations.NothingNullByDefault;
4+
import mekanism.api.tier.AlloyTier;
5+
import mekanism.common.registries.MekanismItems;
6+
import net.minecraft.core.BlockPos;
7+
import net.minecraft.core.Direction;
8+
import net.minecraft.gametest.framework.GameTestInfo;
9+
import net.minecraft.world.entity.player.Player;
10+
11+
@NothingNullByDefault
12+
public class TransmitterTestHelper extends MekGameTestHelper {
13+
14+
public TransmitterTestHelper(GameTestInfo info) {
15+
super(info);
16+
}
17+
18+
public void useConfigurator(int x, int y, int z, Direction side) {
19+
useConfigurator(x, y, z, side, 1);
20+
}
21+
22+
public void useConfigurator(int x, int y, int z, Direction side, int times) {
23+
useConfigurator(x, y, z, side, times, true);
24+
}
25+
26+
public void useConfigurator(int x, int y, int z, Direction side, boolean shift) {
27+
useConfigurator(x, y, z, side, 1, shift);
28+
}
29+
30+
public void useConfigurator(int x, int y, int z, Direction side, int times, boolean shift) {
31+
Player player = makeMockPlayerLookingAt(x, y, z, side.getOpposite());
32+
player.setShiftKeyDown(shift);
33+
useOn(new BlockPos(x, y, z), MekanismItems.CONFIGURATOR.getItemStack(), player, side, times);
34+
}
35+
36+
public void applyAlloyUpgrade(BlockPos relativePos, AlloyTier tier) {
37+
//Note: We don't need to bother making the fake player look at the block as it isn't relevant for alloy upgrading
38+
useOn(relativePos, (switch (tier) {
39+
case INFUSED -> MekanismItems.INFUSED_ALLOY;
40+
case REINFORCED -> MekanismItems.REINFORCED_ALLOY;
41+
case ATOMIC -> MekanismItems.ATOMIC_ALLOY;
42+
}).getItemStack(), makeMockPlayer(), Direction.UP);
43+
}
44+
}

0 commit comments

Comments
 (0)