diff --git a/build.gradle b/build.gradle index 12e29b23..8d35f58b 100644 --- a/build.gradle +++ b/build.gradle @@ -263,6 +263,7 @@ test { events "passed", "skipped", "failed" } jvmArgs("-ea", "-Dmixin.debug.verbose=true", "-Dmixin.debug.export=true", "-Dmixin.checks.interfaces=true") + exclude "**/mixin*" } tasks.withType(ProcessResources).configureEach { diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinDefaultAttributesTest.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinDefaultAttributesTest.java new file mode 100644 index 00000000..0ce35651 --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinDefaultAttributesTest.java @@ -0,0 +1,23 @@ +package io.github.opencubicchunks.cubicchunks.mixin.test.common; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.DefaultAttributes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +// TODO: Remove this mixin class when NeoForge supports JUnit for tests +// This mixin class is only required due to NeoForge not supporting JUnit for testing yet (a workaround is currently used, involving Loom) +@Mixin(DefaultAttributes.class) +public abstract class MixinDefaultAttributesTest { + @Redirect(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/ai/attributes/DefaultAttributes;SUPPLIERS:Ljava/util/Map;", shift = At.Shift.BY, by = -1)) + private static ImmutableMap cubic_chunks_3$fixNeoForgeRegistryError(ImmutableMap.Builder instance) { + return ImmutableMap.builder().build(); + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;createLivingAttributes()Lnet/minecraft/world/entity/ai/attributes/AttributeSupplier$Builder;")) + private static AttributeSupplier.Builder cubic_chunks_3$fixNeoForgeRegistryError() { + return AttributeSupplier.builder(); + } +} diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinEntityTest.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinEntityTest.java new file mode 100644 index 00000000..10a73dd2 --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinEntityTest.java @@ -0,0 +1,26 @@ +package io.github.opencubicchunks.cubicchunks.mixin.test.common; + +import net.minecraft.core.Holder; +import net.minecraft.world.entity.Entity; +import net.neoforged.neoforge.fluids.FluidType; +import org.mockito.Mockito; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// TODO: Remove this mixin class when NeoForge supports JUnit for tests +// This mixin class is only required due to NeoForge not supporting JUnit for testing yet (a workaround is currently used, involving Loom) +@Mixin(Entity.class) +public abstract class MixinEntityTest { + @Redirect(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/Entity;forgeFluidTypeOnEyes:Lnet/neoforged/neoforge/fluids/FluidType;", shift = At.Shift.BY, by = -3)) + private Holder cubic_chunks_3$fixNeoForgeRegistryError() { + return Mockito.mock(); + } + + @Inject(method = "toString", at = @At(value = "HEAD"), cancellable = true) + private void cubic_chunks_3$fixNullPointerException(CallbackInfoReturnable cir) { + cir.setReturnValue("MockedEntity"); + } +} diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinLivingEntityTest.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinLivingEntityTest.java new file mode 100644 index 00000000..ffb0c290 --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinLivingEntityTest.java @@ -0,0 +1,25 @@ +package io.github.opencubicchunks.cubicchunks.mixin.test.common; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import org.mockito.Mockito; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// TODO: Remove this mixin class when NeoForge supports JUnit for tests +// This mixin class is only required due to NeoForge not supporting JUnit for testing yet (a workaround is currently used, involving Loom) +@Mixin(LivingEntity.class) +public abstract class MixinLivingEntityTest { + @Inject(method = "createLivingAttributes", at = @At(value = "HEAD"), cancellable = true) + private static void cubic_chunks_3$mockLivingAttributesInitialization(CallbackInfoReturnable cir) { + cir.setReturnValue(Mockito.mock()); + } + + @Inject(method = "getAttributeValue(Lnet/minecraft/world/entity/ai/attributes/Attribute;)D", at = @At(value = "HEAD"), cancellable = true) + private void cubic_chunks_3$fixNeoForgeErrors(Attribute pAttribute, CallbackInfoReturnable cir) { + cir.setReturnValue(1d); + } +} diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinMobTest.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinMobTest.java new file mode 100644 index 00000000..857ce6d6 --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinMobTest.java @@ -0,0 +1,18 @@ +package io.github.opencubicchunks.cubicchunks.mixin.test.common; + +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// TODO: Remove this mixin class when NeoForge supports JUnit for tests +// This mixin class is only required due to NeoForge not supporting JUnit for testing yet (a workaround is currently used, involving Loom) +@Mixin(Mob.class) +public abstract class MixinMobTest { + @Inject(method = "createMobAttributes", at = @At(value = "HEAD"), cancellable = true) + private static void cubic_chunks_3$fixNeoForgeErrors(CallbackInfoReturnable cir) { + cir.setReturnValue(AttributeSupplier.builder()); + } +} diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinPlayerTest.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinPlayerTest.java new file mode 100644 index 00000000..54806a0a --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/MixinPlayerTest.java @@ -0,0 +1,18 @@ +package io.github.opencubicchunks.cubicchunks.mixin.test.common; + +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.player.Player; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// TODO: Remove this mixin class when NeoForge supports JUnit for tests +// This mixin class is only required due to NeoForge not supporting JUnit for testing yet (a workaround is currently used, involving Loom) +@Mixin(Player.class) +public abstract class MixinPlayerTest { + @Inject(method = "createAttributes", at = @At(value = "HEAD"), cancellable = true) + private static void cubic_chunks_3$fixNeoForgeErrors(CallbackInfoReturnable cir) { + cir.setReturnValue(AttributeSupplier.builder()); + } +} diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/package-info.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/package-info.java new file mode 100644 index 00000000..e57d7ac7 --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package io.github.opencubicchunks.cubicchunks.mixin.test.common; + +import javax.annotation.ParametersAreNonnullByDefault; + +import io.github.opencubicchunks.cc_core.annotation.MethodsReturnNonnullByDefault; diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/server/level/package-info.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/server/level/package-info.java new file mode 100644 index 00000000..6a4f986a --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/server/level/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package io.github.opencubicchunks.cubicchunks.mixin.test.common.server.level; + +import javax.annotation.ParametersAreNonnullByDefault; + +import io.github.opencubicchunks.cc_core.annotation.MethodsReturnNonnullByDefault; diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/server/package-info.java b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/server/package-info.java new file mode 100644 index 00000000..51b30a2f --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/mixin/test/common/server/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package io.github.opencubicchunks.cubicchunks.mixin.test.common.server; + +import javax.annotation.ParametersAreNonnullByDefault; + +import io.github.opencubicchunks.cc_core.annotation.MethodsReturnNonnullByDefault; diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/test/server/level/TestServerPlayer.java b/src/test/java/io/github/opencubicchunks/cubicchunks/test/server/level/TestServerPlayer.java index 17607d41..855a8118 100644 --- a/src/test/java/io/github/opencubicchunks/cubicchunks/test/server/level/TestServerPlayer.java +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/test/server/level/TestServerPlayer.java @@ -2,17 +2,20 @@ import static io.github.opencubicchunks.cubicchunks.testutils.Misc.setupServerLevel; import static io.github.opencubicchunks.cubicchunks.testutils.Setup.setupTests; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import io.github.opencubicchunks.cubicchunks.testutils.CloseableReference; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.TicketType; +import net.minecraft.world.level.ChunkPos; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import org.mockito.Mockito; /** * This test class is for testing {@link io.github.opencubicchunks.cubicchunks.mixin.core.common.server.level.MixinServerPlayer} @@ -25,15 +28,25 @@ public static void setup() { } private ServerPlayer setupServerPlayer(ServerLevel serverLevel) { - return new ServerPlayer(mock(RETURNS_DEEP_STUBS), serverLevel, mock(RETURNS_DEEP_STUBS), mock(RETURNS_DEEP_STUBS)); + var serverPlayer = new ServerPlayer(mock(RETURNS_DEEP_STUBS), serverLevel, mock(RETURNS_DEEP_STUBS), mock(RETURNS_DEEP_STUBS)); + serverPlayer.connection = Mockito.mock(); + return serverPlayer; } - // TODO: Stub. This test needs a mixin from MixinEntityTest to ignore forgeFluidTypeOnEyes from NeoForge. - @Disabled @Test public void testTeleportToVanilla() throws Exception { + @Test public void testTeleportToVanilla() throws Exception { try (CloseableReference serverLevelReference = setupServerLevel()) { ServerPlayer player = setupServerPlayer(serverLevelReference.value()); - player.teleportTo(player.serverLevel(), 0, 0, 0, mock(), 0, 0); - assertTrue(player.serverLevel().getChunkSource().hasChunk(0, 0)); + + // teleportTo takes the destination level to teleport to as a param, so we mock it + ServerLevel serverLevelSpy = spy(serverLevelReference.value()); + ServerChunkCache serverChunkCacheMock = mock(ServerChunkCache.class); + Mockito.when(serverLevelSpy.getChunkSource()).thenReturn(serverChunkCacheMock); + + player.teleportTo(serverLevelSpy, 0, 0, 0, mock(), 0, 0); + + // Verify that serverChunkCacheMock.addRegionTicket(...) is called once + Mockito.verify(serverChunkCacheMock, Mockito.times(1)) + .addRegionTicket(TicketType.POST_TELEPORT, new ChunkPos(0, 0), 1, player.getId()); } } }