Skip to content

Commit 19b8f30

Browse files
committed
More work doing unit tests
1 parent 1277033 commit 19b8f30

17 files changed

+324
-60
lines changed

src/main/java/dev/compactmods/crafting/field/MiniaturizationField.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public AxisAlignedBB getBounds() {
136136
}
137137

138138
public Stream<BlockPos> getFilledBlocks() {
139-
return BlockSpaceUtil.getLayerBlockPositions(getBounds())
139+
return BlockSpaceUtil.getBlocksIn(getBounds())
140140
.filter(p -> !level.isEmptyBlock(p))
141141
.map(BlockPos::immutable);
142142
}

src/main/java/dev/compactmods/crafting/recipes/MiniaturizationRecipe.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,6 @@
55
import com.google.common.collect.ImmutableList;
66
import dev.compactmods.crafting.CompactCrafting;
77
import dev.compactmods.crafting.Registration;
8-
import dev.compactmods.crafting.field.MiniaturizationField;
9-
import dev.compactmods.crafting.recipes.components.CCMiniRecipeComponents;
10-
import dev.compactmods.crafting.recipes.components.EmptyBlockComponent;
11-
import dev.compactmods.crafting.recipes.exceptions.MiniaturizationRecipeException;
12-
import dev.compactmods.crafting.recipes.blocks.RecipeLayerBlocks;
13-
import dev.compactmods.crafting.recipes.layers.RecipeLayerUtil;
14-
import dev.compactmods.crafting.recipes.setup.RecipeBase;
15-
import dev.compactmods.crafting.server.ServerConfig;
16-
import dev.compactmods.crafting.util.BlockSpaceUtil;
178
import dev.compactmods.crafting.api.components.IRecipeBlockComponent;
189
import dev.compactmods.crafting.api.components.IRecipeComponent;
1910
import dev.compactmods.crafting.api.components.IRecipeComponents;
@@ -23,6 +14,15 @@
2314
import dev.compactmods.crafting.api.recipe.layers.IRecipeLayerBlocks;
2415
import dev.compactmods.crafting.api.recipe.layers.dim.IDynamicSizedRecipeLayer;
2516
import dev.compactmods.crafting.api.recipe.layers.dim.IFixedSizedRecipeLayer;
17+
import dev.compactmods.crafting.field.MiniaturizationField;
18+
import dev.compactmods.crafting.recipes.blocks.RecipeLayerBlocks;
19+
import dev.compactmods.crafting.recipes.components.CCMiniRecipeComponents;
20+
import dev.compactmods.crafting.recipes.components.EmptyBlockComponent;
21+
import dev.compactmods.crafting.recipes.exceptions.MiniaturizationRecipeException;
22+
import dev.compactmods.crafting.recipes.layers.RecipeLayerUtil;
23+
import dev.compactmods.crafting.recipes.setup.RecipeBase;
24+
import dev.compactmods.crafting.server.ServerConfig;
25+
import dev.compactmods.crafting.util.BlockSpaceUtil;
2626
import net.minecraft.block.BlockState;
2727
import net.minecraft.item.ItemStack;
2828
import net.minecraft.item.crafting.IRecipeSerializer;
@@ -32,7 +32,7 @@
3232
import net.minecraft.util.math.AxisAlignedBB;
3333
import net.minecraft.util.math.BlockPos;
3434
import net.minecraft.util.math.vector.Vector3d;
35-
import net.minecraft.world.IWorldReader;
35+
import net.minecraft.world.IBlockReader;
3636

3737
public class MiniaturizationRecipe extends RecipeBase implements IMiniaturizationRecipe {
3838

@@ -186,7 +186,7 @@ public boolean fitsInFieldSize(FieldProjectionSize fieldSize) {
186186
return fits;
187187
}
188188

189-
public boolean matches(IWorldReader world, MiniaturizationField field) {
189+
public boolean matches(IBlockReader world, MiniaturizationField field) {
190190
if (!fitsInFieldSize(field.getFieldSize())) {
191191
if (ServerConfig.RECIPE_MATCHING.get())
192192
CompactCrafting.LOGGER.debug("Failing recipe {} for being too large to fit in field.", this.id);
@@ -214,7 +214,7 @@ public boolean matches(IWorldReader world, MiniaturizationField field) {
214214
return false;
215215
}
216216

217-
private boolean checkRotation(IWorldReader world, Rotation rot, AxisAlignedBB filledBounds) {
217+
private boolean checkRotation(IBlockReader world, Rotation rot, AxisAlignedBB filledBounds) {
218218
// Check the recipe layer by layer
219219

220220
int maxY = (int) dimensions.getYsize();

src/main/java/dev/compactmods/crafting/recipes/MiniaturizationRecipeCodec.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ public class MiniaturizationRecipeCodec implements Codec<MiniaturizationRecipe>
2828
public static final Codec<IRecipeComponent> COMPONENT_CODEC =
2929
RecipeComponentTypeCodec.INSTANCE.dispatchStable(IRecipeComponent::getType, RecipeComponentType::getCodec);
3030

31-
MiniaturizationRecipeCodec() {}
31+
MiniaturizationRecipeCodec() {
32+
}
3233

3334
@Override
3435
public <T> DataResult<Pair<MiniaturizationRecipe, T>> decode(DynamicOps<T> ops, T input) {
3536
boolean debugOutput = ServerConfig.RECIPE_REGISTRATION.get();
36-
if(debugOutput) {
37+
if (debugOutput) {
3738
CompactCrafting.RECIPE_LOGGER.debug("Starting recipe decode: {}", input.toString());
3839
}
3940

@@ -64,8 +65,7 @@ public <T> DataResult<Pair<MiniaturizationRecipe, T>> decode(DynamicOps<T> ops,
6465
.get();
6566

6667
boolean hasFixedLayers = layers.stream().anyMatch(l -> l instanceof IFixedSizedRecipeLayer);
67-
if(debugOutput)
68-
{
68+
if (debugOutput) {
6969
CompactCrafting.RECIPE_LOGGER.debug("Number of layers defined: {}", layers.size());
7070
CompactCrafting.RECIPE_LOGGER.debug("Is fixed size: {}", hasFixedLayers);
7171
}
@@ -81,30 +81,36 @@ public <T> DataResult<Pair<MiniaturizationRecipe, T>> decode(DynamicOps<T> ops,
8181
MiniaturizationRecipe recipe = new MiniaturizationRecipe(recipeSize, layers, catalyst, outputs, components);
8282
recipe.recalculateDimensions();
8383

84-
if(debugOutput)
84+
if (debugOutput)
8585
CompactCrafting.RECIPE_LOGGER.debug("Finishing recipe decode.");
8686

8787
return DataResult.success(Pair.of(recipe, input));
8888
}
8989

9090
@Override
91-
public <T> DataResult<T> encode(MiniaturizationRecipe input, DynamicOps<T> ops, T prefix) {
91+
public <T> DataResult<T> encode(MiniaturizationRecipe recipe, DynamicOps<T> ops, T prefix) {
92+
93+
if (recipe == null) {
94+
return DataResult.error("Cannot serialize a null recipe.");
95+
}
9296

93-
DataResult<T> layers = LAYER_CODEC.listOf().encodeStart(ops, input.getLayerListForCodecWrite());
97+
DataResult<T> layers = LAYER_CODEC.listOf().encodeStart(ops, recipe.getLayerListForCodecWrite());
9498

9599
DataResult<T> components = Codec.unboundedMap(Codec.STRING, COMPONENT_CODEC)
96-
.encodeStart(ops, input.getComponents().getAllComponents());
100+
.encodeStart(ops, recipe.getComponents().getAllComponents());
101+
102+
ItemStack catalystItem = recipe.getCatalyst();
103+
DataResult<T> catalyst = ItemStack.CODEC.encodeStart(ops, catalystItem == null ? ItemStack.EMPTY : catalystItem);
97104

98-
DataResult<T> catalyst = ItemStack.CODEC.encodeStart(ops, input.getCatalyst());
99105
DataResult<T> outputs = ItemStack.CODEC.listOf()
100-
.encodeStart(ops, ImmutableList.copyOf(input.getOutputs()));
106+
.encodeStart(ops, ImmutableList.copyOf(recipe.getOutputs()));
101107

102108
RecordBuilder<T> builder = ops.mapBuilder();
103109

104110
builder.add("type", Codec.STRING.encodeStart(ops, "compactcrafting:miniaturization"));
105111

106-
if(input.hasSpecifiedSize())
107-
builder.add("recipeSize", Codec.INT.encodeStart(ops, input.getSize()));
112+
if (recipe.hasSpecifiedSize())
113+
builder.add("recipeSize", Codec.INT.encodeStart(ops, recipe.getSize()));
108114

109115
return builder.add("layers", layers)
110116
.add("components", components)

src/main/java/dev/compactmods/crafting/recipes/MiniaturizationRecipeSerializer.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,16 @@ public MiniaturizationRecipe fromNetwork(ResourceLocation recipeId, PacketBuffer
5757
@Override
5858
public void toNetwork(PacketBuffer buffer, MiniaturizationRecipe recipe) {
5959
boolean debugReg = ServerConfig.RECIPE_REGISTRATION.get();
60-
if(debugReg) CompactCrafting.LOGGER.debug("Sending recipe over network: {}", recipe.getRecipeIdentifier());
60+
if(debugReg && recipe != null)
61+
CompactCrafting.LOGGER.debug("Sending recipe over network: {}", recipe.getRecipeIdentifier());
6162

6263
try {
6364
buffer.writeWithCodec(MiniaturizationRecipe.CODEC, recipe);
64-
} catch (NullPointerException | IOException npe) {
65-
CompactCrafting.LOGGER.error(String.format("Whoops: %s", recipe.getRecipeIdentifier()), npe);
65+
} catch (IOException ioe) {
66+
if(recipe != null)
67+
CompactCrafting.LOGGER.error(String.format("Failed to encode recipe for network: %s", recipe.getRecipeIdentifier()), ioe);
68+
else
69+
CompactCrafting.LOGGER.error("Failed to encode recipe for network.", ioe);
6670
}
6771
}
6872
}

src/main/java/dev/compactmods/crafting/recipes/blocks/ComponentPositionLookupCodec.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ public <T> T write(DynamicOps<T> ops, ComponentPositionLookup value) {
5959
DataResult<T> encoded = Codec.STRING.listOf().listOf().encode(fin, ops, ops.empty());
6060

6161
return encoded
62-
.resultOrPartial(err -> CompactCrafting.LOGGER.error(
63-
String.format("Failed to encode layer component position lookup: %s", err)
64-
))
62+
.resultOrPartial(err -> CompactCrafting.LOGGER.error("Failed to encode layer component position lookup: {}", err))
6563
.get();
6664
}
6765
}

src/main/java/dev/compactmods/crafting/recipes/blocks/RecipeLayerBlocks.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import net.minecraft.block.BlockState;
99
import net.minecraft.util.math.AxisAlignedBB;
1010
import net.minecraft.util.math.BlockPos;
11-
import net.minecraft.world.IWorldReader;
11+
import net.minecraft.world.IBlockReader;
1212

1313
public class RecipeLayerBlocks implements IRecipeLayerBlocks {
1414

@@ -47,14 +47,11 @@ public RecipeLayerBlocks(AxisAlignedBB bounds, Map<BlockPos, BlockState> states,
4747
this.lookup.rebuildComponentTotals();
4848
}
4949

50-
public static RecipeLayerBlocks create(IWorldReader world, MiniaturizationRecipe recipe, AxisAlignedBB bounds) {
50+
public static RecipeLayerBlocks create(IBlockReader blocks, MiniaturizationRecipe recipe, AxisAlignedBB bounds) {
5151
RecipeLayerBlocks instance = new RecipeLayerBlocks(bounds);
5252

53-
BlockPos.betweenClosedStream(bounds).forEach(pos -> {
54-
if (!bounds.contains(pos.getX(), pos.getY(), pos.getZ()))
55-
return;
56-
57-
BlockState state = world.getBlockState(pos);
53+
BlockSpaceUtil.getBlocksIn(bounds).forEach(pos -> {
54+
BlockState state = blocks.getBlockState(pos);
5855

5956
BlockPos normalizedPos = BlockSpaceUtil.normalizeLayerPosition(bounds, pos);
6057

src/main/java/dev/compactmods/crafting/recipes/layers/FilledComponentRecipeLayer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public Optional<String> getComponentForPosition(BlockPos pos) {
5353

5454
@Override
5555
public Stream<BlockPos> getPositionsForComponent(String component) {
56-
return BlockSpaceUtil.getLayerBlockPositions(recipeDimensions);
56+
return BlockSpaceUtil.getBlocksIn(recipeDimensions);
5757
}
5858

5959
public int getNumberFilledPositions() {

src/main/java/dev/compactmods/crafting/util/BlockSpaceUtil.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public static boolean boundsFitsInside(AxisAlignedBB inner, AxisAlignedBB outer)
6161
}
6262

6363
@Nonnull
64-
public static Stream<BlockPos> getLayerBlockPositions(AxisAlignedBB bounds) {
64+
public static Stream<BlockPos> getBlocksIn(AxisAlignedBB bounds) {
6565
return BlockPos.betweenClosedStream(bounds.contract(1, 1, 1));
6666
}
6767

@@ -137,11 +137,11 @@ public static Stream<BlockPos> getWallPositions(AxisAlignedBB bounds) {
137137
AxisAlignedBB layerBounds = new AxisAlignedBB(0, 0, 0, bounds.getXsize() - 1, 0, bounds.getZsize() - 1);
138138
AxisAlignedBB insideBounds = layerBounds.move(1, 0, 1).contract(2, 0, 2);
139139

140-
Set<BlockPos> positions = BlockSpaceUtil.getLayerBlockPositions(layerBounds)
140+
Set<BlockPos> positions = BlockSpaceUtil.getBlocksIn(layerBounds)
141141
.map(BlockPos::immutable)
142142
.collect(Collectors.toSet());
143143

144-
Set<BlockPos> inside = BlockSpaceUtil.getLayerBlockPositions(insideBounds)
144+
Set<BlockPos> inside = BlockSpaceUtil.getBlocksIn(insideBounds)
145145
.map(BlockPos::immutable)
146146
.collect(Collectors.toSet());
147147

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package dev.compactmods.crafting.tests.recipes;
2+
3+
import dev.compactmods.crafting.CompactCrafting;
4+
import dev.compactmods.crafting.recipes.MiniaturizationRecipe;
5+
import dev.compactmods.crafting.recipes.setup.FakeInventory;
6+
import dev.compactmods.crafting.server.ServerConfig;
7+
import net.minecraft.item.ItemStack;
8+
import net.minecraft.server.MinecraftServer;
9+
import net.minecraft.util.ResourceLocation;
10+
import net.minecraft.world.server.ServerWorld;
11+
import net.minecraftforge.fml.server.ServerLifecycleHooks;
12+
import org.junit.jupiter.api.Assertions;
13+
import org.junit.jupiter.api.Tag;
14+
import org.junit.jupiter.api.Test;
15+
16+
public class MiniaturiationRecipeTests {
17+
18+
private static MinecraftServer SERVER;
19+
private static ServerWorld OVERWORLD;
20+
21+
@Tag("minecraft")
22+
@org.junit.jupiter.api.BeforeAll
23+
static void BeforeAllTests() {
24+
ServerConfig.RECIPE_REGISTRATION.set(true);
25+
ServerConfig.RECIPE_MATCHING.set(true);
26+
ServerConfig.FIELD_BLOCK_CHANGES.set(true);
27+
28+
SERVER = ServerLifecycleHooks.getCurrentServer();
29+
OVERWORLD = SERVER.overworld();
30+
}
31+
32+
@Test
33+
@Tag("minecraft")
34+
void CanCreate() {
35+
MiniaturizationRecipe recipe = new MiniaturizationRecipe();
36+
Assertions.assertNotNull(recipe);
37+
}
38+
39+
@Test
40+
@Tag("minecraft")
41+
void CanSetId() {
42+
MiniaturizationRecipe recipe = new MiniaturizationRecipe();
43+
Assertions.assertNotNull(recipe);
44+
45+
Assertions.assertDoesNotThrow(() -> {
46+
recipe.setId(new ResourceLocation(CompactCrafting.MOD_ID, "test"));
47+
});
48+
}
49+
50+
51+
@Test
52+
@Tag("minecraft")
53+
void IsSpecialRecipe() {
54+
MiniaturizationRecipe recipe = new MiniaturizationRecipe();
55+
Assertions.assertNotNull(recipe);
56+
Assertions.assertTrue(recipe.isSpecial());
57+
}
58+
59+
@Test
60+
@Tag("minecraft")
61+
void FakesFakeInventories() {
62+
MiniaturizationRecipe recipe = new MiniaturizationRecipe();
63+
Assertions.assertNotNull(recipe);
64+
65+
Assertions.assertDoesNotThrow(() -> {
66+
boolean matched = recipe.matches(new FakeInventory(), OVERWORLD);
67+
Assertions.assertTrue(matched);
68+
});
69+
}
70+
71+
@Test
72+
@Tag("minecraft")
73+
void FakesAssemble() {
74+
MiniaturizationRecipe recipe = new MiniaturizationRecipe();
75+
Assertions.assertNotNull(recipe);
76+
77+
Assertions.assertDoesNotThrow(() -> {
78+
ItemStack result = recipe.assemble(new FakeInventory());
79+
Assertions.assertTrue(result.isEmpty());
80+
});
81+
}
82+
83+
@Test
84+
@Tag("minecraft")
85+
void FakesCanCraftDimensions() {
86+
MiniaturizationRecipe recipe = new MiniaturizationRecipe();
87+
Assertions.assertNotNull(recipe);
88+
89+
Assertions.assertDoesNotThrow(() -> {
90+
boolean canCraft = recipe.canCraftInDimensions(0, 0);
91+
Assertions.assertTrue(canCraft);
92+
});
93+
}
94+
95+
@Test
96+
@Tag("minecraft")
97+
void FakesResultItem() {
98+
MiniaturizationRecipe recipe = new MiniaturizationRecipe();
99+
Assertions.assertNotNull(recipe);
100+
101+
Assertions.assertDoesNotThrow(() -> {
102+
final ItemStack result = recipe.getResultItem();
103+
Assertions.assertTrue(result.isEmpty());
104+
});
105+
}
106+
}

src/test/java/dev/compactmods/crafting/tests/recipes/components/ComponentPositionLookupTests.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.compactmods.crafting.tests.recipes.components;
22

3+
import java.util.Map;
34
import java.util.Optional;
45
import java.util.Set;
56
import java.util.stream.Collectors;
@@ -61,4 +62,22 @@ void NullStringLookupReturnsEmpty() {
6162

6263
Assertions.assertEquals(0, positionsForComponent.count());
6364
}
65+
66+
@Test
67+
void CanCreateAndCacheTotals() {
68+
ComponentPositionLookup lookup = new ComponentPositionLookup();
69+
lookup.add(BlockPos.ZERO, "C");
70+
71+
// First pass - should calculate successfully
72+
final Map<String, Integer> totals = Assertions.assertDoesNotThrow(lookup::getComponentTotals);
73+
Assertions.assertTrue(totals.containsKey("C"));
74+
Assertions.assertEquals(1, totals.get("C"));
75+
76+
// Second pass - should return the already built totals object
77+
final Map<String, Integer> secondPass = Assertions.assertDoesNotThrow(lookup::getComponentTotals);
78+
Assertions.assertSame(totals, secondPass);
79+
Assertions.assertTrue(secondPass.containsKey("C"));
80+
Assertions.assertEquals(1, secondPass.get("C"));
81+
}
82+
6483
}

0 commit comments

Comments
 (0)