diff --git a/build.gradle.kts b/build.gradle.kts index e242ffbf..d40b00a9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,13 +5,16 @@ plugins { helper.withApiSourceSet() helper.withDataGenSourceSet() +helper.withTestSourceSet() dependencies { implementation(helper.neoforge()) + testImplementation("net.neoforged:testframework:${helper.neoVersion.get()}") } helper.withCommonRuns() helper.withDataGenRuns() +helper.withGameTestRuns() helper.publication.pom { organization { diff --git a/gradle.properties b/gradle.properties index c77ed1f4..eced5388 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,6 +2,7 @@ org.gradle.jvmargs=-Xmx4G org.gradle.daemon=false org.gradle.parallel=true org.gradle.caching=true +org.gradle.configuration-cache=true mod.group=com.github.minecraftschurlimods mod.id=bibliocraft @@ -28,7 +29,7 @@ neogradle.subsystems.parchment.mappingsVersion=2024.02.25 mc_version=1.20.4 mc_version_range=[1.20.4,1.20.5) -neo_version=20.4.167 +neo_version=20.4.198 neo_version_range=[20.4.80-beta,20.5) loader.version=[1,) diff --git a/settings.gradle.kts b/settings.gradle.kts index 257379ed..f581428e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { - id("net.neoforged.gradle.userdev") version "7.0.80" - id("com.github.minecraftschurlimods.helperplugin") version "1.9" + id("net.neoforged.gradle.userdev") version "7.0.+" + id("com.github.minecraftschurlimods.helperplugin") version "1.10" } repositories { mavenLocal() diff --git a/src/api/java/com/github/minecraftschurlimods/bibliocraft/api/RegisterBibliocraftWoodTypesEvent.java b/src/api/java/com/github/minecraftschurlimods/bibliocraft/api/RegisterBibliocraftWoodTypesEvent.java index e7fc6ff3..d32145d3 100644 --- a/src/api/java/com/github/minecraftschurlimods/bibliocraft/api/RegisterBibliocraftWoodTypesEvent.java +++ b/src/api/java/com/github/minecraftschurlimods/bibliocraft/api/RegisterBibliocraftWoodTypesEvent.java @@ -35,7 +35,6 @@ public void register(WoodType woodType, Supplier prop public void register(ResourceLocation id, WoodType woodType, Supplier properties, ResourceLocation texture, BlockFamily family) { if (this.woodTypes.containsKey(id)) throw new IllegalStateException("Wood type " + id + " is already registered"); - System.out.println("Registering wood type " + woodType.name()); this.woodTypes.put(id, new BibliocraftWoodType(id, woodType, properties, texture, family)); } } diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/EventHandler.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/EventHandler.java index b62f4871..dd24c764 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/EventHandler.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/EventHandler.java @@ -37,7 +37,6 @@ private static void entityAttributeCreation(EntityAttributeCreationEvent event) @SubscribeEvent private static void registerBibliocraftWoodTypes(RegisterBibliocraftWoodTypesEvent event) { - System.out.println("registering vanilla bibliocraft wood types"); registerVanilla(event, WoodType.OAK, Blocks.OAK_PLANKS, BlockFamilies.OAK_PLANKS); registerVanilla(event, WoodType.SPRUCE, Blocks.SPRUCE_PLANKS, BlockFamilies.SPRUCE_PLANKS); registerVanilla(event, WoodType.BIRCH, Blocks.BIRCH_PLANKS, BlockFamilies.BIRCH_PLANKS); diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/apiimpl/BibliocraftWoodTypeRegistryImpl.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/apiimpl/BibliocraftWoodTypeRegistryImpl.java index 1a17cb5c..3efb5d9f 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/apiimpl/BibliocraftWoodTypeRegistryImpl.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/apiimpl/BibliocraftWoodTypeRegistryImpl.java @@ -23,7 +23,6 @@ public BibliocraftWoodTypeRegistryImpl() { @ApiStatus.Internal public void register() { - System.out.println("Posting Bibliocraft Wood Types registry event"); ModLoader.get().postEvent(new RegisterBibliocraftWoodTypesEvent(this.values)); this.loaded = true; } diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/content/seat/SeatEntity.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/content/seat/SeatEntity.java index 77adf768..e3c2293b 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/content/seat/SeatEntity.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/content/seat/SeatEntity.java @@ -23,15 +23,14 @@ protected void defineSynchedData() { @Override public void tick() { - super.tick(); BlockPos pos = blockPosition(); BlockState state = level().getBlockState(pos); if (level().isClientSide()) return; if (!(state.getBlock() instanceof SeatBlock)) { getPassengers().forEach(Entity::stopRiding); - removeAfterChangingDimensions(); + discard(); } else if (getPassengers().isEmpty()) { - removeAfterChangingDimensions(); + discard(); if (state.getBlock() instanceof SeatBlock) { level().setBlockAndUpdate(pos, state.setValue(SeatBlock.OCCUPIED, false)); } diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/util/init/WoodTypeDeferredHolder.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/util/init/WoodTypeDeferredHolder.java index 10ecfd2c..27a38976 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/util/init/WoodTypeDeferredHolder.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/util/init/WoodTypeDeferredHolder.java @@ -30,7 +30,6 @@ public class WoodTypeDeferredHolder { * @param creator A function of {@link BibliocraftWoodType} to {@code T}, responsible for actually creating the {@link DeferredHolder}. */ public WoodTypeDeferredHolder(DeferredRegister register, String suffix, Function creator) { - System.out.println("Creating " + suffix); for (BibliocraftWoodType type : BibliocraftApi.getWoodTypeRegistry().getAll()) { map.put(type, register.register(type.getRegistrationPrefix() + "_" + suffix, () -> creator.apply(type))); } diff --git a/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/BibliocraftApiTest.java b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/BibliocraftApiTest.java new file mode 100644 index 00000000..c1f6a9b5 --- /dev/null +++ b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/BibliocraftApiTest.java @@ -0,0 +1,50 @@ +package com.github.minecraftschurlimods.bibliocraft.test; + + +import com.github.minecraftschurlimods.bibliocraft.api.BibliocraftApi; +import com.github.minecraftschurlimods.bibliocraft.api.BibliocraftDatagenHelper; +import com.github.minecraftschurlimods.bibliocraft.api.BibliocraftWoodTypeRegistry; +import com.github.minecraftschurlimods.bibliocraft.apiimpl.BibliocraftDatagenHelperImpl; +import com.github.minecraftschurlimods.bibliocraft.apiimpl.BibliocraftWoodTypeRegistryImpl; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.world.level.block.state.properties.WoodType; +import net.neoforged.testframework.annotation.ForEachTest; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.gametest.EmptyTemplate; +import net.neoforged.testframework.gametest.ExtendedGameTestHelper; + +import static com.github.minecraftschurlimods.bibliocraft.test.GametestAssertions.*; + +@ForEachTest(groups = BibliocraftApi.MOD_ID + ".api") +public class BibliocraftApiTest { + @GameTest + @EmptyTemplate + @TestHolder(description = "Test that the BibliocraftDatagenHelper is available via the BibliocraftApi") + public static void testDatagenHelperAvailable(ExtendedGameTestHelper helper) { + BibliocraftDatagenHelper datagenHelper = BibliocraftApi.getDatagenHelper(); + assertNotNull(datagenHelper, "BibliocraftDatagenHelper is not available"); + assertInstance(datagenHelper, BibliocraftDatagenHelperImpl.class, "BibliocraftDatagenHelper implementation is replaced"); + helper.succeed(); + } + + @GameTest + @EmptyTemplate + @TestHolder(description = "Test that the BibliocraftWoodTypeRegistry is available via the BibliocraftApi") + public static void testWoodTypeRegistryAvailable(ExtendedGameTestHelper helper) { + BibliocraftWoodTypeRegistry woodTypeRegistry = BibliocraftApi.getWoodTypeRegistry(); + assertNotNull(woodTypeRegistry, "BibliocraftWoodTypeRegistry is not available"); + assertInstance(woodTypeRegistry, BibliocraftWoodTypeRegistryImpl.class, "BibliocraftWoodTypeRegistry implementation is replaced"); + assertNotNull(woodTypeRegistry.get(WoodType.OAK), "Oak WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.SPRUCE), "Spruce WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.BIRCH), "Birch WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.JUNGLE), "Jungle WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.ACACIA), "Acacia WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.DARK_OAK), "Dark Oak WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.CRIMSON), "Crimson WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.WARPED), "Warped WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.MANGROVE), "Mangrove WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.BAMBOO), "Bamboo WoodType is not registered"); + assertNotNull(woodTypeRegistry.get(WoodType.CHERRY), "Cherry WoodType is not registered"); + helper.succeed(); + } +} diff --git a/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/GametestAssertions.java b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/GametestAssertions.java new file mode 100644 index 00000000..6f1f55f7 --- /dev/null +++ b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/GametestAssertions.java @@ -0,0 +1,76 @@ +package com.github.minecraftschurlimods.bibliocraft.test; + +import net.minecraft.gametest.framework.GameTestAssertException; +import org.jetbrains.annotations.ApiStatus.NonExtendable; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; + +import java.math.BigDecimal; +import java.util.Objects; + +@NonExtendable +public interface GametestAssertions { + @Contract("false, _ -> fail") + static void assertTrue(boolean condition, String message) { + if (!condition) { + fail(message); + } + } + + @Contract("true, _ -> fail") + static void assertFalse(boolean condition, String message) { + if (condition) { + fail(message); + } + } + + @SuppressWarnings("UnusedReturnValue") + static T assertInstance(@Nullable Object instance, Class clazz, String message) { + if (!clazz.isInstance(instance)) { + fail(message); + return null; // never reached + } else { + return clazz.cast(instance); + } + } + + @Contract("!null, _ -> fail") + static void assertNull(@Nullable Object o, String message) { + if (o != null) { + fail(message); + } + } + + @Contract("null, _ -> fail") + static void assertNotNull(@Nullable Object o, String message) { + if (o == null) { + fail(message); + } + } + + static void assertEquals(@Nullable Object expected, @Nullable Object actual, String message) { + if (expected == null) { + assertNull(actual, message); + } + if (expected instanceof BigDecimal bd1 && actual instanceof BigDecimal bd2) { + assertEquals(bd1, bd2, message); + } + if (!Objects.equals(expected, actual)) { + fail(message); + } + } + + static void assertEquals(@Nullable BigDecimal expected, @Nullable BigDecimal actual, String message) { + if (expected == null) { + assertNull(actual, message); + } + if (Objects.compare(expected, actual, Comparable::compareTo) != 0) { + fail(message); + } + } + + @Contract("_ -> fail") + static void fail(String message) throws GameTestAssertException { + throw new GameTestAssertException(message); + } +} diff --git a/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/Tests.java b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/Tests.java new file mode 100644 index 00000000..686b6f7b --- /dev/null +++ b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/Tests.java @@ -0,0 +1,48 @@ +package com.github.minecraftschurlimods.bibliocraft.test; + +import com.github.minecraftschurlimods.bibliocraft.api.BibliocraftApi; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.bus.api.EventPriority; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLConstructModEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.RegisterCommandsEvent; +import net.neoforged.testframework.conf.ClientConfiguration; +import net.neoforged.testframework.conf.Feature; +import net.neoforged.testframework.conf.FrameworkConfiguration; +import net.neoforged.testframework.impl.MutableTestFramework; +import net.neoforged.testframework.summary.GitHubActionsStepSummaryFormatter; +import org.lwjgl.glfw.GLFW; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = BibliocraftApi.MOD_ID) +public final class Tests { + @SubscribeEvent(priority = EventPriority.HIGHEST) + static void init(FMLConstructModEvent event) { + ModList.get().getModContainerById(BibliocraftApi.MOD_ID).ifPresent(Tests::init); + } + + private static void init(ModContainer container) { + final MutableTestFramework framework = FrameworkConfiguration.builder(new ResourceLocation(container.getModId(), "tests")) + .clientConfiguration(() -> ClientConfiguration.builder() + .toggleOverlayKey(GLFW.GLFW_KEY_J) + .openManagerKey(GLFW.GLFW_KEY_N) + .build()) + .enable(Feature.CLIENT_SYNC, Feature.CLIENT_MODIFICATIONS, Feature.TEST_STORE) + .formatters(new GitHubActionsStepSummaryFormatter("Bibliocraft Gametest Summary")) + .build().create(); + + framework.init(container.getEventBus(), container); + + NeoForge.EVENT_BUS.addListener((final RegisterCommandsEvent event) -> { + final LiteralArgumentBuilder node = Commands.literal("tests"); + framework.registerCommands(node); + event.getDispatcher().register(node); + }); + } +} diff --git a/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/package-info.java b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/package-info.java new file mode 100644 index 00000000..d707fc3f --- /dev/null +++ b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package com.github.minecraftschurlimods.bibliocraft.test; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/readme.txt b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/readme.txt new file mode 100644 index 00000000..0ca7149a --- /dev/null +++ b/src/test/java/com/github/minecraftschurlimods/bibliocraft/test/readme.txt @@ -0,0 +1,12 @@ +todo: + - add tests for interactions + - bookcase + - display case + - fancy armor stand + - potion shelf + - seat + - shelf + - sword pedestal + - table + - toolrack + - add tests for automation (hoppers etc.)