diff --git a/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/inventory/BInventory.java b/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/inventory/BInventory.java index fb1b56ad9b..fd7273e2af 100644 --- a/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/inventory/BInventory.java +++ b/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/inventory/BInventory.java @@ -394,7 +394,7 @@ public void addUpdatingButton(AdvancedCorePlugin plugin, long delay, long interv if (futures == null) { futures = new ArrayList<>(); } - futures.add(plugin.getInventoryTimer().scheduleWithFixedDelay(runnable, delay, delay, TimeUnit.MILLISECONDS)); + futures.add(plugin.getInventoryTimer().scheduleWithFixedDelay(runnable, delay, interval, TimeUnit.MILLISECONDS)); } /** diff --git a/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/misc/MiscUtils.java b/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/misc/MiscUtils.java index c5cc386363..f0a8276fa2 100644 --- a/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/misc/MiscUtils.java +++ b/AdvancedCore/src/main/java/com/bencodez/advancedcore/api/misc/MiscUtils.java @@ -72,7 +72,7 @@ private MiscUtils() { */ public Date addSeconds(Date date, int seconds) { Calendar c = Calendar.getInstance(); - c.setTime(new Date()); + c.setTime(date); c.add(Calendar.SECOND, seconds); return c.getTime(); } @@ -165,6 +165,7 @@ public void executeConsoleCommands(final ArrayList cmds, final HashMap for (final String cmd : commands) { plugin.debug("Executing console command: " + cmd); runConsoleCommand(cmd, tick, stagger); + tick++; } } @@ -191,7 +193,7 @@ public void executeConsoleCommands(Player player, String command, HashMap 0) { plugin.getBukkitScheduler().runTaskLater(plugin, new Runnable() { @Override public void run() { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command); + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), commandToRun); } }, delay); @@ -472,12 +473,19 @@ public void run() { @Override public void run() { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command); + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), commandToRun); } }); } } + private String stripLeadingSlash(String command) { + if (command != null && command.startsWith("/")) { + return command.substring(1); + } + return command; + } + public void setBlockMeta(Block block, String str, Object value) { block.removeMetadata(str, plugin); block.setMetadata(str, new MetadataValue() { diff --git a/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/FileThread.java b/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/FileThread.java index d235193e24..cd99a21afe 100644 --- a/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/FileThread.java +++ b/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/FileThread.java @@ -115,12 +115,12 @@ public boolean hasPlayerFile(String uuid) { @Override public void run() { - while (!thread.isInterrupted()) { + while (!isInterrupted()) { try { sleep(50); } catch (InterruptedException e) { - e.printStackTrace(); - System.exit(0); + interrupt(); + break; } } } @@ -214,4 +214,4 @@ public void loadThread() { public void run(Runnable run) { getThread().run(run); } -} \ No newline at end of file +} diff --git a/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/Thread.java b/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/Thread.java index c3fd4ac81d..87cd77392f 100644 --- a/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/Thread.java +++ b/AdvancedCore/src/main/java/com/bencodez/advancedcore/thread/Thread.java @@ -29,12 +29,12 @@ public String getName(java.util.UUID uuid) { @Override public void run() { - while (!thread.isInterrupted()) { + while (!isInterrupted()) { try { sleep(50); } catch (InterruptedException e) { - e.printStackTrace(); - System.exit(0); + interrupt(); + break; } } } diff --git a/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/inventory/BInventoryTest.java b/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/inventory/BInventoryTest.java new file mode 100644 index 0000000000..2943b530c5 --- /dev/null +++ b/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/inventory/BInventoryTest.java @@ -0,0 +1,38 @@ +package com.bencodez.advancedcore.tests.inventory; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.Test; + +import com.bencodez.advancedcore.AdvancedCorePlugin; +import com.bencodez.advancedcore.api.inventory.BInventory; + +public class BInventoryTest { + + @Test + @SuppressWarnings("rawtypes") + public void updatingButtonUsesConfiguredIntervalAndCancelsFuture() { + AdvancedCorePlugin plugin = mock(AdvancedCorePlugin.class); + ScheduledExecutorService timer = mock(ScheduledExecutorService.class); + ScheduledFuture future = mock(ScheduledFuture.class); + Runnable runnable = mock(Runnable.class); + when(plugin.getInventoryTimer()).thenReturn(timer); + doReturn(future).when(timer).scheduleWithFixedDelay(eq(runnable), eq(100L), eq(250L), + eq(TimeUnit.MILLISECONDS)); + + BInventory inventory = new BInventory("Test"); + inventory.addUpdatingButton(plugin, 100L, 250L, runnable); + inventory.cancelTimer(); + + verify(timer).scheduleWithFixedDelay(runnable, 100L, 250L, TimeUnit.MILLISECONDS); + verify(future).cancel(true); + } +} diff --git a/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/misc/MiscUtilsTest.java b/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/misc/MiscUtilsTest.java new file mode 100644 index 0000000000..306995e729 --- /dev/null +++ b/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/misc/MiscUtilsTest.java @@ -0,0 +1,86 @@ +package com.bencodez.advancedcore.tests.misc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.ConsoleCommandSender; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.MockedStatic; + +import com.bencodez.advancedcore.AdvancedCorePlugin; +import com.bencodez.advancedcore.api.misc.MiscUtils; +import com.bencodez.advancedcore.tests.BaseTest; +import com.bencodez.simpleapi.scheduler.BukkitScheduler; + +public class MiscUtilsTest { + + private AdvancedCorePlugin plugin; + private BukkitScheduler scheduler; + private MiscUtils miscUtils; + + @BeforeEach + public void setUp() throws Exception { + plugin = BaseTest.getInstance().plugin; + scheduler = mock(BukkitScheduler.class); + when(plugin.getBukkitScheduler()).thenReturn(scheduler); + miscUtils = MiscUtils.getInstance(); + + Field pluginField = MiscUtils.class.getDeclaredField("plugin"); + pluginField.setAccessible(true); + pluginField.set(miscUtils, plugin); + } + + @Test + public void addSecondsUsesProvidedDate() { + Date base = new Date(1_000_000L); + + Date result = miscUtils.addSeconds(base, 30); + + assertEquals(1_030_000L, result.getTime()); + } + + @Test + public void staggeredCommandsIncrementDelayForEachCommand() { + ArrayList commands = new ArrayList<>(List.of("first", "second", "third")); + + miscUtils.executeConsoleCommands(commands, new HashMap<>(), true); + + verify(scheduler).runTask(eq(plugin), any(Runnable.class)); + verify(scheduler).runTaskLater(eq(plugin), any(Runnable.class), eq(1L)); + verify(scheduler).runTaskLater(eq(plugin), any(Runnable.class), eq(2L)); + } + + @Test + public void consoleCommandsStripLeadingSlashBeforeDispatch() { + Server server = mock(Server.class); + ConsoleCommandSender console = mock(ConsoleCommandSender.class); + ArgumentCaptor task = ArgumentCaptor.forClass(Runnable.class); + + try (MockedStatic bukkit = mockStatic(Bukkit.class)) { + bukkit.when(Bukkit::getServer).thenReturn(server); + bukkit.when(Bukkit::getConsoleSender).thenReturn(console); + bukkit.when(() -> Bukkit.getOfflinePlayer("Ben")).thenReturn(null); + + miscUtils.executeConsoleCommands("Ben", "/say hi", new HashMap<>()); + + verify(scheduler).executeOrScheduleSync(eq(plugin), task.capture()); + task.getValue().run(); + verify(server).dispatchCommand(console, "say hi"); + } + } +} diff --git a/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/thread/ThreadInterruptionTest.java b/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/thread/ThreadInterruptionTest.java new file mode 100644 index 0000000000..ae9f3d680f --- /dev/null +++ b/AdvancedCore/src/test/java/com/bencodez/advancedcore/tests/thread/ThreadInterruptionTest.java @@ -0,0 +1,34 @@ +package com.bencodez.advancedcore.tests.thread; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Test; + +import com.bencodez.advancedcore.thread.FileThread; + +public class ThreadInterruptionTest { + + @Test + public void fileReadThreadStopsWhenInterrupted() throws InterruptedException { + FileThread.ReadThread readThread = FileThread.getInstance().new ReadThread(); + + readThread.start(); + readThread.interrupt(); + readThread.join(1_000L); + + assertFalse(readThread.isAlive()); + } + + @Test + @SuppressWarnings("deprecation") + public void legacyReadThreadStopsWhenInterrupted() throws InterruptedException { + com.bencodez.advancedcore.thread.Thread.ReadThread readThread = com.bencodez.advancedcore.thread.Thread + .getInstance().new ReadThread(); + + readThread.start(); + readThread.interrupt(); + readThread.join(1_000L); + + assertFalse(readThread.isAlive()); + } +}