1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

Added first Unit Tests

This commit is contained in:
TheBusyBiscuit 2020-05-04 16:25:47 +02:00
parent 3e2d1847ed
commit 0e58c3fa35
14 changed files with 342 additions and 32 deletions

View File

@ -19,6 +19,9 @@
## Release Candidate 12 (TBD)
#### Additions
* Added Unit Tests
#### Changes
* Little performance improvements
* Bandages, Rags and Splints will no longer be consumed if your health is full and you are not on fire

26
pom.xml
View File

@ -83,6 +83,12 @@
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
@ -212,6 +218,26 @@
<scope>provided</scope>
</dependency>
<!-- Development / Testing dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit</artifactId>
<version>v1.15-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<scope>test</scope>
</dependency>
<!-- Shaded packages -->
<dependency>
<groupId>com.github.thebusybiscuit</groupId>

View File

@ -12,6 +12,13 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin;
*/
public enum MinecraftVersion {
/**
* This is a very special state that represents the environment being a Unit
* Test and not an actual running Minecraft Server. This constant stands at
* the very top because it is the one with the least features.
*/
UNIT_TEST("Unit Test Environment"),
/**
* This constant represents Minecraft (Java Edition) Version 1.14
* (The Update Aquatic)

View File

@ -87,7 +87,7 @@ public final class SlimefunGuide {
if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) {
return;
}
Optional<PlayerProfile> optional = PlayerProfile.find(p);
if (optional.isPresent()) {

View File

@ -48,28 +48,34 @@ public class LocalizationService extends SlimefunLocalization implements Persist
this.plugin = plugin;
this.prefix = prefix;
translationsEnabled = SlimefunPlugin.getCfg().getBoolean("options.enable-translations");
languageKey = new NamespacedKey(plugin, LANGUAGE_PATH);
defaultLanguage = new Language(serverDefaultLanguage, "11b3188fd44902f72602bd7c2141f5a70673a411adb3d81862c69e536166b");
defaultLanguage.setMessages(getConfig().getConfiguration());
if (serverDefaultLanguage != null) {
translationsEnabled = SlimefunPlugin.getCfg().getBoolean("options.enable-translations");
defaultLanguage = new Language(serverDefaultLanguage, "11b3188fd44902f72602bd7c2141f5a70673a411adb3d81862c69e536166b");
defaultLanguage.setMessages(getConfig().getConfiguration());
loadEmbeddedLanguages();
loadEmbeddedLanguages();
String language = getConfig().getString(LANGUAGE_PATH);
if (language == null) language = serverDefaultLanguage;
String language = getConfig().getString(LANGUAGE_PATH);
if (language == null) language = serverDefaultLanguage;
if (hasLanguage(serverDefaultLanguage)) {
setLanguage(serverDefaultLanguage, !serverDefaultLanguage.equals(language));
if (hasLanguage(serverDefaultLanguage)) {
setLanguage(serverDefaultLanguage, !serverDefaultLanguage.equals(language));
}
else {
setLanguage("en", false);
plugin.getLogger().log(Level.WARNING, "Could not recognize the given language: \"{0}\"", serverDefaultLanguage);
}
Slimefun.getLogger().log(Level.INFO, "Available languages: {0}", String.join(", ", languages.keySet()));
save();
}
else {
setLanguage("en", false);
plugin.getLogger().log(Level.WARNING, "Could not recognize the given language: \"{0}\"", serverDefaultLanguage);
translationsEnabled = false;
defaultLanguage = null;
}
Slimefun.getLogger().log(Level.INFO, "Available languages: {0}", String.join(", ", languages.keySet()));
save();
}
/**

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.core.services.localization;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
@ -85,11 +86,13 @@ public abstract class SlimefunLocalization extends Localization implements Keyed
public String getMessage(Player p, String key) {
Language language = getLanguage(p);
if (language == null) return "NO LANGUAGE FOUND";
return language.getMessages().getString(key);
}
public List<String> getMessages(Player p, String key) {
Language language = getLanguage(p);
if (language == null) return Arrays.asList("NO LANGUAGE FOUND");
return language.getMessages().getStringList(key);
}

View File

@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import org.bukkit.block.BrewingStand;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
@ -37,7 +38,8 @@ public class VanillaMachinesListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onGrindstone(InventoryClickEvent e) {
// The Grindstone was only ever added in MC 1.14
if (!SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
MinecraftVersion minecraftVersion = SlimefunPlugin.getMinecraftVersion();
if (minecraftVersion != MinecraftVersion.UNIT_TEST && !minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
return;
}
@ -46,9 +48,10 @@ public class VanillaMachinesListener implements Listener {
ItemStack item2 = e.getInventory().getContents()[1];
if (checkForUnallowedItems(item1, item2)) {
e.setCancelled(true);
e.setResult(Result.DENY);
}
}
}
@EventHandler

View File

@ -36,7 +36,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.Research;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
@ -539,9 +538,18 @@ public class SlimefunItem implements Placeable {
}
// Support for legacy items
if (this instanceof ChargableItem && SlimefunUtils.isItemSimilar(item, this.item, false)) return true;
else if (this instanceof SlimefunBackpack && SlimefunUtils.isItemSimilar(item, this.item, false)) return true;
else return SlimefunUtils.isItemSimilar(item, this.item, true);
if (this instanceof ChargableItem && SlimefunUtils.isItemSimilar(item, this.item, false)) {
return true;
}
else if (this instanceof SlimefunBackpack && SlimefunUtils.isItemSimilar(item, this.item, false)) {
return true;
}
else if (id.equals("BROKEN_SPAWNER") || id.equals("REINFORCED_SPAWNER")) {
return SlimefunUtils.isItemSimilar(item, this.item, false);
}
else {
return SlimefunUtils.isItemSimilar(item, this.item, true);
}
}
/**
@ -794,14 +802,6 @@ public class SlimefunItem implements Placeable {
}
}
if (SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.BROKEN_SPAWNER, false)) {
return getByID("BROKEN_SPAWNER");
}
if (SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.REPAIRED_SPAWNER, false)) {
return getByID("REINFORCED_SPAWNER");
}
return null;
}

View File

@ -15,7 +15,9 @@ import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
@ -55,13 +57,13 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.DeathpointLis
import io.github.thebusybiscuit.slimefun4.implementation.listeners.DebugFishListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.DispenserListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.EnhancedFurnaceListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MobDropListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ExplosionsListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.FireworksListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.GadgetsListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.GrapplingHookListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.IronGolemListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MobDropListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener;
@ -103,6 +105,8 @@ import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
public static SlimefunPlugin instance;
private final boolean isTestEnvironment;
private MinecraftVersion minecraftVersion = MinecraftVersion.UNKNOWN;
private final SlimefunRegistry registry = new SlimefunRegistry();
@ -139,9 +143,24 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
private final BackpackListener backpackListener = new BackpackListener();
private final SlimefunBowListener bowListener = new SlimefunBowListener();
public SlimefunPlugin() {
super();
isTestEnvironment = false;
}
public SlimefunPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
super(loader, description, dataFolder, file);
isTestEnvironment = true;
}
@Override
public void onEnable() {
if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
if (isTestEnvironment) {
instance = this;
minecraftVersion = MinecraftVersion.UNIT_TEST;
local = new LocalizationService(this, "", null);
}
else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
long timestamp = System.nanoTime();
// We wanna ensure that the Server uses a compatible version of Minecraft
@ -339,7 +358,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
@Override
public void onDisable() {
// Slimefun never loaded successfully, so we don't even bother doing stuff here
if (instance == null) {
if (instance == null || isTestEnvironment) {
return;
}

View File

@ -0,0 +1,14 @@
package io.github.thebusybiscuit.slimefun4.mocks;
import org.bukkit.inventory.ItemStack;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
class MockSlimefunItem extends SlimefunItem {
public MockSlimefunItem(Category category, ItemStack item, String id) {
super(category, item, id, null, new ItemStack[9]);
}
}

View File

@ -0,0 +1,34 @@
package io.github.thebusybiscuit.slimefun4.mocks;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.mockito.Mockito;
import static org.mockito.Mockito.when;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
public final class SlimefunMocks {
private static final Category category = new Category(new NamespacedKey(SlimefunPlugin.instance, "test"), new ItemStack(Material.EMERALD));
private SlimefunMocks() {}
public static Inventory mockInventory(InventoryType type, ItemStack... contents) {
Inventory inv = Mockito.mock(Inventory.class);
when(inv.getType()).thenReturn(type);
when(inv.getContents()).thenReturn(contents);
return inv;
}
public static SlimefunItem mockSlimefunItem(String id, ItemStack item) {
return new MockSlimefunItem(category, item, id);
}
}

View File

@ -0,0 +1,53 @@
package io.github.thebusybiscuit.slimefun4.tests.items;
import org.bukkit.Material;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.mocks.SlimefunMocks;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.ItemState;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
public class TestSlimefunItemRegistration {
private static ServerMock server;
private static SlimefunPlugin plugin;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
public void testSuccessfulRegistration() {
SlimefunItem item = SlimefunMocks.mockSlimefunItem("TEST_ITEM", new CustomItem(Material.DIAMOND, "&cTest"));
item.register(plugin);
Assertions.assertEquals(ItemState.ENABLED, item.getState());
}
@Test
public void testIdConflict() {
SlimefunItem item = SlimefunMocks.mockSlimefunItem("DUPLICATE_ID", new CustomItem(Material.DIAMOND, "&cTest"));
item.register(plugin);
SlimefunItem item2 = SlimefunMocks.mockSlimefunItem("DUPLICATE_ID", new CustomItem(Material.DIAMOND, "&cTest"));
item2.register(plugin);
Assertions.assertEquals(ItemState.ENABLED, item.getState());
Assertions.assertEquals(ItemState.UNREGISTERED, item2.getState());
}
}

View File

@ -0,0 +1,87 @@
package io.github.thebusybiscuit.slimefun4.tests.listeners;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.IronGolemListener;
import io.github.thebusybiscuit.slimefun4.mocks.SlimefunMocks;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
public class TestIronGolemListener {
private static SlimefunPlugin plugin;
private static IronGolemListener listener;
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
listener = new IronGolemListener(plugin);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
private PlayerInteractEntityEvent callIronGolemEvent(EquipmentSlot hand, ItemStack itemInHand) {
// Fake Player with an Iron Ingot
Player player = server.addPlayer();
if (hand == EquipmentSlot.HAND) {
player.getInventory().setItemInMainHand(itemInHand);
}
else {
player.getInventory().setItemInOffHand(itemInHand);
}
// Fake Iron Golem
IronGolem golem = Mockito.mock(IronGolem.class);
Mockito.when(golem.getType()).thenReturn(EntityType.IRON_GOLEM);
// Fake Event
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, golem, hand);
listener.onIronGolemHeal(event);
return event;
}
@Test
public void testWithIron() {
// This should heal the Iron Golem
ItemStack item = new ItemStack(Material.IRON_INGOT);
PlayerInteractEntityEvent event = callIronGolemEvent(EquipmentSlot.HAND, item);
Assertions.assertFalse(event.isCancelled());
PlayerInteractEntityEvent event2 = callIronGolemEvent(EquipmentSlot.OFF_HAND, item);
Assertions.assertFalse(event2.isCancelled());
}
@Test
public void testWithSlimefunIron() {
SlimefunItem slimefunItem = SlimefunMocks.mockSlimefunItem("SLIMEFUN_IRON", new CustomItem(Material.IRON_INGOT, "&cSlimefun Iron"));
slimefunItem.register(plugin);
// The Event should be cancelled, we do not wanna use Slimefun Items for this
PlayerInteractEntityEvent event = callIronGolemEvent(EquipmentSlot.HAND, slimefunItem.getItem());
Assertions.assertTrue(event.isCancelled());
PlayerInteractEntityEvent event2 = callIronGolemEvent(EquipmentSlot.OFF_HAND, slimefunItem.getItem());
Assertions.assertTrue(event2.isCancelled());
}
}

View File

@ -0,0 +1,55 @@
package io.github.thebusybiscuit.slimefun4.tests.listeners;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.inventory.meta.EnchantedBookMetaMock;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VanillaMachinesListener;
import io.github.thebusybiscuit.slimefun4.mocks.SlimefunMocks;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
public class TestVanillaMachinesListener {
private static SlimefunPlugin plugin;
private static VanillaMachinesListener listener;
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
listener = new VanillaMachinesListener(plugin);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
public void testGrindStoneWithoutSlimefunItems() {
Player player = server.addPlayer();
Inventory inv = SlimefunMocks.mockInventory(InventoryType.GRINDSTONE, new ItemStack(Material.ENCHANTED_BOOK), null);
InventoryView view = player.openInventory(inv);
InventoryClickEvent event = new InventoryClickEvent(view, SlotType.CONTAINER, 2, ClickType.LEFT, InventoryAction.PICKUP_ONE);
listener.onGrindstone(event);
Assertions.assertEquals(Result.DEFAULT, event.getResult());
}
}