Add some testing (#38)

This commit is contained in:
alexcrea 2024-11-18 07:29:51 +01:00 committed by GitHub
parent c42140a45a
commit ed58c9c107
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 1911 additions and 150 deletions

View file

@ -0,0 +1,18 @@
package io.delilaheve;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import xyz.alexcrea.cuanvil.tests.DefaultCustomAnvilTest;
public class CustomAnvilTests extends DefaultCustomAnvilTest {
@Test
public void simpleInitTest() {
Assertions.assertNotNull(server);
Assertions.assertNotNull(plugin);
// Test shutdown
plugin.onDisable();
}
}

View file

@ -0,0 +1,184 @@
package io.delilaheve.util;
import io.delilaheve.CustomAnvil;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachment;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockbukkit.mockbukkit.entity.PlayerMock;
import org.mockbukkit.mockbukkit.inventory.ItemStackMock;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestData;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil;
import java.util.List;
public class EnchantmentUtilTests extends ConfigResetCustomAnvilTest {
private AnvilInventory anvil;
private PlayerMock player;
@Override
@BeforeEach
public void setUp() {
super.setUp();
// Mock used player & open anvil
player = server.addPlayer();
Inventory anvil = server.createInventory(player, InventoryType.ANVIL);
this.anvil = (AnvilInventory) anvil;
player.openInventory(anvil);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log", true);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log_verbose", true);
}
@Test
public void testBypassFuse(){
// Test permission did not changed (if it do then server owner should be warned)
String permission = CustomAnvil.bypassFusePermission;
Assertions.assertEquals("ca.bypass.fuse", permission, "bypass fuse permission changed. " +
"Caution with that as it will break some server CustomAnvil setup.");
// Create ingredient item
ItemStack normalStick = new ItemStackMock(Material.STICK);
ItemStack sharpnessBook = AnvilFuseTestUtil.prepareItem(
Material.ENCHANTED_BOOK,
List.of("sharpness"), 1);
ItemStack sharpnessStick = AnvilFuseTestUtil.prepareItem(
Material.STICK,
List.of("sharpness"), 1);
// Create result item
ItemStack sharpnessResultStick = AnvilFuseTestUtil.prepareItem(
Material.STICK, 1,
List.of("sharpness"), 1);
ItemStack sharpness2ResultStick = AnvilFuseTestUtil.prepareItem(
Material.STICK, 1,
List.of("sharpness"), 2);
// Create failing anvil fuse data
AnvilFuseTestData nullResultData = new AnvilFuseTestData(
normalStick, sharpnessBook,
null
);
AnvilFuseTestData nullResultData2 = new AnvilFuseTestData(
sharpnessStick, sharpnessStick,
null
);
// Create successful anvil fuse data
AnvilFuseTestData legalResultData = new AnvilFuseTestData(
normalStick, sharpnessBook,
sharpnessResultStick
// TODO add expected price
);
AnvilFuseTestData legalResultData2 = new AnvilFuseTestData(
sharpnessStick, sharpnessStick,
sharpness2ResultStick
// TODO add expected price
);
// Test with no permission
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData2);
// Add permission
PermissionAttachment attachment = player.addAttachment(plugin);
attachment.setPermission(permission, true);
// Test with new permission
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData2);
}
@Test
public void testLeveLimitFuse(){
String permission = CustomAnvil.bypassLevelPermission;
Assertions.assertEquals("ca.bypass.level", permission, "level fuse permission changed. " +
"Caution with that as it will break some server CustomAnvil setup.");
// Create ingredient item
ItemStack sharpness5Sword = AnvilFuseTestUtil.prepareItem(
Material.DIAMOND_SWORD,
List.of("sharpness"), 5);
ItemStack sharpnessBook = AnvilFuseTestUtil.prepareItem(
Material.ENCHANTED_BOOK,
List.of("sharpness"), 1);
ItemStack sharpness5Book = AnvilFuseTestUtil.prepareItem(
Material.ENCHANTED_BOOK,
List.of("sharpness"), 5);
ItemStack sharpness6Book = AnvilFuseTestUtil.prepareItem(
Material.ENCHANTED_BOOK,
List.of("sharpness"), 6);
// Create result item
ItemStack sharpness2BookResult = AnvilFuseTestUtil.prepareItem(
Material.ENCHANTED_BOOK, 1,
List.of("sharpness"), 2);
ItemStack sharpness6SwordResult = AnvilFuseTestUtil.prepareItem(
Material.DIAMOND_SWORD, 1,
List.of("sharpness"), 6);
// Create failing anvil fuse data
AnvilFuseTestData nullResultData = new AnvilFuseTestData(
sharpnessBook, sharpnessBook,
null
);
AnvilFuseTestData nullResultData2 = new AnvilFuseTestData(
sharpness5Sword, sharpness6Book,
null
);
AnvilFuseTestData nullResultData3 = new AnvilFuseTestData(
sharpness5Sword, sharpness5Book,
null
);
// Create successful anvil fuse data
AnvilFuseTestData legalResultData = new AnvilFuseTestData(
sharpnessBook, sharpnessBook,
sharpness2BookResult
// TODO add expected price
);
AnvilFuseTestData legalResultData2 = new AnvilFuseTestData(
sharpness5Sword, sharpness6Book,
sharpness6SwordResult
// TODO add expected price
);
AnvilFuseTestData legalResultData3 = new AnvilFuseTestData(
sharpness5Sword, sharpness5Book,
sharpness6SwordResult
// TODO add expected price
);
// Test failing result first
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData2);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData3);
// Test working sharpness 2
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
// Set merge limit to 2 & test
ConfigHolder.DEFAULT_CONFIG.getConfig().set("disable-merge-over.minecraft:sharpness", 1);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
// Add permission
PermissionAttachment attachment = player.addAttachment(plugin);
attachment.setPermission(permission, true);
// Test working sharpness 2
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData2);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData3);
}
}

View file

@ -0,0 +1,92 @@
package xyz.alexcrea.cuanvil.anvil;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockbukkit.mockbukkit.entity.PlayerMock;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.tests.SharedCustomAnvilTest;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestData;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil;
import xyz.alexcrea.cuanvil.util.CommonItemUtil;
public class AnvilFuseTests extends SharedCustomAnvilTest {
private static AnvilInventory anvil;
private static PlayerMock player;
@BeforeAll
public static void setUp() {
// Mock used player & open anvil
player = server.addPlayer();
Inventory anvil = server.createInventory(player, InventoryType.ANVIL);
AnvilFuseTests.anvil = (AnvilInventory) anvil;
player.openInventory(anvil);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log", true);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log_verbose", true);
}
@BeforeEach
public void prepareAnvil(){
anvil.clear();
}
@AfterAll
public static void tearDown() {
player = null;
anvil = null;
}
@Test
public void mergeFuseTest(){
// Literally just test a sharpness 4 + sharpness 4
ItemStack sharpness4 = CommonItemUtil.sharpness(4);
ItemStack sharpness5 = CommonItemUtil.sharpness(5);
AnvilFuseTestData data = new AnvilFuseTestData(
sharpness4, sharpness4,
sharpness5
// TODO add expected price
);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, data);
}
@Test
public void overFuseTest(){
// Test sharpness 4 + sharpness 5
ItemStack sharpness4 = CommonItemUtil.sharpness(4);
ItemStack sharpness5 = CommonItemUtil.sharpness(5);
AnvilFuseTestData data = new AnvilFuseTestData(
sharpness4, sharpness5,
sharpness5
// TODO add expected price
);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, data);
}
@Test
public void underFuseTest(){
// test sharpness 5 + 4. Custom Anvil should not allow it to be as it result as the same item as left item
ItemStack sharpness4 = CommonItemUtil.sharpness(4);
ItemStack sharpness5 = CommonItemUtil.sharpness(5);
AnvilFuseTestData data = new AnvilFuseTestData(
sharpness5, sharpness4,
null
);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, data);
}
}

View file

@ -0,0 +1,85 @@
package xyz.alexcrea.cuanvil.api;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import xyz.alexcrea.cuanvil.tests.SharedOnlyMockBukkit;
import static org.junit.jupiter.api.Assertions.*;
public class AnvilRecipeBuilderTest extends SharedOnlyMockBukkit {
private AnvilRecipeBuilder builder;
@BeforeEach
public void setup() {
builder = new AnvilRecipeBuilder("test");
}
@Test
void createBuilder_NoLeftItem(){
builder.setResultItem(new ItemStack(Material.STICK));
assertNull(builder.build());
}
@Test
void createBuilder_NoResultItem(){
builder.setLeftItem(new ItemStack(Material.STICK));
assertNull(builder.build());
}
@Test
void createBuilder_minimalist(){
builder.setLeftItem(new ItemStack(Material.STICK))
.setResultItem(new ItemStack(Material.STICK));
assertNotNull(builder.build());
}
@Test
void setLeftItem(){
assertNull(builder.getLeftItem());
builder.setLeftItem(new ItemStack(Material.STICK));
assertNotNull(builder.getLeftItem());
}
@Test
void setRightItem(){
assertNull(builder.getRightItem());
builder.setRightItem(new ItemStack(Material.STICK));
assertNotNull(builder.getRightItem());
}
@Test
void setResultItem(){
assertNull(builder.getResultItem());
builder.setResultItem(new ItemStack(Material.STICK));
assertNotNull(builder.getResultItem());
}
@Test
void setXpCostPerCraft(){
assertEquals(1, builder.getXpCostPerCraft());
builder.setXpCostPerCraft(2);
assertEquals(2, builder.getXpCostPerCraft());
}
@Test
void setExactCount(){
assertTrue(builder.isExactCount());
builder.setExactCount(false);
assertFalse(builder.isExactCount());
}
@Test
void setName(){
assertEquals("test", builder.getName());
builder.setName("other");
assertEquals("other", builder.getName());
}
}

View file

@ -0,0 +1,161 @@
package xyz.alexcrea.cuanvil.api;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockbukkit.mockbukkit.entity.PlayerMock;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestData;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil;
import xyz.alexcrea.cuanvil.util.CommonItemUtil;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ConflictApiTests extends ConfigResetCustomAnvilTest {
private AnvilInventory anvil;
private PlayerMock player;
@Override
@BeforeEach
public void setUp() {
super.setUp();
// Mock used player & open anvil
player = server.addPlayer();
Inventory anvil = server.createInventory(player, InventoryType.ANVIL);
this.anvil = (AnvilInventory) anvil;
player.openInventory(anvil);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log", true);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log_verbose", true);
}
@Test
public void testConflict() {
ItemStack sharpness1 = CommonItemUtil.sharpness(1);
ItemStack arthropods1 = CommonItemUtil.bane_of_arthropods(1);
ItemStack illegalResult = AnvilFuseTestUtil.prepareItem(
Material.DIAMOND_SWORD,
List.of("bane_of_arthropods", "sharpness"),
1, 1
);
AnvilFuseTestData nullResultData = new AnvilFuseTestData(
sharpness1, arthropods1,
null
);
AnvilFuseTestData legalResultData = new AnvilFuseTestData(
sharpness1, arthropods1,
illegalResult,
// TODO add expected price
null
);
CAEnchantment sharpness = EnchantmentApi.getByKey(Enchantment.SHARPNESS.getKey());
Assertions.assertNotNull(sharpness);
// Testing default conflict (illegal item should not be produced)
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
// Try to find & remove conflict
EnchantConflictGroup conflict = findGroup("sword_enchant_conflict");
Assertions.assertNotNull(conflict, "Could not find conflict.");
// Test what happen when we remove the conflict (illegal item should be allowed)
ConflictAPI.removeConflict(conflict);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
// We create and add a new conflict
ConflictBuilder builder = new ConflictBuilder("sword_enchant_conflict");
builder.addEnchantment("bane_of_arthropods").addEnchantment(sharpness); //TODO maybe add "add by bukkit enchantment"
builder.setMaxBeforeConflict(1);
// Nothing should change as it is not new: it was previously deleted
Assertions.assertFalse(builder.registerIfNew());
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
// Now the conflict should be registered and conflict should exist
Assertions.assertTrue(builder.registerIfAbsent());
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
}
@Test
void writeGroup_Reload() {
String conflictName = "conflict";
ConflictBuilder builder = new ConflictBuilder(conflictName);
builder.addEnchantment("bane_of_arthropods");
// Group not being set should not exist
assertFalse(doGroupExist(conflictName));
// Add group and reload
assertTrue(ConflictAPI.writeConflict(builder));
assertFalse(doGroupExist(conflictName));
// Tick so write get reloaded
server.getScheduler().performOneTick();
assertTrue(doGroupExist(conflictName));
}
@Test
void writeGroup_Empty() {
String conflictName = "conflict";
ConflictBuilder builder = new ConflictBuilder(conflictName);
// Group not being set should not exist
assertFalse(doGroupExist(conflictName));
// Add group and reload
assertFalse(ConflictAPI.writeConflict(builder));
assertFalse(doGroupExist(conflictName));
// Tick so write get reloaded
server.getScheduler().performOneTick();
assertFalse(doGroupExist(conflictName));
}
@Test
void writeGroup_InvalidDot() {
String conflictName = "conflict.conflict";
ConflictBuilder builder = new ConflictBuilder(conflictName);
// Try write group
assertFalse(ConflictAPI.writeConflict(builder));
}
// Maybe move to ConflictApi class ?
private static boolean doGroupExist(@NotNull String groupName) {
return findGroup(groupName) != null;
}
// Maybe move to ConflictApi class ?
@Nullable
private static EnchantConflictGroup findGroup(@NotNull String groupName) {
for (EnchantConflictGroup enchantConflictGroup : ConflictAPI.getRegisteredConflict()) {
if (groupName.equalsIgnoreCase(enchantConflictGroup.getName())) {
return enchantConflictGroup;
}
}
return null;
}
}

View file

@ -0,0 +1,115 @@
package xyz.alexcrea.cuanvil.api;
import org.bukkit.NamespacedKey;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import xyz.alexcrea.cuanvil.group.IncludeGroup;
import xyz.alexcrea.cuanvil.tests.SharedOnlyMockBukkit;
import static org.junit.jupiter.api.Assertions.*;
public class ConflictBuilderTests extends SharedOnlyMockBukkit {
private ConflictBuilder builder;
@BeforeEach
public void setup() {
builder = new ConflictBuilder("test");
}
@Test
void testDefaults() {
assertNull(builder.getSource());
assertEquals("an unknown source", builder.getSourceName());
assertEquals("test", builder.getName());
assertTrue(builder.getEnchantmentNames().isEmpty());
assertTrue(builder.getEnchantmentKeys().isEmpty());
assertTrue(builder.getExcludedGroupNames().isEmpty());
assertEquals(0, builder.getMaxBeforeConflict());
}
@Test
void setName() {
assertEquals("test", builder.getName());
assertEquals(builder, builder.setName("another"));
assertEquals("another", builder.getName());
}
@Test
void setMaxBeforeConflict() {
assertEquals(0, builder.getMaxBeforeConflict());
assertEquals(builder, builder.setMaxBeforeConflict(1));
assertEquals(1, builder.getMaxBeforeConflict());
}
@Test
void enchantmentString() {
assertTrue(builder.getEnchantmentNames().isEmpty());
assertEquals(builder, builder.addEnchantment("bane_of_arthropods"));
assertEquals(1, builder.getEnchantmentNames().size());
assertEquals(builder, builder.removeEnchantment("bane_of_arthropods"));
assertTrue(builder.getEnchantmentNames().isEmpty());
}
@Test
void enchantmentKey() {
NamespacedKey key = NamespacedKey.fromString("bane_of_arthropods");
assertNotNull(key);
assertTrue(builder.getEnchantmentKeys().isEmpty());
assertEquals(builder, builder.addEnchantment(key));
assertEquals(1, builder.getEnchantmentKeys().size());
assertEquals(builder, builder.removeEnchantment(key));
assertTrue(builder.getEnchantmentKeys().isEmpty());
}
@Test
void excludedGroup_String() {
assertTrue(builder.getExcludedGroupNames().isEmpty());
assertEquals(builder, builder.addExcludedGroup("group"));
assertEquals(1, builder.getExcludedGroupNames().size());
assertEquals(builder, builder.removeExcludedGroup("group"));
assertTrue(builder.getExcludedGroupNames().isEmpty());
}
@Test
void excludedGroup_Group() {
IncludeGroup group = new IncludeGroup("group");
assertTrue(builder.getExcludedGroupNames().isEmpty());
assertEquals(builder, builder.addExcludedGroup(group));
assertEquals(1, builder.getExcludedGroupNames().size());
assertEquals(builder, builder.removeExcludedGroup(group));
assertTrue(builder.getExcludedGroupNames().isEmpty());
}
@Test
void copy(){
builder.setName("other");
builder.setMaxBeforeConflict(1);
builder.addEnchantment("bane_of_arthropods");
builder.addEnchantment(NamespacedKey.fromString("bane_of_arthropods"));
builder.addExcludedGroup("group");
builder.addExcludedGroup(new IncludeGroup("group2"));
ConflictBuilder copy = builder.copy();
assertEquals("other", copy.getName());
assertEquals(1, copy.getMaxBeforeConflict());
assertEquals(1, copy.getEnchantmentNames().size());
assertEquals("bane_of_arthropods", copy.getEnchantmentNames().stream().findFirst().orElse(null));
assertEquals(1, copy.getEnchantmentKeys().size());
assertEquals(NamespacedKey.fromString("bane_of_arthropods"), copy.getEnchantmentKeys().stream().findFirst().orElse(null));
assertEquals(2, copy.getExcludedGroupNames().size());
}
}

View file

@ -0,0 +1,151 @@
package xyz.alexcrea.cuanvil.api;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockbukkit.mockbukkit.entity.PlayerMock;
import org.mockbukkit.mockbukkit.inventory.ItemStackMock;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestData;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil;
import static org.junit.jupiter.api.Assertions.*;
public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest {
private AnvilInventory anvil;
private PlayerMock player;
@Override
@BeforeEach
public void setUp() {
super.setUp();
// Mock used player & open anvil
player = server.addPlayer();
Inventory anvil = server.createInventory(player, InventoryType.ANVIL);
this.anvil = (AnvilInventory) anvil;
player.openInventory(anvil);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log", true);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log_verbose", true);
}
@Test
public void testBasicRecipe() {
String recipeName = "stick_recipe";
ItemStack stick = new ItemStackMock(Material.STICK);
AnvilFuseTestData nullResultData = new AnvilFuseTestData(
stick, stick,
null
);
AnvilFuseTestData legalResultData = new AnvilFuseTestData(
stick, stick,
null, stick, null,
// TODO add expected price
null,
null, null
);
// Testing default conflict (no recipe exist)
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
// Add and test recipe
AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName);
builder.setExactCount(true).setLeftItem(stick).setResultItem(stick).setXpCostPerCraft(2);
assertTrue(builder.registerIfAbsent());
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
AnvilCustomRecipe recipe = getByName(recipeName);
assertNotNull(recipe);
// Remove recipe
assertTrue(CustomAnvilRecipeApi.removeRecipe(recipe));
assertFalse(CustomAnvilRecipeApi.removeRecipe(recipe));
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
recipe = getByName(recipeName);
assertNull(recipe);
// Try to add deleted recipe with no override (should not add)
assertFalse(CustomAnvilRecipeApi.addRecipe(builder, false));
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
recipe = getByName(recipeName);
assertNull(recipe);
// Try to add deleted recipe with override (should add)
assertTrue(CustomAnvilRecipeApi.addRecipe(builder, true));
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
recipe = getByName(recipeName);
assertNotNull(recipe);
}
@Test
public void testUnitRecipe() {
String recipeName = "stick_recipe";
ItemStack stick = new ItemStackMock(Material.STICK);
ItemStack stick2 = new ItemStackMock(Material.STICK, 2);
ItemStack stick5 = new ItemStackMock(Material.STICK, 5);
ItemStack stick10 = new ItemStackMock(Material.STICK, 10);
AnvilFuseTestData nullResultData = new AnvilFuseTestData(
stick, stick,
null
);
AnvilFuseTestData legalResultData1 = new AnvilFuseTestData(
stick, stick,
null, stick2, null,
// TODO add expected price
null,
null, null
);
AnvilFuseTestData legalResultData2 = new AnvilFuseTestData(
stick5, stick,
null, stick10, null,
// TODO add expected price
null,
null, null
);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName);
builder.setExactCount(false)
.setLeftItem(stick)
.setResultItem(stick2)
.setXpCostPerCraft(2);
assertTrue(builder.registerIfAbsent());
// Now working test
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData1);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData2);
}
@Nullable
public static AnvilCustomRecipe getByName(String name){
for (AnvilCustomRecipe registeredRecipe : CustomAnvilRecipeApi.getRegisteredRecipes()) {
if(registeredRecipe.getName().contentEquals(name)){
return registeredRecipe;
}
}
return null;
}
}

View file

@ -0,0 +1,108 @@
package xyz.alexcrea.cuanvil.api;
import org.bukkit.Material;
import org.junit.jupiter.api.Test;
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
import xyz.alexcrea.cuanvil.group.IncludeGroup;
import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class MaterialGroupApiTests extends ConfigResetCustomAnvilTest {
@Test
void groupAddAndRemove() {
String groupName = "group";
IncludeGroup group = new IncludeGroup(groupName);
group.addToPolicy(Material.DIAMOND_PICKAXE); // We do not want it to be empty
// Group not being set should not exist
assertFalse(doGroupExist(groupName));
assertFalse(doGroupCanBeFound(groupName));
// Add group
assertTrue(MaterialGroupApi.addMaterialGroup(group));
assertFalse(MaterialGroupApi.addMaterialGroup(group, true));
assertTrue(doGroupExist(groupName));
assertTrue(doGroupCanBeFound(groupName));
// Remove group
assertTrue(MaterialGroupApi.removeGroup(group));
assertFalse(MaterialGroupApi.removeGroup(group));
assertFalse(doGroupExist(groupName));
assertFalse(doGroupCanBeFound(groupName));
// Re add
assertFalse(MaterialGroupApi.addMaterialGroup(group, false));
assertTrue(MaterialGroupApi.addMaterialGroup(group, true));
assertTrue(doGroupExist(groupName));
assertTrue(doGroupCanBeFound(groupName));
}
@Test
void writeGroup_Reload() {
String groupName = "group";
IncludeGroup group = new IncludeGroup(groupName);
group.addToPolicy(Material.DIAMOND_PICKAXE); // We do not want it to be empty
// Group not being set should not exist
assertFalse(doGroupExist(groupName));
assertFalse(doGroupCanBeFound(groupName));
// Add group and reload
assertTrue(MaterialGroupApi.writeMaterialGroup(group));
assertFalse(doGroupExist(groupName));
assertFalse(doGroupCanBeFound(groupName));
// Tick so write get reloaded
server.getScheduler().performOneTick();
assertTrue(doGroupExist(groupName));
assertTrue(doGroupCanBeFound(groupName));
}
@Test
void writeGroup_Empty() {
String groupName = "group";
IncludeGroup group = new IncludeGroup(groupName);
// Add group and reload
assertFalse(MaterialGroupApi.writeMaterialGroup(group));
assertFalse(doGroupExist(groupName));
assertFalse(doGroupCanBeFound(groupName));
// Tick so write get reloaded
server.getScheduler().performOneTick();
assertFalse(doGroupExist(groupName));
assertFalse(doGroupCanBeFound(groupName));
}
@Test
void writeGroup_InvalidDot() {
String groupName = "group.group";
IncludeGroup group = new IncludeGroup(groupName);
// Try write group
assertFalse(MaterialGroupApi.writeMaterialGroup(group));
}
boolean doGroupExist(String groupName) {
return MaterialGroupApi.getGroup(groupName) != null;
}
boolean doGroupCanBeFound(String groupName) {
ConflictBuilder builder = new ConflictBuilder(groupName);
builder.addExcludedGroup(groupName);
EnchantConflictGroup group = builder.build();
IncludeGroup materialGroup = (IncludeGroup) group.getCantConflictGroup();
return materialGroup.getGroups().size() == 1;
}
}

View file

@ -0,0 +1,118 @@
package xyz.alexcrea.cuanvil.api;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.Repairable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockbukkit.mockbukkit.entity.PlayerMock;
import org.mockbukkit.mockbukkit.inventory.ItemStackMock;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestData;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil;
import static org.junit.jupiter.api.Assertions.*;
public class UnitRepairApiTests extends ConfigResetCustomAnvilTest {
private AnvilInventory anvil;
private PlayerMock player;
@Override
@BeforeEach
public void setUp() {
super.setUp();
// Mock used player & open anvil
player = server.addPlayer();
Inventory anvil = server.createInventory(player, InventoryType.ANVIL);
this.anvil = (AnvilInventory) anvil;
player.openInventory(anvil);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log", true);
ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log_verbose", true);
}
@Test
void vanillaUnitRepair(){
ItemStack damagedPickaxe = new ItemStackMock(Material.DIAMOND_PICKAXE);
damagedPickaxe.setDurability((short) (Material.DIAMOND_PICKAXE.getMaxDurability() -1));
ItemStack resultPickaxe = new ItemStackMock(Material.DIAMOND_PICKAXE);
resultPickaxe.setDurability((short) (Material.DIAMOND_PICKAXE.getMaxDurability()/2));
ItemMeta meta = resultPickaxe.getItemMeta();
((Repairable) meta).setRepairCost(1);
ItemStack diamond2 = new ItemStackMock(Material.DIAMOND, 2);
AnvilFuseTestData legalResultData = new AnvilFuseTestData(
damagedPickaxe, diamond2,
resultPickaxe,
// TODO add expected price
null
);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
}
@Test
void removeUnitRepair(){
ItemStack damagedPickaxe = new ItemStackMock(Material.DIAMOND_PICKAXE);
damagedPickaxe.setDurability((short) (Material.DIAMOND_PICKAXE.getMaxDurability() -1));
ItemStack diamond2 = new ItemStackMock(Material.DIAMOND, 2);
AnvilFuseTestData nullResultData = new AnvilFuseTestData(
damagedPickaxe, diamond2,
null
);
// Remove unit repair
assertTrue(UnitRepairApi.removeUnitRepair(Material.DIAMOND, Material.DIAMOND_PICKAXE));
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
// see override
assertFalse(UnitRepairApi.addUnitRepair(Material.DIAMOND, Material.DIAMOND_PICKAXE, 0.25));
assertTrue(UnitRepairApi.addUnitRepair(Material.DIAMOND, Material.DIAMOND_PICKAXE, 0.25, true));
}
@Test
void addUnitRepair(){
ItemStack damagedPickaxe = new ItemStackMock(Material.DIAMOND_PICKAXE);
damagedPickaxe.setDurability((short) (Material.DIAMOND_PICKAXE.getMaxDurability() -1));
ItemStack resultPickaxe = new ItemStackMock(Material.DIAMOND_PICKAXE);
resultPickaxe.setDurability((short) (Material.DIAMOND_PICKAXE.getMaxDurability()/2));
ItemMeta meta = resultPickaxe.getItemMeta();
((Repairable) meta).setRepairCost(1);
ItemStack stick2 = new ItemStackMock(Material.STICK, 2);
AnvilFuseTestData nullResultData = new AnvilFuseTestData(
damagedPickaxe, stick2,
null
);
AnvilFuseTestData legalResultData = new AnvilFuseTestData(
damagedPickaxe, stick2,
resultPickaxe,
// TODO add expected price
null
);
AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData);
// Add unit repair
assertTrue(UnitRepairApi.addUnitRepair(Material.STICK, Material.DIAMOND_PICKAXE));
assertFalse(UnitRepairApi.addUnitRepair(Material.STICK, Material.DIAMOND_PICKAXE));
AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData);
}
}

View file

@ -0,0 +1,89 @@
package xyz.alexcrea.cuanvil.config;
import io.delilaheve.util.ConfigOptions;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
import xyz.alexcrea.cuanvil.tests.SharedCustomAnvilTest;
import java.util.stream.Stream;
public class DefaultConfigTests extends SharedCustomAnvilTest {
@ParameterizedTest
@MethodSource("provideStringsForIsConfiguredValueValid")
public void isConfiguredValueValid(String path, Object value){
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig();
Assertions.assertEquals(value.toString(), config.getString(path), "Default value is not the same as in the config file");
}
@ParameterizedTest
@MethodSource("provideForEnchantmentsTests")
public void testDefaultEnchantLimit(NamespacedKey key){
CAEnchantment enchantment = CAEnchantmentRegistry.getInstance().getByKey(key);
Assertions.assertNotNull(enchantment, "Enchantment was somehow not found");
int levelLimit = ConfigOptions.INSTANCE.enchantLimit(enchantment);
int mergeLimit = ConfigOptions.INSTANCE.maxBeforeMergeDisabled(enchantment);
Assertions.assertEquals(enchantment.defaultMaxLevel(), levelLimit,"Default enchantment limit is not the same as expected limit ");
if(mergeLimit >= 0) { // negative mean default
Assertions.assertEquals(enchantment.defaultMaxLevel(), mergeLimit,"Default enchantment merge limit is not the same as expected limit ");
}
}
@ParameterizedTest
@MethodSource("provideForEnchantmentsTests")
public void testDefaultEnchantValues(NamespacedKey key){
CAEnchantment enchantment = CAEnchantmentRegistry.getInstance().getByKey(key);
Assertions.assertNotNull(enchantment, "Enchantment was somehow not found");
int itemValue = ConfigOptions.INSTANCE.enchantmentValue(enchantment, false);
int bookValue = ConfigOptions.INSTANCE.enchantmentValue(enchantment, true);
EnchantmentRarity rarity = enchantment.defaultRarity();
Assertions.assertEquals(rarity.getItemValue(), itemValue,"Default enchantment item value is not the same as expected value");
Assertions.assertEquals(rarity.getBookValue(), bookValue,"Default enchantment book value is not the same as expected value");
}
private static Stream<Arguments> provideStringsForIsConfiguredValueValid() {
return Stream.of(
// Default options
Arguments.of(ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST),
Arguments.of(ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST),
Arguments.of(ConfigOptions.MAX_ANVIL_COST, ConfigOptions.DEFAULT_MAX_ANVIL_COST),
Arguments.of(ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT),
Arguments.of(ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE),
Arguments.of(ConfigOptions.ITEM_REPAIR_COST, ConfigOptions.DEFAULT_ITEM_REPAIR_COST),
Arguments.of(ConfigOptions.UNIT_REPAIR_COST, ConfigOptions.DEFAULT_UNIT_REPAIR_COST),
Arguments.of(ConfigOptions.ITEM_RENAME_COST, ConfigOptions.DEFAULT_ITEM_RENAME_COST),
Arguments.of(ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST),
// Color options
Arguments.of(ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE),
Arguments.of(ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR),
Arguments.of(ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR),
Arguments.of(ConfigOptions.USE_OF_COLOR_COST, ConfigOptions.DEFAULT_USE_OF_COLOR_COST)
);
}
// Test every enchantment defaults
private static Stream<Arguments> provideForEnchantmentsTests() {
return RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT)
.stream().map(enchantment -> Arguments.of(enchantment.getKey()));
}
}

View file

@ -0,0 +1,76 @@
package xyz.alexcrea.cuanvil.mock;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.view.AnvilView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mockbukkit.mockbukkit.inventory.PlayerInventoryViewMock;
@SuppressWarnings({"removal"})
public class AnvilViewMock extends PlayerInventoryViewMock implements AnvilView {
private @NotNull AnvilInventory top;
/**
* Constructs a new {@link PlayerInventoryViewMock} for the provided player, with the specified top inventory.
*
* @param player The player to create the view for.
* @param top The top inventory.
*/
public AnvilViewMock(@NotNull HumanEntity player, @NotNull AnvilInventory top) {
super(player, top);
this.top = top;
}
@Override
public @Nullable String getRenameText() {
return top.getRenameText();
}
@Override
public int getRepairItemCountCost() {
return top.getRepairCostAmount();
}
@Override
public int getRepairCost() {
return top.getRepairCost();
}
@Override
public int getMaximumRepairCost() {
return top.getMaximumRepairCost();
}
@Override
public void setRepairItemCountCost(int amount) {
top.setRepairCostAmount(amount);
}
@Override
public void setRepairCost(int cost) {
top.setRepairCost(cost);
}
@Override
public void setMaximumRepairCost(int levels) {
top.setMaximumRepairCost(levels);
}
@Override
public boolean bypassesEnchantmentLevelRestriction() {
throw new UnsupportedOperationException("Custom anvil was not think with this existing");
}
@Override
public void bypassEnchantmentLevelRestriction(boolean bypassEnchantmentLevelRestriction) {
throw new UnsupportedOperationException("Custom anvil was not think with this existing");
}
@Override
public @NotNull AnvilInventory getTopInventory() {
return top;
}
}

View file

@ -0,0 +1,57 @@
package xyz.alexcrea.cuanvil.mock;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.mockbukkit.mockbukkit.inventory.ItemStackMock;
public class EnchantedItemStackMock extends ItemStackMock {
public EnchantedItemStackMock(@NotNull Material type, int amount) {
super(type, amount);
}
public EnchantedItemStackMock(@NotNull Material type) {
this(type, 1);
}
public EnchantedItemStackMock(@NotNull ItemStack stack) {
super(stack);
}
@Override
public int removeEnchantment(@NotNull Enchantment ench) {
if(!this.hasItemMeta()) return 0;
int level = this.getEnchantmentLevel(ench);
this.getItemMeta().removeEnchant(ench);
return level;
}
@Override
public void removeEnchantments() {
if(!this.hasItemMeta()) return;
this.getItemMeta().removeEnchantments();
}
@Override
public boolean equals(Object obj) {
if(!super.equals(obj)) return false;
return getItemMeta().equals(((ItemStack)obj).getItemMeta());
}
@Override
public @NotNull ItemStack clone() {
EnchantedItemStackMock clone = new EnchantedItemStackMock(this.getType());
clone.setAmount(this.getAmount());
clone.setItemMeta(this.getItemMeta());
clone.setDurability(this.getDurability());
return clone;
}
}

View file

@ -0,0 +1,38 @@
package xyz.alexcrea.cuanvil.tests;
import org.junit.jupiter.api.AfterEach;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import java.io.File;
public abstract class ConfigResetCustomAnvilTest extends DefaultCustomAnvilTest {
@Override
@AfterEach
public void tearDown() {
// Destroy saved config file
String[] configs = new String[]{
"config.yml",
"item_groups.yml",
"enchant_conflict.yml",
"unit_repair_item.yml",
"custom_recipes.yml"
};
for (String config : configs) {
File configFile = new File(plugin.getDataFolder(), config);
configFile.delete();
}
// Set config to null
ConfigHolder.DEFAULT_CONFIG = null;
ConfigHolder.ITEM_GROUP_HOLDER = null;
ConfigHolder.CONFLICT_HOLDER = null;
ConfigHolder.UNIT_REPAIR_HOLDER = null;
ConfigHolder.CUSTOM_RECIPE_HOLDER = null;
// Do parent works
super.tearDown();
}
}

View file

@ -0,0 +1,45 @@
package xyz.alexcrea.cuanvil.tests;
import io.delilaheve.CustomAnvil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.mockbukkit.mockbukkit.MockBukkit;
import org.mockbukkit.mockbukkit.ServerMock;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import java.util.ArrayList;
import java.util.List;
public abstract class DefaultCustomAnvilTest {
protected ServerMock server;
protected CustomAnvil plugin;
@BeforeEach
public void setUp() {
// Start the mock server
server = MockBukkit.mock();
// Load your plugin
plugin = MockBukkit.load(CustomAnvil.class);
// Continue initialization of the plugin
server.getScheduler().performOneTick();
}
@AfterEach
public void tearDown() {
// Stop the mock server
MockBukkit.unmock();
// Unregister enchantments
List<CAEnchantment> toUnregister = new ArrayList<>(
CAEnchantmentRegistry.getInstance().values()
);
for (CAEnchantment caEnchantment : toUnregister) {
CAEnchantmentRegistry.getInstance().unregister(caEnchantment);
}
}
}

View file

@ -0,0 +1,45 @@
package xyz.alexcrea.cuanvil.tests;
import io.delilaheve.CustomAnvil;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.mockbukkit.mockbukkit.MockBukkit;
import org.mockbukkit.mockbukkit.ServerMock;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import java.util.ArrayList;
import java.util.List;
public abstract class SharedCustomAnvilTest {
protected static ServerMock server;
protected static CustomAnvil plugin;
@BeforeAll
public static void setUp() {
// Start the mock server
server = MockBukkit.mock();
// Load your plugin
plugin = MockBukkit.load(CustomAnvil.class);
// Continue initialization of the plugin
server.getScheduler().performOneTick();
}
@AfterAll
public static void tearDown() {
// Stop the mock server
MockBukkit.unmock();
// Unregister enchantments
List<CAEnchantment> toUnregister = new ArrayList<>(
CAEnchantmentRegistry.getInstance().values()
);
for (CAEnchantment caEnchantment : toUnregister) {
CAEnchantmentRegistry.getInstance().unregister(caEnchantment);
}
}
}

View file

@ -0,0 +1,24 @@
package xyz.alexcrea.cuanvil.tests;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.mockbukkit.mockbukkit.MockBukkit;
import org.mockbukkit.mockbukkit.ServerMock;
public class SharedOnlyMockBukkit {
protected static ServerMock server;
@BeforeAll
public static void setUp() {
// Start the mock server
server = MockBukkit.mock();
}
@AfterAll
public static void tearDown() {
// Stop the mock server
MockBukkit.unmock();
}
}

View file

@ -0,0 +1,39 @@
package xyz.alexcrea.cuanvil.util;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
public record AnvilFuseTestData(
@Nullable ItemStack leftItem,
@Nullable ItemStack rightItem,
@Nullable ItemStack expectedResult,
@Nullable ItemStack expectedAfterLeftPlaced,
@Nullable ItemStack expectedAfterRightPlaced,
@Nullable Integer expectedPriceAfterLeftPlaced,
@Nullable Integer expectedPriceAfterRightPlaced,
@Nullable Integer expectedPriceAfterBothPlaced
){
public AnvilFuseTestData(
@Nullable ItemStack leftItem,
@Nullable ItemStack rightItem,
@Nullable ItemStack expectedResult,
@Nullable Integer expectedPriceAfterBothPlaced
){
this(leftItem, rightItem, expectedResult,
null, null, null, null,
expectedPriceAfterBothPlaced
);
}
public AnvilFuseTestData(
@Nullable ItemStack leftItem,
@Nullable ItemStack rightItem,
@Nullable ItemStack expectedResult
){
this(leftItem, rightItem, expectedResult, null
);
}
}

View file

@ -0,0 +1,165 @@
package xyz.alexcrea.cuanvil.util;
import io.delilaheve.util.ItemUtil;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.Repairable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Assertions;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener;
import xyz.alexcrea.cuanvil.mock.AnvilViewMock;
import xyz.alexcrea.cuanvil.mock.EnchantedItemStackMock;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class AnvilFuseTestUtil {
public static ItemStack prepareItem(@NotNull Material material,
@NotNull List<CAEnchantment> enchantments,
@NotNull List<Integer> level){
return prepareItem(material, 0, enchantments, level);
}
public static ItemStack prepareItem(@NotNull Material material,
int repairCost,
@NotNull List<CAEnchantment> enchantments,
@NotNull List<Integer> level){
Assertions.assertEquals(enchantments.size(), level.size());
HashMap<CAEnchantment, Integer> enchantmentMap = new HashMap<>();
for (int i = 0; i < enchantments.size(); i++) {
enchantmentMap.put(enchantments.get(i), level.get(i));
}
ItemStack item = new EnchantedItemStackMock(material);
ItemUtil.INSTANCE.setEnchantmentsUnsafe(item, enchantmentMap);
ItemMeta meta = item.getItemMeta();
((Repairable) meta).setRepairCost(repairCost);
item.setItemMeta(meta);
return item;
}
public static ItemStack prepareItem(@NotNull Material material,
@NotNull List<String> enchantmentNames,
Integer... levels){
return prepareItem(material, 0, enchantmentNames, levels);
}
public static ItemStack prepareItem(@NotNull Material material,
int repairCost,
@NotNull List<String> enchantmentNames,
Integer... levels){
List<CAEnchantment> enchantments = new ArrayList<>();
for (String enchantmentName : enchantmentNames) {
List<CAEnchantment> enchantmentList = CAEnchantment.getListByName(enchantmentName);
Assertions.assertNotEquals(0, enchantmentList.size(),
"Could not find enchantment \"" + enchantmentName + "\"");
enchantments.addAll(enchantmentList);
}
return prepareItem(material, repairCost, enchantments, List.of(levels));
}
/*
* Need to use that as it seems setting item in the inventory will not trigger the anvil click even
*
* Not the best for non-custom anvil plugins but work in the context of CA
*/
public static void imitateAnvilUpdate(
@NotNull HumanEntity player,
@NotNull AnvilInventory anvil) {
AnvilViewMock view = new AnvilViewMock(player, anvil);
try {
PrepareAnvilEvent event = new PrepareAnvilEvent(view, anvil.getItem(2));
// Not ideal but possible and the easiest so why not
new PrepareAnvilListener().anvilCombineCheck(event);
anvil.setResult(event.getResult());
} catch (Exception e){
Assertions.fail(e);
}
}
public static void executeAnvilTest(
@NotNull AnvilInventory anvil,
@NotNull HumanEntity player,
@NotNull AnvilFuseTestData data
){
Assertions.assertEquals(player.getOpenInventory().getTopInventory(), anvil,
"Openned inventory is not anvil");
// Test with only the left item
anvil.setItem(1, null); // We clear the right slot in case something was there
testPlacingItem(anvil, player,
0, data.expectedPriceAfterLeftPlaced(),
data.leftItem(), data.expectedAfterLeftPlaced());
// Test with only the right item
anvil.setItem(0, null); // We only want the right item. so we remove the left one
testPlacingItem(anvil, player,
1, data.expectedPriceAfterRightPlaced(),
data.rightItem(), data.expectedAfterRightPlaced());
// Test with both placed
testPlacingItem(anvil, player,
0, data.expectedPriceAfterBothPlaced(),
data.leftItem(), data.expectedResult());
// Sadly, can't currently test player click
}
@SuppressWarnings({"removal"})
private static void testPlacingItem(
@NotNull AnvilInventory anvil,
@NotNull HumanEntity player,
int slot,
Integer expectedPrice,
@Nullable ItemStack toPlace,
@Nullable ItemStack expectedResult){
anvil.setItem(slot, toPlace);
anvil.setItem(2, null);
AnvilFuseTestUtil.imitateAnvilUpdate(player, anvil);
ItemStack result = anvil.getItem(2);
assertEqual(expectedResult, result);
assertPriceEqual(expectedPrice, anvil.getRepairCost());
}
public static void assertEqual(@Nullable ItemStack item1, @Nullable ItemStack item2) {
boolean secondIsAir = isAir(item2);
if(isAir(item1)) Assertions.assertTrue(secondIsAir,"Item "+item2+" was not AIR but was expected to be air");
else {
Assertions.assertFalse(secondIsAir,"Item "+item2+" was expected not to be air");
item1.setDurability(item1.getDurability());
item2.setDurability(item2.getDurability());
Assertions.assertEquals(item1, item2);
}
}
public static boolean isAir(@Nullable ItemStack item){
return item == null || item.isEmpty();
}
public static void assertPriceEqual(Integer expectedPrice, int price){
if(expectedPrice == null) return;
Assertions.assertEquals(price, expectedPrice);
}
}

View file

@ -0,0 +1,27 @@
package xyz.alexcrea.cuanvil.util;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public class CommonItemUtil {
public static ItemStack sharpness(int level){
return AnvilFuseTestUtil.prepareItem(
Material.DIAMOND_SWORD,
List.of("sharpness"),
level
);
}
public static ItemStack bane_of_arthropods(int level){
return AnvilFuseTestUtil.prepareItem(
Material.DIAMOND_SWORD,
List.of("bane_of_arthropods"),
level
);
}
}

View file

@ -0,0 +1,61 @@
main: io.delilaheve.CustomAnvil
name: CustomAnvil
prefix: "Custom Anvil"
version: test
folia-supported: true
description: Allow to customise anvil mechanics
api-version: 1.16
load: POSTWORLD
authors: [ DelilahEve, alexcrea ]
libraries:
- org.jetbrains.kotlin:kotlin-stdlib:2.0.21
commands:
anvilconfigreload:
description: Reload every config of this plugin
permission: ca.command.reload
aliases:
#- acreload # anvil config reload
#- careload # custom anvil reload
- carl # custom anvil reload
customanvilconfig:
description: open a menu for administrator to edit plugin's config in game
permission: ca.config.edit
aliases:
- configanvil
permissions:
ca.affected:
default: true
description: Player with this permission will be affected by the plugin
ca.bypass.fuse:
default: false
description: Allow player to combine every enchantments to every item (no custom limit)
ca.bypass.level:
default: false
description: Allow player to bypass every level limit (no custom limit)
ca.command.reload:
default: op
description: Allow administrator to reload the plugin's configs
ca.config.edit:
default: op
description: Allow administrator to edit the plugin's config in game
# color permissions
ca.color.code:
default: op
description: Allow player to use color code if permission is required (toggleable)
ca.color.hex:
default: op
description: Allow player to use hexadecimal color if permission is required (toggleable)
# soft depend on old name (UnsafeEnchantsPlus), so I can disable it if it is on the same server (old name for this plugin)
# Also depend to other plugin for compatibility
softdepend:
- UnsafeEnchantsPlus
- ProtocolLib
- Disenchantment
- EnchantsSquared
- EcoEnchants
- eco
- ExcellentEnchants