diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts index dccac76..11f4bcd 100644 --- a/paper/build.gradle.kts +++ b/paper/build.gradle.kts @@ -39,6 +39,14 @@ dependencies { // Lombok compileOnly("org.projectlombok:lombok:1.18.32") annotationProcessor("org.projectlombok:lombok:1.18.32") + + // Testing + testImplementation(platform("org.junit:junit-bom:5.12.2")) + testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.76.1") + testImplementation("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT") + testImplementation("net.kyori:adventure-text-serializer-plain:4.26.1") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } java { @@ -57,6 +65,10 @@ tasks.shadowJar { archiveClassifier.set("") } +tasks.test { + useJUnitPlatform() +} + publishing { publications { create("mavenJava") { diff --git a/paper/src/test/java/gg/moonrise/engine/paper/cooldown/CooldownsTest.java b/paper/src/test/java/gg/moonrise/engine/paper/cooldown/CooldownsTest.java new file mode 100644 index 0000000..79dcd1d --- /dev/null +++ b/paper/src/test/java/gg/moonrise/engine/paper/cooldown/CooldownsTest.java @@ -0,0 +1,39 @@ +package gg.moonrise.engine.paper.cooldown; + +import gg.moonrise.engine.paper.support.MockBukkitTest; +import net.kyori.adventure.text.Component; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerQuitEvent.QuitReason; +import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.entity.PlayerMock; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CooldownsTest extends MockBukkitTest { + + @Test + void cooldownsExpireByTime() { + PlayerMock player = server.addPlayer(); + String key = "action"; + + Cooldowns.addCooldown(player.getUniqueId(), key, Duration.ofSeconds(1)); + assertTrue(Cooldowns.isOnCooldown(player.getUniqueId(), key)); + + Cooldowns.addCooldown(player.getUniqueId(), key, -1L); + assertFalse(Cooldowns.isOnCooldown(player.getUniqueId(), key)); + } + + @Test + void quitClearsPlayerCooldowns() { + PlayerMock player = server.addPlayer(); + String key = "quit-action"; + Cooldowns.addCooldown(player.getUniqueId(), key, Duration.ofMinutes(1)); + + new Cooldowns().onQuit(new PlayerQuitEvent(player, Component.empty(), QuitReason.DISCONNECTED)); + + assertFalse(Cooldowns.isOnCooldown(player.getUniqueId(), key)); + } +} diff --git a/paper/src/test/java/gg/moonrise/engine/paper/data/AABBTest.java b/paper/src/test/java/gg/moonrise/engine/paper/data/AABBTest.java new file mode 100644 index 0000000..06056c0 --- /dev/null +++ b/paper/src/test/java/gg/moonrise/engine/paper/data/AABBTest.java @@ -0,0 +1,46 @@ +package gg.moonrise.engine.paper.data; + +import org.bukkit.util.Vector; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class AABBTest { + + @Test + void convertsToVectorsAndArrays() { + AABB box = new AABB(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); + + assertEquals(new Vector(1.0, 2.0, 3.0), box.minVector()); + assertEquals(new Vector(4.0, 5.0, 6.0), box.maxVector()); + assertEquals(box.minVector(), box.toVectors().first()); + assertEquals(box.maxVector(), box.toVectors().second()); + assertArrayEquals(new double[]{1.0, 2.0, 3.0}, box.minArray()); + assertArrayEquals(new double[]{4.0, 5.0, 6.0}, box.maxArray()); + assertArrayEquals(new double[]{1.0, 2.0, 3.0, 4.0, 5.0, 6.0}, box.toArrayPair()); + } + + @Test + void insideCheckIncludesBoundaries() { + AABB box = new AABB(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); + + assertTrue(box.isInside(1.0, 2.0, 3.0)); + assertTrue(box.isInside(new Vector(4.0, 5.0, 6.0))); + assertTrue(box.isInside(2.5, 3.5, 4.5)); + assertFalse(box.isInside(0.99, 3.5, 4.5)); + assertFalse(box.isInside(2.5, 5.01, 4.5)); + } + + @Test + void createsFromVectorsAndArrayPair() { + AABB fromVectors = AABB.fromVectors(new Vector(1.0, 2.0, 3.0), new Vector(4.0, 5.0, 6.0)); + AABB fromArray = AABB.fromArrayPair(new double[]{1.0, 2.0, 3.0, 4.0, 5.0, 6.0}); + + assertEquals(fromVectors, fromArray); + assertThrows(IllegalArgumentException.class, () -> AABB.fromArrayPair(new double[]{1.0, 2.0})); + } +} diff --git a/paper/src/test/java/gg/moonrise/engine/paper/gui/ChestMenuTest.java b/paper/src/test/java/gg/moonrise/engine/paper/gui/ChestMenuTest.java new file mode 100644 index 0000000..646138c --- /dev/null +++ b/paper/src/test/java/gg/moonrise/engine/paper/gui/ChestMenuTest.java @@ -0,0 +1,72 @@ +package gg.moonrise.engine.paper.gui; + +import gg.moonrise.engine.paper.gui.button.Button; +import gg.moonrise.engine.paper.support.MockBukkitTest; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataType; +import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.entity.PlayerMock; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ChestMenuTest extends MockBukkitTest { + + @Test + void addRemoveAndSlotBoundsWork() { + PlayerMock player = server.addPlayer(); + TestChestMenu menu = new TestChestMenu(player, 1); + Button button = button(Material.DIAMOND); + + menu.addButton(0, button); + + assertTrue(menu.hasButton(0)); + assertEquals(1, menu.getButtonCount()); + assertEquals(button, menu.removeButton(0)); + assertFalse(menu.hasButton(0)); + assertNull(button.boundingInventory()); + assertThrows(IllegalArgumentException.class, () -> menu.addButton(9, button)); + } + + @Test + void refreshWritesButtonItemsAndPersistentIds() { + PlayerMock player = server.addPlayer(); + TestChestMenu menu = new TestChestMenu(player, 1); + Button button = Button.builder() + .item(viewer -> new ItemStack(Material.EMERALD)) + .refresh(10L) + .build(); + + menu.addButton(4, button); + menu.refresh(); + + ItemStack rendered = menu.getView().getTopInventory().getItem(4); + assertNotNull(rendered); + assertEquals(Material.EMERALD, rendered.getType()); + assertEquals(button.uuid().toString(), rendered.getPersistentDataContainer().get(Button.KEY, PersistentDataType.STRING)); + assertEquals(menu.getView(), button.boundingInventory()); + assertEquals(1, menu.getRefreshingButtons().size()); + assertTrue(menu.checkCancelClick(4)); + } + + private static Button button(Material material) { + return Button.builder() + .item(player -> new ItemStack(material)) + .build(); + } + + private static final class TestChestMenu extends ChestMenu { + + private TestChestMenu(Player player, int rows) { + super(player, "Test", rows); + } + } +} diff --git a/paper/src/test/java/gg/moonrise/engine/paper/gui/HopperMenuTest.java b/paper/src/test/java/gg/moonrise/engine/paper/gui/HopperMenuTest.java new file mode 100644 index 0000000..d93eddc --- /dev/null +++ b/paper/src/test/java/gg/moonrise/engine/paper/gui/HopperMenuTest.java @@ -0,0 +1,55 @@ +package gg.moonrise.engine.paper.gui; + +import gg.moonrise.engine.paper.gui.button.Button; +import gg.moonrise.engine.paper.support.MockBukkitTest; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataType; +import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.entity.PlayerMock; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class HopperMenuTest extends MockBukkitTest { + + @Test + void refreshWritesButtonItemsAndPersistentIds() { + PlayerMock player = server.addPlayer(); + TestHopperMenu menu = new TestHopperMenu(player); + Button button = Button.builder() + .item(viewer -> new ItemStack(Material.HOPPER)) + .refresh(5L) + .build(); + + menu.addButton(2, button); + menu.refresh(); + + ItemStack rendered = menu.getView().getTopInventory().getItem(2); + assertNotNull(rendered); + assertEquals(Material.HOPPER, rendered.getType()); + assertEquals(button.uuid().toString(), rendered.getPersistentDataContainer().get(Button.KEY, PersistentDataType.STRING)); + assertEquals(menu.getView(), button.boundingInventory()); + assertEquals(1, menu.getRefreshingButtons().size()); + assertTrue(menu.checkCancelClick(2)); + } + + @Test + void cancelClicksCanBeDisabled() { + TestHopperMenu menu = new TestHopperMenu(server.addPlayer()); + + assertTrue(menu.cancelClicks()); + menu.cancelClicks(false); + assertFalse(menu.cancelClicks()); + } + + private static final class TestHopperMenu extends HopperMenu { + + private TestHopperMenu(Player player) { + super(player, "Test"); + } + } +} diff --git a/paper/src/test/java/gg/moonrise/engine/paper/gui/button/ButtonTest.java b/paper/src/test/java/gg/moonrise/engine/paper/gui/button/ButtonTest.java new file mode 100644 index 0000000..4fd4ea1 --- /dev/null +++ b/paper/src/test/java/gg/moonrise/engine/paper/gui/button/ButtonTest.java @@ -0,0 +1,56 @@ +package gg.moonrise.engine.paper.gui.button; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ButtonTest { + + @Test + void builderRequiresDisplayItem() { + assertThrows(IllegalStateException.class, () -> Button.builder().build()); + } + + @Test + void builderStoresDefaultsAndRefreshInterval() { + Button button = Button.builder() + .item(player -> new ItemStack(Material.DIAMOND)) + .refresh(20L) + .build(); + + assertNotNull(button.uuid()); + assertTrue(button.cancelClick()); + assertEquals(20L, button.refreshIntervalTicks()); + button.setLastRefreshTime(40L); + assertEquals(40L, button.lastRefreshTime()); + } + + @Test + void customCancelAndClickActionAreApplied() { + AtomicBoolean clicked = new AtomicBoolean(false); + AtomicReference