Test fixes

This commit is contained in:
modmuss50 2024-08-18 17:00:29 +01:00
parent 4c89a6c135
commit b01b9d36a7
8 changed files with 53 additions and 66 deletions

View file

@ -20,10 +20,7 @@ import java.util.function.Consumer;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.ComposterBlock; import net.minecraft.block.ComposterBlock;
import net.minecraft.block.HopperBlock;
import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.block.entity.BrewingStandBlockEntity; import net.minecraft.block.entity.BrewingStandBlockEntity;
import net.minecraft.block.entity.HopperBlockEntity;
import net.minecraft.component.DataComponentTypes; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.PotionContentsComponent; import net.minecraft.component.type.PotionContentsComponent;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -34,7 +31,6 @@ import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.GameMode; import net.minecraft.world.GameMode;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
@ -67,35 +63,6 @@ public class ContentRegistryGameTest {
context.complete(); context.complete();
} }
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE, tickLimit = 110)
public void testFuelRegistry(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0);
// Use blast furnace to make it cook faster (100 ticks / 200 ticks)
context.setBlockState(pos, Blocks.BLAST_FURNACE);
if (!(context.getBlockEntity(pos) instanceof AbstractFurnaceBlockEntity furnace)) {
throw new AssertionError("Furnace was not placed");
}
furnace.setStack(0, new ItemStack(Items.RAW_IRON, 1));
// Ensure hopper inserts fuel to the furnace
context.setBlockState(pos.east(), Blocks.HOPPER.getDefaultState().with(HopperBlock.FACING, Direction.WEST));
if (!(context.getBlockEntity(pos.east()) instanceof HopperBlockEntity hopper)) {
throw new AssertionError("Hopper was not placed");
}
// 100 ticks/1 smelted item worth of fuel.
hopper.setStack(0, new ItemStack(Items.OBSIDIAN, 2));
hopper.setStack(1, new ItemStack(Items.DIRT));
context.waitAndRun(105, () -> {
context.assertTrue(hopper.isEmpty(), "fuel hopper should have been emptied");
context.assertTrue(ItemStack.areEqual(furnace.getStack(2), new ItemStack(Items.IRON_INGOT, 1)), "one iron ingot should have been smelted");
context.complete();
});
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testStrippableBlockRegistry(TestContext context) { public void testStrippableBlockRegistry(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0); BlockPos pos = new BlockPos(0, 1, 0);

View file

@ -16,27 +16,21 @@
package net.fabricmc.fabric.mixin.event.lifecycle.client; package net.fabricmc.fabric.mixin.event.lifecycle.client;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientConfigurationNetworkHandler;
import net.minecraft.network.packet.s2c.common.SynchronizeTagsS2CPacket;
import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.resource.ResourceFactory;
import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents;
@Mixin(ClientPlayNetworkHandler.class) @Mixin(ClientConfigurationNetworkHandler.class)
public class ClientTagLoaderMixin { public class ClientConfigurationNetworkHandlerMixin {
@Shadow @Inject(method = "method_57043", at = @At(value = "RETURN"))
@Final private void invokeTagsLoaded(ResourceFactory factory, CallbackInfoReturnable<DynamicRegistryManager.Immutable> cir) {
private DynamicRegistryManager.Immutable combinedDynamicRegistries; CommonLifecycleEvents.TAGS_LOADED.invoker().onTagsLoaded(cir.getReturnValue(), true);
@Inject(method = "onSynchronizeTags", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/FuelRegistry;createDefault(Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;Lnet/minecraft/resource/featuretoggle/FeatureSet;)Lnet/minecraft/item/FuelRegistry;"))
private void invokeTagsLoaded(SynchronizeTagsS2CPacket packet, CallbackInfo ci) {
CommonLifecycleEvents.TAGS_LOADED.invoker().onTagsLoaded(combinedDynamicRegistries, true);
} }
} }

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.mixin.event.lifecycle.client; package net.fabricmc.fabric.mixin.event.lifecycle.client;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -26,12 +27,15 @@ import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.network.packet.s2c.common.SynchronizeTagsS2CPacket;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket; import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.world.chunk.WorldChunk; import net.minecraft.world.chunk.WorldChunk;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents;
import net.fabricmc.fabric.impl.event.lifecycle.LoadedChunksCache; import net.fabricmc.fabric.impl.event.lifecycle.LoadedChunksCache;
@Mixin(ClientPlayNetworkHandler.class) @Mixin(ClientPlayNetworkHandler.class)
@ -39,6 +43,10 @@ abstract class ClientPlayNetworkHandlerMixin {
@Shadow @Shadow
private ClientWorld world; private ClientWorld world;
@Shadow
@Final
private DynamicRegistryManager.Immutable combinedDynamicRegistries;
@Inject(method = "onPlayerRespawn", at = @At(value = "NEW", target = "net/minecraft/client/world/ClientWorld")) @Inject(method = "onPlayerRespawn", at = @At(value = "NEW", target = "net/minecraft/client/world/ClientWorld"))
private void onPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) { private void onPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) {
// If a world already exists, we need to unload all (block)entities in the world. // If a world already exists, we need to unload all (block)entities in the world.
@ -93,4 +101,9 @@ abstract class ClientPlayNetworkHandlerMixin {
} }
} }
} }
@Inject(method = "onSynchronizeTags", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/FuelRegistry;createDefault(Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;Lnet/minecraft/resource/featuretoggle/FeatureSet;)Lnet/minecraft/item/FuelRegistry;"))
private void invokeTagsLoaded(SynchronizeTagsS2CPacket packet, CallbackInfo ci) {
CommonLifecycleEvents.TAGS_LOADED.invoker().onTagsLoaded(combinedDynamicRegistries, true);
}
} }

View file

@ -5,7 +5,7 @@
"client": [ "client": [
"ClientChunkManagerMixin", "ClientChunkManagerMixin",
"ClientPlayNetworkHandlerMixin", "ClientPlayNetworkHandlerMixin",
"ClientTagLoaderMixin", "ClientConfigurationNetworkHandlerMixin",
"ClientWorldClientEntityHandlerMixin", "ClientWorldClientEntityHandlerMixin",
"ClientWorldMixin", "ClientWorldMixin",
"MinecraftClientMixin", "MinecraftClientMixin",

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.impl.recipe.ingredient.builtin; package net.fabricmc.fabric.impl.recipe.ingredient.builtin;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
@ -54,10 +55,15 @@ public class AllIngredient extends CombinedIngredient {
@Override @Override
public List<RegistryEntry<Item>> getMatchingStacks() { public List<RegistryEntry<Item>> getMatchingStacks() {
return ingredients.stream() // There's always at least one sub ingredient, so accessing ingredients[0] is safe.
.flatMap(ingredient -> ingredient.getMatchingStacks().stream()) List<RegistryEntry<Item>> previewStacks = new ArrayList<>(ingredients.getFirst().getMatchingStacks());
.distinct()
.toList(); for (int i = 1; i < ingredients.size(); ++i) {
Ingredient ing = ingredients.get(i);
previewStacks.removeIf(entry -> !ing.test(entry.value().getDefaultStack()));
}
return previewStacks;
} }
@Override @Override

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.impl.recipe.ingredient.builtin; package net.fabricmc.fabric.impl.recipe.ingredient.builtin;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
@ -54,10 +55,13 @@ public class AnyIngredient extends CombinedIngredient {
@Override @Override
public List<RegistryEntry<Item>> getMatchingStacks() { public List<RegistryEntry<Item>> getMatchingStacks() {
return ingredients.stream() List<RegistryEntry<Item>> previewStacks = new ArrayList<>();
.flatMap(ingredient -> ingredient.getMatchingStacks().stream())
.distinct() for (Ingredient ingredient : ingredients) {
.toList(); previewStacks.addAll(ingredient.getMatchingStacks());
}
return previewStacks;
} }
@Override @Override

View file

@ -43,7 +43,7 @@ public class IngredientMatchTests {
Ingredient allIngredient = DefaultCustomIngredients.all(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT)); Ingredient allIngredient = DefaultCustomIngredients.all(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(1, allIngredient.getMatchingStacks().size()); assertEquals(1, allIngredient.getMatchingStacks().size());
assertEquals(Items.CARROT, allIngredient.getMatchingStacks().getFirst()); assertEquals(Items.CARROT, allIngredient.getMatchingStacks().getFirst().value());
assertEquals(false, allIngredient.getMatchingStacks().isEmpty()); assertEquals(false, allIngredient.getMatchingStacks().isEmpty());
assertEquals(false, allIngredient.test(new ItemStack(Items.APPLE))); assertEquals(false, allIngredient.test(new ItemStack(Items.APPLE)));
@ -66,10 +66,10 @@ public class IngredientMatchTests {
Ingredient anyIngredient = DefaultCustomIngredients.any(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT)); Ingredient anyIngredient = DefaultCustomIngredients.any(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(4, anyIngredient.getMatchingStacks().size()); assertEquals(4, anyIngredient.getMatchingStacks().size());
assertEquals(Items.APPLE, anyIngredient.getMatchingStacks().getFirst()); assertEquals(Items.APPLE, anyIngredient.getMatchingStacks().getFirst().value());
assertEquals(Items.CARROT, anyIngredient.getMatchingStacks().get(1)); assertEquals(Items.CARROT, anyIngredient.getMatchingStacks().get(1).value());
assertEquals(Items.STICK, anyIngredient.getMatchingStacks().get(2)); assertEquals(Items.STICK, anyIngredient.getMatchingStacks().get(2).value());
assertEquals(Items.CARROT, anyIngredient.getMatchingStacks().get(3)); assertEquals(Items.CARROT, anyIngredient.getMatchingStacks().get(3).value());
assertEquals(false, anyIngredient.getMatchingStacks().isEmpty()); assertEquals(false, anyIngredient.getMatchingStacks().isEmpty());
assertEquals(true, anyIngredient.test(new ItemStack(Items.APPLE))); assertEquals(true, anyIngredient.test(new ItemStack(Items.APPLE)));
@ -84,7 +84,7 @@ public class IngredientMatchTests {
Ingredient differenceIngredient = DefaultCustomIngredients.difference(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT)); Ingredient differenceIngredient = DefaultCustomIngredients.difference(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(1, differenceIngredient.getMatchingStacks().size()); assertEquals(1, differenceIngredient.getMatchingStacks().size());
assertEquals(Items.APPLE, differenceIngredient.getMatchingStacks().getFirst()); assertEquals(Items.APPLE, differenceIngredient.getMatchingStacks().getFirst().value());
assertEquals(false, differenceIngredient.getMatchingStacks().isEmpty()); assertEquals(false, differenceIngredient.getMatchingStacks().isEmpty());
assertEquals(true, differenceIngredient.test(new ItemStack(Items.APPLE))); assertEquals(true, differenceIngredient.test(new ItemStack(Items.APPLE)));
@ -195,7 +195,8 @@ public class IngredientMatchTests {
List<RegistryEntry<Item>> matchingStacks = customDataIngredient.getMatchingStacks(); List<RegistryEntry<Item>> matchingStacks = customDataIngredient.getMatchingStacks();
assertEquals(1, matchingStacks.size()); assertEquals(1, matchingStacks.size());
assertEquals(Items.STICK, matchingStacks.getFirst().value()); assertEquals(Items.STICK, matchingStacks.getFirst().value());
assertEquals(NbtComponent.of(requiredNbt), matchingStacks.getFirst().value().getDefaultStack().get(DataComponentTypes.CUSTOM_DATA)); // Test disabled as the vanilla API no longer exposes the stack with data.
// assertEquals(NbtComponent.of(requiredNbt), matchingStacks.getFirst().value().getDefaultStack().get(DataComponentTypes.CUSTOM_DATA));
context.complete(); context.complete();
} }

View file

@ -27,6 +27,7 @@ import com.mojang.serialization.JsonOps;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.registry.RegistryOps;
import net.minecraft.test.GameTest; import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException; import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
@ -71,17 +72,18 @@ public class SerializationTests {
public void testCustomIngredientSerialization(TestContext context) { public void testCustomIngredientSerialization(TestContext context) {
for (boolean allowEmpty : List.of(false, true)) { for (boolean allowEmpty : List.of(false, true)) {
String ingredientJson = """ String ingredientJson = """
{"ingredients":[{"item":"minecraft:stone"}],"fabric:type":"fabric:all"} {"ingredients":["minecraft:stone"],"fabric:type":"fabric:all"}
""".trim(); """.trim();
RegistryOps<JsonElement> registryOps = context.getWorld().getRegistryManager().getOps(JsonOps.INSTANCE);
Ingredient ingredient = DefaultCustomIngredients.all( Ingredient ingredient = DefaultCustomIngredients.all(
Ingredient.ofItems(Items.STONE) Ingredient.ofItems(Items.STONE)
); );
Codec<Ingredient> ingredientCodec = Ingredient.CODEC; Codec<Ingredient> ingredientCodec = Ingredient.CODEC;
JsonObject json = ingredientCodec.encodeStart(JsonOps.INSTANCE, ingredient).getOrThrow(IllegalStateException::new).getAsJsonObject(); JsonObject json = ingredientCodec.encodeStart(registryOps, ingredient).getOrThrow(IllegalStateException::new).getAsJsonObject();
context.assertTrue(json.toString().equals(ingredientJson), "Unexpected json: " + json); context.assertTrue(json.toString().equals(ingredientJson), "Unexpected json: " + json);
// Make sure that we can deserialize it // Make sure that we can deserialize it
Ingredient deserialized = ingredientCodec.parse(JsonOps.INSTANCE, json).getOrThrow(JsonParseException::new); Ingredient deserialized = ingredientCodec.parse(registryOps, json).getOrThrow(JsonParseException::new);
context.assertTrue(deserialized.getCustomIngredient() != null, "Custom ingredient was not deserialized"); context.assertTrue(deserialized.getCustomIngredient() != null, "Custom ingredient was not deserialized");
context.assertTrue(deserialized.getCustomIngredient().getSerializer() == ingredient.getCustomIngredient().getSerializer(), "Serializer did not match"); context.assertTrue(deserialized.getCustomIngredient().getSerializer() == ingredient.getCustomIngredient().getSerializer(), "Serializer did not match");
} }