diff options
Diffstat (limited to 'src/test/java/de/hysky')
21 files changed, 750 insertions, 0 deletions
diff --git a/src/test/java/de/hysky/skyblocker/skyblock/StatusBarTrackerTest.java b/src/test/java/de/hysky/skyblocker/skyblock/StatusBarTrackerTest.java new file mode 100644 index 00000000..c058da5d --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/StatusBarTrackerTest.java @@ -0,0 +1,74 @@ +package de.hysky.skyblocker.skyblock; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class StatusBarTrackerTest { + private StatusBarTracker tracker; + + @BeforeEach + void setUp() { + tracker = new StatusBarTracker(); + } + + void assertStats(int hp, int maxHp, int def, int mana, int maxMana, int overflowMana) { + int absorption = 0; + if(hp > maxHp) { + absorption = hp - maxHp; + hp -= absorption; + if(absorption > maxHp) + absorption = maxHp; + } + assertEquals(new StatusBarTracker.Resource(hp, maxHp, absorption), tracker.getHealth()); + assertEquals(new StatusBarTracker.Resource(mana, maxMana, overflowMana), tracker.getMana()); + } + + @Test + void normalStatusBar() { + String res = tracker.update("§c934/1086❤ §a159§a❈ Defense §b562/516✎ Mana", false); + assertNull(res); + assertStats(934, 1086, 159, 562, 516, 0); + } + + @Test + void overflowMana() { + String res = tracker.update("§61605/1305❤ §a270§a❈ Defense §b548/548✎ §3200ʬ", false); + assertNull(res); + assertStats(1605, 1305, 270, 548, 548, 200); + } + + @Test + void regeneration() { + String res = tracker.update("§c2484/2484❤+§c120▄ §a642§a❈ Defense §b2557/2611✎ Mana", false); + assertEquals("§c❤+§c120▄", res); + } + + @Test + void instantTransmission() { + String actionBar = "§c2259/2259❤ §b-20 Mana (§6Instant Transmission§b) §b549/2676✎ Mana"; + assertEquals("§b-20 Mana (§6Instant Transmission§b)", tracker.update(actionBar, false)); + assertNull(tracker.update(actionBar, true)); + } + + @Test + void rapidFire() { + String actionBar = "§c2509/2509❤ §b-48 Mana (§6Rapid-fire§b) §b2739/2811✎ Mana"; + assertEquals("§b-48 Mana (§6Rapid-fire§b)", tracker.update(actionBar, false)); + assertNull(tracker.update(actionBar, true)); + } + + @Test + void zombieSword() { + String actionBar = "§c2509/2509❤ §b-56 Mana (§6Instant Heal§b) §b2674/2821✎ Mana §e§lⓩⓩⓩⓩ§6§lⓄ"; + assertEquals("§b-56 Mana (§6Instant Heal§b) §e§lⓩⓩⓩⓩ§6§lⓄ", tracker.update(actionBar, false)); + assertEquals("§e§lⓩⓩⓩⓩ§6§lⓄ", tracker.update(actionBar, true)); + } + + @Test + void campfire() { + String res = tracker.update("§c17070/25565❤+§c170▃ §65,625 DPS §c1 second §b590/626✎ §3106ʬ", false); + assertEquals("§c❤+§c170▃ §65,625 DPS §c1 second", res); + } +} diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/AcceptRepartyTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/AcceptRepartyTest.java new file mode 100644 index 00000000..5dba3f96 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/AcceptRepartyTest.java @@ -0,0 +1,37 @@ +package de.hysky.skyblocker.skyblock.dungeon; + +import de.hysky.skyblocker.utils.chat.ChatPatternListenerTest; +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class AcceptRepartyTest extends ChatPatternListenerTest<Reparty> { + + public AcceptRepartyTest() { super(new Reparty()); } + + protected void assertGroup(String message, String group, String expect) { + Matcher matcher = matcher(message); + assertTrue(matcher.matches()); + assertEquals(expect, matcher.group(group)); + } + + @Test + void testDisband() { + assertGroup("[VIP+] KoloiYolo has disbanded the party!", + /* group: */ "disband", + /* expect: */ "KoloiYolo"); + } + + @Test + void testInvite() { + assertGroup("-----------------------------------------------------" + + "\n[MVP+] 1wolvesgaming has invited you to join their party!" + + "\nYou have 60 seconds to accept. Click here to join!" + + "\n-----------------------------------------------------", + /* group: */ "invite", + /* expect: */ "1wolvesgaming"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/DungeonChestProfitTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/DungeonChestProfitTest.java new file mode 100644 index 00000000..3a55ce5b --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/DungeonChestProfitTest.java @@ -0,0 +1,22 @@ +package de.hysky.skyblocker.skyblock.dungeon; + +import de.hysky.skyblocker.config.SkyblockerConfig; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class DungeonChestProfitTest { + @Test + void testProfitText() { + SkyblockerConfig.DungeonChestProfit config = new SkyblockerConfig.DungeonChestProfit(); + Assertions.assertEquals("literal{ 0}[style={color=dark_gray}]", DungeonChestProfit.getProfitText(0, false, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ 0}[style={color=blue}]", DungeonChestProfit.getProfitText(0, true, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ +10}[style={color=dark_gray}]", DungeonChestProfit.getProfitText(10, false, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ +10}[style={color=blue}]", DungeonChestProfit.getProfitText(10, true, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ -10}[style={color=dark_gray}]", DungeonChestProfit.getProfitText(-10, false, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ -10}[style={color=blue}]", DungeonChestProfit.getProfitText(-10, true, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ +10,000}[style={color=dark_green}]", DungeonChestProfit.getProfitText(10000, false, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ +10,000}[style={color=blue}]", DungeonChestProfit.getProfitText(10000, true, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ -10,000}[style={color=red}]", DungeonChestProfit.getProfitText(-10000, false, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + Assertions.assertEquals("literal{ -10,000}[style={color=blue}]", DungeonChestProfit.getProfitText(-10000, true, config.neutralThreshold, config.neutralColor, config.profitColor, config.lossColor, config.incompleteColor).toString()); + } +} diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/ThreeWeirdosTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/ThreeWeirdosTest.java new file mode 100644 index 00000000..3772fd75 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/ThreeWeirdosTest.java @@ -0,0 +1,19 @@ +package de.hysky.skyblocker.skyblock.dungeon; + +import de.hysky.skyblocker.utils.chat.ChatPatternListenerTest; +import org.junit.jupiter.api.Test; + +class ThreeWeirdosTest extends ChatPatternListenerTest<ThreeWeirdos> { + public ThreeWeirdosTest() { + super(new ThreeWeirdos()); + } + + @Test + void test1() { + assertGroup("§e[NPC] §cBaxter§f: My chest doesn't have the reward. We are all telling the truth.", 1, "Baxter"); + } + @Test + void test2() { + assertGroup("§e[NPC] §cHope§f: The reward isn't in any of our chests.", 1, "Hope"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/TriviaTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/TriviaTest.java new file mode 100644 index 00000000..1df5a8e1 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/TriviaTest.java @@ -0,0 +1,33 @@ +package de.hysky.skyblocker.skyblock.dungeon; + +import de.hysky.skyblocker.utils.chat.ChatPatternListenerTest; +import org.junit.jupiter.api.Test; + +class TriviaTest extends ChatPatternListenerTest<Trivia> { + public TriviaTest() { + super(new Trivia()); + } + + @Test + void anyQuestion1() { + assertGroup(" What is the first question?", 1, "What is the first question?"); + } + + @Test + void anyQestion2() { + assertGroup(" How many questions are there?", 1, "How many questions are there?"); + } + + @Test + void answer1() { + assertGroup(" §6 ⓐ §aAnswer 1", 3, "Answer 1"); + } + @Test + void answer2() { + assertGroup(" §6 ⓑ §aAnswer 2", 3, "Answer 2"); + } + @Test + void answer3() { + assertGroup(" §6 ⓒ §aAnswer 3", 3, "Answer 3"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java new file mode 100644 index 00000000..3d2993cf --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -0,0 +1,167 @@ +package de.hysky.skyblocker.skyblock.dungeon.secrets; + +import net.minecraft.datafixer.fix.ItemIdFix; +import net.minecraft.datafixer.fix.ItemInstanceTheFlatteningFix; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.URL; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + +/** + * Utility class to convert the old dungeon rooms data from Dungeon Rooms Mod to a new format. + * The new format is similar to <a href="https://quantizr.github.io/posts/how-it-works/">DRM's format</a>, but uses ints instead of longs and a custom numeric block id to store the block states. + * The first byte is the x position, the second byte is the y position, the third byte is the z position, and the fourth byte is the custom numeric block id. + * Use {@link DungeonSecrets#NUMERIC_ID} to get the custom numeric block id of a block. + * Run this manually when updating dungeon rooms data with DRM's data in {@code src/test/resources/assets/skyblocker/dungeons/dungeonrooms}. + */ +public class DungeonRoomsDFU { + private static final Logger LOGGER = LoggerFactory.getLogger(DungeonRoomsDFU.class); + private static final String DUNGEONS_DATA_DIR = "/assets/skyblocker/dungeons"; + private static final String DUNGEON_ROOMS_DATA_DIR = DUNGEONS_DATA_DIR + "/dungeonrooms"; + private static final HashMap<String, HashMap<String, HashMap<String, long[]>>> OLD_ROOMS = new HashMap<>(); + private static final HashMap<String, HashMap<String, HashMap<String, int[]>>> ROOMS = new HashMap<>(); + + public static void main(String[] args) { + load().join(); + updateRooms(); + save().join(); + } + + private static CompletableFuture<Void> load() { + List<CompletableFuture<Void>> dungeonFutures = new ArrayList<>(); + URL dungeonsURL = DungeonRoomsDFU.class.getResource(DUNGEON_ROOMS_DATA_DIR); + if (dungeonsURL == null) { + LOGGER.error("Failed to load dungeon secrets, unable to find dungeon rooms data directory"); + return CompletableFuture.completedFuture(null); + } + Path dungeonsDir = Path.of(dungeonsURL.getPath()); + int resourcePathIndex = dungeonsDir.toString().indexOf(DUNGEON_ROOMS_DATA_DIR); + try (DirectoryStream<Path> dungeons = Files.newDirectoryStream(dungeonsDir, Files::isDirectory)) { + for (Path dungeon : dungeons) { + try (DirectoryStream<Path> roomShapes = Files.newDirectoryStream(dungeon, Files::isDirectory)) { + List<CompletableFuture<Void>> roomShapeFutures = new ArrayList<>(); + HashMap<String, HashMap<String, long[]>> roomShapesMap = new HashMap<>(); + for (Path roomShape : roomShapes) { + roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> roomShapesMap.put(roomShape.getFileName().toString().toLowerCase(), rooms))); + } + OLD_ROOMS.put(dungeon.getFileName().toString().toLowerCase(), roomShapesMap); + dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getFileName(), roomShapesMap.size(), roomShapesMap.values().stream().mapToInt(HashMap::size).sum()))); + } catch (IOException e) { + LOGGER.error("Failed to load dungeon secrets for dungeon " + dungeon.getFileName(), e); + } + } + } catch (IOException e) { + LOGGER.error("Failed to load dungeon secrets", e); + } + return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", OLD_ROOMS.size(), OLD_ROOMS.values().stream().mapToInt(HashMap::size).sum(), OLD_ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); + } + + private static HashMap<String, long[]> readRooms(Path roomShape, int resourcePathIndex) { + try (DirectoryStream<Path> rooms = Files.newDirectoryStream(roomShape, Files::isRegularFile)) { + HashMap<String, long[]> roomsData = new HashMap<>(); + for (Path room : rooms) { + String name = room.getFileName().toString(); + //noinspection DataFlowIssue + try (ObjectInputStream in = new ObjectInputStream(new InflaterInputStream(DungeonRoomsDFU.class.getResourceAsStream(room.toString().substring(resourcePathIndex))))) { + roomsData.put(name.substring(0, name.length() - 9).toLowerCase(), (long[]) in.readObject()); + LOGGER.info("Loaded dungeon secrets room {}", name); + } catch (NullPointerException | IOException | ClassNotFoundException e) { + LOGGER.error("Failed to load dungeon secrets room " + name, e); + } + } + LOGGER.info("Loaded dungeon secrets room shape {} with {} rooms", roomShape.getFileName(), roomsData.size()); + return roomsData; + } catch (IOException e) { + LOGGER.error("Failed to load dungeon secrets room shape " + roomShape.getFileName(), e); + } + return null; + } + + private static void updateRooms() { + for (Map.Entry<String, HashMap<String, HashMap<String, long[]>>> oldDungeon : OLD_ROOMS.entrySet()) { + HashMap<String, HashMap<String, int[]>> dungeon = new HashMap<>(); + for (Map.Entry<String, HashMap<String, long[]>> oldRoomShape : oldDungeon.getValue().entrySet()) { + HashMap<String, int[]> roomShape = new HashMap<>(); + for (Map.Entry<String, long[]> oldRoomEntry : oldRoomShape.getValue().entrySet()) { + roomShape.put(oldRoomEntry.getKey().replaceAll(" ", "-"), updateRoom(oldRoomEntry.getValue())); + } + dungeon.put(oldRoomShape.getKey(), roomShape); + } + ROOMS.put(oldDungeon.getKey(), dungeon); + } + } + + private static int[] updateRoom(long[] oldRoom) { + int[] room = new int[oldRoom.length]; + for (int i = 0; i < oldRoom.length; i++) { + room[i] = updateBlock(oldRoom[i]); + } + // Technically not needed, as the long array should be sorted already. + Arrays.sort(room); + return room; + } + + /** + * Updates the block state from Dungeon Rooms Mod's format to the new format explained in {@link DungeonRoomsDFU}. + * + * @param oldBlock the old block state in DRM's format + * @return the new block state in the new format + */ + private static int updateBlock(long oldBlock) { + short x = (short) (oldBlock >> 48 & 0xFFFF); + short y = (short) (oldBlock >> 32 & 0xFFFF); + short z = (short) (oldBlock >> 16 & 0xFFFF); + // Blocks should be within the range 0 to 256, since a dungeon room is at most around 128 blocks long and around 150 blocks tall. + if (x < 0 || x > 0xFF || y < 0 || y > 0xFF || z < 0 || z > 0xFF) { + throw new IllegalArgumentException("Invalid block: " + oldBlock); + } + short oldId = (short) (oldBlock & 0xFFFF); + // Get the new id for the block. + String newId = ItemInstanceTheFlatteningFix.getItem(ItemIdFix.fromId(oldId / 100), oldId % 100); + if (newId == null) { + newId = ItemIdFix.fromId(oldId / 100); + } + return x << 24 | y << 16 | z << 8 | DungeonSecrets.NUMERIC_ID.getByte(newId); + } + + private static CompletableFuture<Void> save() { + List<CompletableFuture<Void>> dungeonFutures = new ArrayList<>(); + for (Map.Entry<String, HashMap<String, HashMap<String, int[]>>> dungeon : ROOMS.entrySet()) { + Path dungeonDir = Path.of("out", "dungeons", dungeon.getKey()); + List<CompletableFuture<Void>> roomShapeFutures = new ArrayList<>(); + for (Map.Entry<String, HashMap<String, int[]>> roomShape : dungeon.getValue().entrySet()) { + Path roomShapeDir = dungeonDir.resolve(roomShape.getKey()); + roomShapeFutures.add(CompletableFuture.runAsync(() -> saveRooms(roomShapeDir, roomShape))); + } + dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Saved dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getKey(), dungeon.getValue().size(), dungeon.getValue().values().stream().mapToInt(HashMap::size).sum()))); + } + return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Saved dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", ROOMS.size(), ROOMS.values().stream().mapToInt(HashMap::size).sum(), ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); + } + + private static void saveRooms(Path roomShapeDir, Map.Entry<String, HashMap<String, int[]>> roomShape) { + try { + Files.createDirectories(roomShapeDir); + } catch (IOException e) { + LOGGER.error("Failed to save dungeon secrets: failed to create dungeon secrets room shape directory " + roomShapeDir, e); + } + for (Map.Entry<String, int[]> room : roomShape.getValue().entrySet()) { + try (ObjectOutputStream out = new ObjectOutputStream(new DeflaterOutputStream(Files.newOutputStream(roomShapeDir.resolve(room.getKey() + ".skeleton"))))) { + out.writeObject(room.getValue()); + LOGGER.info("Saved dungeon secrets room {}", room.getKey()); + } catch (IOException e) { + LOGGER.error("Failed to save dungeon secrets room " + room.getKey(), e); + } + } + LOGGER.info("Saved dungeon secrets room shape {} with {} rooms", roomShape.getKey(), roomShape.getValue().size()); + } +} diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/RoomTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/RoomTest.java new file mode 100644 index 00000000..5309aae6 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/RoomTest.java @@ -0,0 +1,13 @@ +package de.hysky.skyblocker.skyblock.dungeon.secrets; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class RoomTest { + @Test + void onChatMessage() { + Assertions.assertFalse(Room.isAllSecretsFound("§10,000/10,000❤ §a5,000§a❈ Defense §b2,000/2,000✎ Mana §70/1 Secrets")); + Assertions.assertTrue(Room.isAllSecretsFound("§1,000,000/10,000❤ §3+1,000.5 Combat (33.33%) §b4,000/2,000✎ Mana §710/10 Secrets")); + Assertions.assertTrue(Room.isAllSecretsFound("§1,000,000/10,000❤ §b-25 Mana (§6Instant Transmission§b) §b2,000/2,000✎ Mana §710/1 Secrets")); + } +} diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dwarven/FetchurTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dwarven/FetchurTest.java new file mode 100644 index 00000000..08282972 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dwarven/FetchurTest.java @@ -0,0 +1,15 @@ +package de.hysky.skyblocker.skyblock.dwarven; + +import de.hysky.skyblocker.utils.chat.ChatPatternListenerTest; +import org.junit.jupiter.api.Test; + +class FetchurTest extends ChatPatternListenerTest<Fetchur> { + public FetchurTest() { + super(new Fetchur()); + } + + @Test + public void patternCaptures() { + assertGroup("§e[NPC] Fetchur§f: its a hint", 1, "a hint"); + } +} diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dwarven/PuzzlerTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dwarven/PuzzlerTest.java new file mode 100644 index 00000000..9437a5c9 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/dwarven/PuzzlerTest.java @@ -0,0 +1,15 @@ +package de.hysky.skyblocker.skyblock.dwarven; + +import de.hysky.skyblocker.utils.chat.ChatPatternListenerTest; +import org.junit.jupiter.api.Test; + +class PuzzlerTest extends ChatPatternListenerTest<Puzzler> { + public PuzzlerTest() { + super(new Puzzler()); + } + + @Test + void puzzler() { + assertGroup("§e[NPC] §dPuzzler§f: §b◀§d▲§b◀§d▲§d▲§5▶§5▶§b◀§d▲§a▼", 1, "§b◀§d▲§b◀§d▲§d▲§5▶§5▶§b◀§d▲§a▼"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/AbilityFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/AbilityFilterTest.java new file mode 100644 index 00000000..8e286d8f --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/AbilityFilterTest.java @@ -0,0 +1,19 @@ +package de.hysky.skyblocker.skyblock.filters; + +import org.junit.jupiter.api.Test; + +class AbilityFilterTest extends ChatFilterTest<AbilityFilter> { + public AbilityFilterTest() { + super(new AbilityFilter()); + } + + @Test + void charges() { + assertMatches("No more charges, next one in 13.2s!"); + } + + @Test + void cooldown() { + assertMatches("This ability is on cooldown for 42s."); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/AdFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/AdFilterTest.java new file mode 100644 index 00000000..3eec1cd9 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/AdFilterTest.java @@ -0,0 +1,68 @@ +package de.hysky.skyblocker.skyblock.filters; + +import de.hysky.skyblocker.utils.chat.ChatPatternListenerTest; +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class AdFilterTest extends ChatPatternListenerTest<AdFilter> { + public AdFilterTest() { + super(new AdFilter()); + } + + @Test + void noRank() { + assertMatches("§8[§a86§8] §7Advertiser§7: advertisement"); + } + + @Test + void vip() { + assertMatches("§8[§b280§8] §a[VIP] Advertiser§f: advertisement"); + } + + @Test + void mvp() { + assertMatches("§8[§d256§8] §6§l⚡ §b[MVP§c+§b] Advertiser§f: advertisement"); + } + + @Test + void plusPlus() { + assertMatches("§8[§6222§8] §6[MVP§c++§6] Advertiser§f: advertisement"); + } + + @Test + void capturesMessage() { + assertGroup("§8[§c325§8] §b[MVP§c+§b] b2dderr§f: buying prismapump", 2, "buying prismapump"); + } + + @Test + void simpleAd() { + assertFilters("§8[§e320§8] §b[MVP§c+§b] b2dderr§f: buying prismapump"); + } + + @Test + void uppercaseAd() { + assertFilters("§8[§f70§8] §a[VIP] Tecnoisnoob§f: SELLING REJUVENATE 5 Book on ah!"); + } + + @Test + void characterSpam() { + assertFilters("§8[§9144§8] §a[VIP] Benyyy_§f: Hey, Visit my Island, i spent lots of time to build it! I also made donate room! <<<<<<<<<<<<<<<<<<<"); + } + + @Test + void notAd() { + Matcher matcher = listener.pattern.matcher("§8[§6200§8] §a[VIP] NotMatching§f: This message shouldn't match!"); + assertTrue(matcher.matches()); + assertFalse(listener.onMatch(null, matcher)); + } + + void assertFilters(String message) { + Matcher matcher = listener.pattern.matcher(message); + assertTrue(matcher.matches()); + assertTrue(listener.onMatch(null, matcher)); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/AoteFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/AoteFilterTest.java new file mode 100644 index 00000000..3115a48d --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/AoteFilterTest.java @@ -0,0 +1,14 @@ +package de.hysky.skyblocker.skyblock.filters; + +import org.junit.jupiter.api.Test; + +class AoteFilterTest extends ChatFilterTest<AoteFilter> { + public AoteFilterTest() { + super(new AoteFilter()); + } + + @Test + void testRegex() { + assertMatches("There are blocks in the way!"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/AutopetFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/AutopetFilterTest.java new file mode 100644 index 00000000..846acbb8 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/AutopetFilterTest.java @@ -0,0 +1,15 @@ +package de.hysky.skyblocker.skyblock.filters; + +import de.hysky.skyblocker.utils.chat.ChatPatternListenerTest; +import org.junit.jupiter.api.Test; + +class AutopetFilterTest extends ChatPatternListenerTest<AutopetFilter> { + public AutopetFilterTest() { + super(new AutopetFilter()); + } + + @Test + void testAutopet() { + assertMatches("§cAutopet §eequipped your §7[Lvl 85] §6Tiger§e! §a§lVIEW RULE"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/ChatFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/ChatFilterTest.java new file mode 100644 index 00000000..7b779945 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/ChatFilterTest.java @@ -0,0 +1,10 @@ +package de.hysky.skyblocker.skyblock.filters; + +import me.xmrvizzy.skyblocker.utils.chat.ChatPatternListener; +import me.xmrvizzy.skyblocker.utils.chat.ChatPatternListenerTest; + +public class ChatFilterTest<T extends ChatPatternListener> extends ChatPatternListenerTest<T> { + public ChatFilterTest(T listener) { + super(listener); + } +} diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java new file mode 100644 index 00000000..85b01b4b --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java @@ -0,0 +1,29 @@ +package de.hysky.skyblocker.skyblock.filters; + +import org.junit.jupiter.api.Test; + +public class ComboFilterTest extends ChatFilterTest<ComboFilter> { + public ComboFilterTest() { + super(new ComboFilter()); + } + + @Test + void testComboMF() { + assertMatches("+5 Kill Combo +3% ✯ Magic Find"); + } + + @Test + void testComboCoins() { + assertMatches("+10 Kill Combo +10 coins per kill"); + } + + @Test + void testComboEXP() { + assertMatches("+20 Kill Combo +15% Combat Exp"); + } + + @Test + void testComboExpired() { + assertMatches("Your Kill Combo has expired! You reached a 11 Kill Combo!"); + } +} diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/HealFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/HealFilterTest.java new file mode 100644 index 00000000..d57bf0dc --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/HealFilterTest.java @@ -0,0 +1,19 @@ +package de.hysky.skyblocker.skyblock.filters; + +import org.junit.jupiter.api.Test; + +class HealFilterTest extends ChatFilterTest<HealFilter> { + public HealFilterTest() { + super(new HealFilter()); + } + + @Test + void healSelf() { + assertMatches("You healed yourself for 18.3 health!"); + } + + @Test + void healedYou() { + assertMatches("H3aler_ healed you for 56 health!"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/ImplosionFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/ImplosionFilterTest.java new file mode 100644 index 00000000..327fcebb --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/ImplosionFilterTest.java @@ -0,0 +1,19 @@ +package de.hysky.skyblocker.skyblock.filters; + +import org.junit.jupiter.api.Test; + +class ImplosionFilterTest extends ChatFilterTest<ImplosionFilter> { + public ImplosionFilterTest() { + super(new ImplosionFilter()); + } + + @Test + void oneEnemy() { + assertMatches("Your Implosion hit 1 enemy for 636,116.8 damage."); + } + + @Test + void multipleEnemies() { + assertMatches("Your Implosion hit 7 enemies for 4,452,817.4 damage."); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/TeleportPadFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/TeleportPadFilterTest.java new file mode 100644 index 00000000..681d64c0 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/TeleportPadFilterTest.java @@ -0,0 +1,19 @@ +package de.hysky.skyblocker.skyblock.filters; + +import org.junit.jupiter.api.Test; + +public class TeleportPadFilterTest extends ChatFilterTest<TeleportPadFilter> { + public TeleportPadFilterTest() { + super(new TeleportPadFilter()); + } + + @Test + void testTeleport() { + assertMatches("Warped from the Base Teleport Pad to the Minion Teleport Pad!"); + } + + @Test + void testNoDestination() { + assertMatches("This Teleport Pad does not have a destination set!"); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/skyblock/item/ArmorTrimIdSerializationTest.java b/src/test/java/de/hysky/skyblocker/skyblock/item/ArmorTrimIdSerializationTest.java new file mode 100644 index 00000000..36b65cae --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/skyblock/item/ArmorTrimIdSerializationTest.java @@ -0,0 +1,27 @@ +package de.hysky.skyblocker.skyblock.item; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import net.minecraft.util.Identifier; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ArmorTrimIdSerializationTest { + private final Gson gson = new GsonBuilder().registerTypeAdapter(Identifier.class, new Identifier.Serializer()).create(); + + @Test + void serialize() { + CustomArmorTrims.ArmorTrimId armorTrimId = new CustomArmorTrims.ArmorTrimId(new Identifier("material_id"), new Identifier("pattern_id")); + String json = gson.toJson(armorTrimId); + String expectedJson = "{\"material\":\"minecraft:material_id\",\"pattern\":\"minecraft:pattern_id\"}"; + Assertions.assertEquals(expectedJson, json); + } + + @Test + void deserialize() { + String json = "{\"material\":\"minecraft:material_id\",\"pattern\":\"minecraft:pattern_id\"}"; + CustomArmorTrims.ArmorTrimId armorTrimId = gson.fromJson(json, CustomArmorTrims.ArmorTrimId.class); + CustomArmorTrims.ArmorTrimId expectedArmorTrimId = new CustomArmorTrims.ArmorTrimId(new Identifier("material_id"), new Identifier("pattern_id")); + Assertions.assertEquals(expectedArmorTrimId, armorTrimId); + } +} diff --git a/src/test/java/de/hysky/skyblocker/utils/chat/ChatPatternListenerTest.java b/src/test/java/de/hysky/skyblocker/utils/chat/ChatPatternListenerTest.java new file mode 100644 index 00000000..8b670cbb --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/utils/chat/ChatPatternListenerTest.java @@ -0,0 +1,28 @@ +package de.hysky.skyblocker.utils.chat; + +import java.util.regex.Matcher; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public abstract class ChatPatternListenerTest<T extends ChatPatternListener> { + protected final T listener; + + public ChatPatternListenerTest(T listener) { + this.listener = listener; + } + + protected Matcher matcher(String message) { + return listener.pattern.matcher(message); + } + + protected void assertMatches(String message) { + assertTrue(matcher(message).matches()); + } + + protected void assertGroup(String message, int group, String expect) { + Matcher matcher = matcher(message); + assertTrue(matcher.matches()); + assertEquals(expect, matcher.group(group)); + } +}
\ No newline at end of file diff --git a/src/test/java/de/hysky/skyblocker/utils/scheduler/SchedulerTest.java b/src/test/java/de/hysky/skyblocker/utils/scheduler/SchedulerTest.java new file mode 100644 index 00000000..429273ac --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/utils/scheduler/SchedulerTest.java @@ -0,0 +1,88 @@ +package de.hysky.skyblocker.utils.scheduler; + +import org.apache.commons.lang3.mutable.MutableInt; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SchedulerTest { + private final MutableInt currentTick = new MutableInt(0); + private final MutableInt cycleCount1 = new MutableInt(0); + private final MutableInt cycleCount2 = new MutableInt(0); + private final MutableInt cycleCount3 = new MutableInt(0); + private final MutableInt cycleCount4 = new MutableInt(0); + private final MutableInt cycleCount5 = new MutableInt(0); + private final MutableInt cycleCount6 = new MutableInt(0); + private final MutableInt cycleCount7 = new MutableInt(0); + private final MutableInt cycleCount8 = new MutableInt(0); + + @Test + public void testSchedule() { + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(0, currentTick.intValue()), 0); + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(1, currentTick.intValue()), 1); + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(2, currentTick.intValue()), 2); + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(10, currentTick.intValue()), 10); + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(20, currentTick.intValue()), 20); + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(50, currentTick.intValue()), 50); + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(100, currentTick.intValue()), 100); + Scheduler.INSTANCE.schedule(() -> Assertions.assertEquals(123, currentTick.intValue()), 123); + Scheduler.INSTANCE.scheduleCyclic(() -> {}, 1); + Scheduler.INSTANCE.scheduleCyclic(() -> {}, 1); + Scheduler.INSTANCE.scheduleCyclic(() -> {}, 1); + Scheduler.INSTANCE.scheduleCyclic(() -> {}, 1); + Scheduler.INSTANCE.scheduleCyclic(() -> { + Assertions.assertEquals(cycleCount1.intValue(), currentTick.intValue()); + cycleCount1.increment(); + }, 1); + Scheduler.INSTANCE.scheduleCyclic(() -> { + Assertions.assertEquals(0, currentTick.intValue() % 10); + Assertions.assertEquals(cycleCount2.intValue(), currentTick.intValue() / 10); + cycleCount2.increment(); + }, 10); + Scheduler.INSTANCE.scheduleCyclic(() -> { + Assertions.assertEquals(0, currentTick.intValue() % 55); + Assertions.assertEquals(cycleCount3.intValue(), currentTick.intValue() / 55); + cycleCount3.increment(); + }, 55); + Scheduler.INSTANCE.schedule(() -> Scheduler.INSTANCE.scheduleCyclic(() -> { + Assertions.assertEquals(7, currentTick.intValue() % 10); + Assertions.assertEquals(cycleCount4.intValue(), currentTick.intValue() / 10); + cycleCount4.increment(); + }, 10), 7); + Scheduler.INSTANCE.schedule(() -> Scheduler.INSTANCE.scheduleCyclic(() -> { + Assertions.assertEquals(0, currentTick.intValue() % 75); + Assertions.assertEquals(cycleCount5.intValue(), currentTick.intValue() / 75); + cycleCount5.increment(); + }, 75), 0); + Scheduler.INSTANCE.schedule(() -> Scheduler.INSTANCE.scheduleCyclic(() -> { + Assertions.assertEquals(1, currentTick.intValue() % 99); + Assertions.assertEquals(cycleCount6.intValue(), currentTick.intValue() / 99); + cycleCount6.increment(); + }, 99), 1); + Scheduler.INSTANCE.scheduleCyclic(() -> Scheduler.INSTANCE.schedule(() -> { + Assertions.assertEquals(5, currentTick.intValue() % 10); + Assertions.assertEquals(cycleCount7.intValue(), currentTick.intValue() / 10); + cycleCount7.increment(); + }, 5), 10); + Scheduler.INSTANCE.scheduleCyclic(() -> Scheduler.INSTANCE.schedule(() -> { + Assertions.assertEquals(10, currentTick.intValue() % 55); + Assertions.assertEquals(cycleCount8.intValue(), currentTick.intValue() / 55); + cycleCount8.increment(); + }, 10), 55); + while (currentTick.intValue() < 100_000) { + tick(); + } + Assertions.assertEquals(100000, cycleCount1.intValue()); + Assertions.assertEquals(10000, cycleCount2.intValue()); + Assertions.assertEquals(1819, cycleCount3.intValue()); + Assertions.assertEquals(10000, cycleCount4.intValue()); + Assertions.assertEquals(1334, cycleCount5.intValue()); + Assertions.assertEquals(1011, cycleCount6.intValue()); + Assertions.assertEquals(10000, cycleCount7.intValue()); + Assertions.assertEquals(1818, cycleCount8.intValue()); + } + + private void tick() { + Scheduler.INSTANCE.tick(); + currentTick.increment(); + } +} |