Add fuse test. Also made some modification to allow the test to work

This commit is contained in:
alexcrea 2024-10-24 10:29:29 +02:00
parent 2008b41b09
commit 99a7829990
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
15 changed files with 514 additions and 52 deletions

View file

@ -87,7 +87,7 @@ allprojects {
compileOnly(kotlin("stdlib")) compileOnly(kotlin("stdlib"))
// Test dependency // Test dependency
testImplementation(platform("org.junit:junit-bom:5.9.1")) testImplementation(platform("org.junit:junit-bom:5.11.3"))
testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.junit.jupiter:junit-jupiter")
} }

View file

@ -7,10 +7,28 @@ import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
class v1_21R1_ExternGuiTester: ExternGuiTester { class v1_21R1_ExternGuiTester: ExternGuiTester {
override val wesjdAnvilGuiName = "Wrapper1_21_R1" override val wesjdAnvilGuiName = "Wrapper1_21_R1"
var tested = false;
var possible = false;
override fun getContainerClass(view: InventoryView): Class<Any>? { override fun getContainerClass(view: InventoryView): Class<Any>? {
// In case we are in a test environment
if(!tested) testClassExist()
if(!possible) return null
if(view !is CraftInventoryView<*, *>) return null if(view !is CraftInventoryView<*, *>) return null
val container = view.handle val container = view.handle
return container.javaClass return container.javaClass
} }
fun testClassExist(){
tested = true;
try {
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
possible = true
} catch (e: ClassNotFoundException){
possible = false
}
}
} }

View file

@ -29,7 +29,8 @@ public class BukkitEnchantBulkOperation implements BulkGetEnchantOperation, Bulk
@Override @Override
public void bulkClear(@NotNull ItemStack item) { public void bulkClear(@NotNull ItemStack item) {
if (item.getType() != Material.ENCHANTED_BOOK) { if (item.getType() != Material.ENCHANTED_BOOK) {
item.getEnchantments().forEach((enchantment, leve) ->
item.getEnchantments().forEach((enchantment, level) ->
item.removeEnchantment(enchantment) item.removeEnchantment(enchantment)
); );
} }
@ -43,5 +44,6 @@ public class BukkitEnchantBulkOperation implements BulkGetEnchantOperation, Bulk
bookMeta.removeStoredEnchant(enchantment) bookMeta.removeStoredEnchant(enchantment)
); );
} }
} }
} }

View file

@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.dependency
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.entity.HumanEntity
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.AnvilInventory
@ -91,11 +92,11 @@ object DependencyManager {
} }
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent): Boolean { fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
var bypass = false var bypass = false
// Test if disenchantment used special prepare anvil // Test if disenchantment used special prepare anvil
if(disenchantmentCompatibility?.testPrepareAnvil(event) == true) bypass = true if(disenchantmentCompatibility?.testPrepareAnvil(event, player) == true) bypass = true
// Test excellent enchantments used special prepare anvil // Test excellent enchantments used special prepare anvil
if(!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true if(!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true

View file

@ -5,6 +5,7 @@ import cz.kominekjan.disenchantment.events.DisenchantEvent
import cz.kominekjan.disenchantment.events.ShatterClickEvent import cz.kominekjan.disenchantment.events.ShatterClickEvent
import cz.kominekjan.disenchantment.events.ShatterEvent import cz.kominekjan.disenchantment.events.ShatterEvent
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.AnvilInventory
@ -70,7 +71,7 @@ class DisenchantmentDependency {
} }
fun testPrepareAnvil(event: PrepareAnvilEvent): Boolean { fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
val previousResult = event.result val previousResult = event.result
event.result = null event.result = null
@ -79,14 +80,14 @@ class DisenchantmentDependency {
if(event.result != null) { if(event.result != null) {
CustomAnvil.log("Detected pre anvil item extract bypass.") CustomAnvil.log("Detected pre anvil item extract bypass.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, event.inventory.repairCost) AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
return true return true
} }
splitEvent.onDisenchantmentEvent(event) splitEvent.onDisenchantmentEvent(event)
if(event.result != null) { if(event.result != null) {
CustomAnvil.log("Detected pre anvil split enchant bypass.") CustomAnvil.log("Detected pre anvil split enchant bypass.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, event.inventory.repairCost) AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
return true return true
} }

View file

@ -11,11 +11,13 @@ import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe
import io.delilaheve.util.ItemUtil.unitRepair import io.delilaheve.util.ItemUtil.unitRepair
import org.bukkit.ChatColor import org.bukkit.ChatColor
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority import org.bukkit.event.EventPriority
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.util.AnvilColorUtil import xyz.alexcrea.cuanvil.util.AnvilColorUtil
@ -41,19 +43,20 @@ class PrepareAnvilListener : Listener {
*/ */
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
fun anvilCombineCheck(event: PrepareAnvilEvent) { fun anvilCombineCheck(event: PrepareAnvilEvent) {
// Should find player
val player: HumanEntity = event.viewers.first()
// Test if the event should bypass custom anvil. // Test if the event should bypass custom anvil.
if(DependencyManager.tryEventPreAnvilBypass(event)) return if(DependencyManager.tryEventPreAnvilBypass(event, player)) return
val inventory = event.inventory val inventory = event.inventory
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val second = inventory.getItem(ANVIL_INPUT_RIGHT) val second = inventory.getItem(ANVIL_INPUT_RIGHT)
// Should find player
val player = event.view.player
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
// Test custom recipe // Test custom recipe
if(testCustomRecipe(event, inventory, first, second)) return if(testCustomRecipe(event, inventory, player, first, second)) return
// Test rename lonely item // Test rename lonely item
if(second == null) { if(second == null) {
@ -75,7 +78,9 @@ class PrepareAnvilListener : Listener {
} }
private fun testCustomRecipe(event: PrepareAnvilEvent, inventory: AnvilInventory, first: ItemStack, second: ItemStack?): Boolean { private fun testCustomRecipe(event: PrepareAnvilEvent, inventory: AnvilInventory,
player: HumanEntity,
first: ItemStack, second: ItemStack?): Boolean {
val recipe = CustomRecipeUtil.getCustomRecipe(first, second) val recipe = CustomRecipeUtil.getCustomRecipe(first, second)
CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}") CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}")
if(recipe == null) return false if(recipe == null) return false
@ -87,7 +92,7 @@ class PrepareAnvilListener : Listener {
event.result = resultItem event.result = resultItem
DependencyManager.treatAnvilResult(event, resultItem) DependencyManager.treatAnvilResult(event, resultItem)
AnvilXpUtil.setAnvilInvXp(inventory, event.view, recipe.xpCostPerCraft * amount, true) AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, recipe.xpCostPerCraft * amount, true)
return true return true
} }
@ -109,7 +114,7 @@ class PrepareAnvilListener : Listener {
anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem) anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem)
AnvilXpUtil.setAnvilInvXp(inventory, event.view, anvilCost) AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
} }
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int { private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
@ -177,7 +182,7 @@ class PrepareAnvilListener : Listener {
event.result = resultItem event.result = resultItem
DependencyManager.treatAnvilResult(event, resultItem) DependencyManager.treatAnvilResult(event, resultItem)
AnvilXpUtil.setAnvilInvXp(inventory, event.view, anvilCost) AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
} }
private fun testUnitRepair(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, private fun testUnitRepair(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
@ -203,7 +208,7 @@ class PrepareAnvilListener : Listener {
event.result = resultItem event.result = resultItem
DependencyManager.treatAnvilResult(event, resultItem) DependencyManager.treatAnvilResult(event, resultItem)
AnvilXpUtil.setAnvilInvXp(inventory, event.view, anvilCost) AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
return true return true
} }

View file

@ -6,6 +6,7 @@ import io.delilaheve.util.EnchantmentUtil.enchantmentName
import io.delilaheve.util.ItemUtil.findEnchantments import io.delilaheve.util.ItemUtil.findEnchantments
import io.delilaheve.util.ItemUtil.isEnchantedBook import io.delilaheve.util.ItemUtil.isEnchantedBook
import org.bukkit.GameMode import org.bukkit.GameMode
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView import org.bukkit.inventory.InventoryView
@ -25,6 +26,7 @@ object AnvilXpUtil {
fun setAnvilInvXp( fun setAnvilInvXp(
inventory: AnvilInventory, inventory: AnvilInventory,
view: InventoryView, view: InventoryView,
player: HumanEntity,
anvilCost: Int, anvilCost: Int,
ignoreRules: Boolean = false ignoreRules: Boolean = false
) { ) {
@ -38,8 +40,6 @@ object AnvilXpUtil {
anvilCost anvilCost
} }
val player = view.player
/* Because Minecraft likes to have the final say in the repair cost displayed /* Because Minecraft likes to have the final say in the repair cost displayed
* we need to wait for the event to end before overriding it, this ensures that * we need to wait for the event to end before overriding it, this ensures that
* we have the final say in the process. */ * we have the final say in the process. */

View file

@ -1,44 +1,15 @@
package io.delilaheve; package io.delilaheve;
import be.seeseemelk.mockbukkit.MockBukkit; import org.junit.jupiter.api.Assertions;
import be.seeseemelk.mockbukkit.ServerMock;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import xyz.alexcrea.cuanvil.DefaultCustomAnvilTest;
public class CustomAnvilTests { public class CustomAnvilTests extends DefaultCustomAnvilTest {
private ServerMock server;
private CustomAnvil plugin;
@BeforeEach
public void setUp() {
// Start the mock server
server = MockBukkit.mock();
// Load your plugin
plugin = MockBukkit.load(CustomAnvil.class);
}
@AfterEach
public void tearDown() {
// Stop the mock server
MockBukkit.unmock();
}
@Test @Test
public void simpleInitTest() { public void simpleInitTest() {
// Continue initialization of the plugin Assertions.assertNotNull(server);
server.getScheduler().performOneTick(); Assertions.assertNotNull(plugin);
} }
} }

View file

@ -0,0 +1,53 @@
package xyz.alexcrea.cuanvil;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.delilaheve.CustomAnvil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import java.util.ArrayList;
import java.util.List;
public 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() {
// 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;
// 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,81 @@
package xyz.alexcrea.cuanvil.anvil;
import be.seeseemelk.mockbukkit.entity.PlayerMock;
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.BeforeEach;
import org.junit.jupiter.api.Test;
import xyz.alexcrea.cuanvil.DefaultCustomAnvilTest;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestData;
import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil;
import xyz.alexcrea.cuanvil.util.CommonItemUtil;
public class AnvilFuseTest extends DefaultCustomAnvilTest {
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 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,76 @@
package xyz.alexcrea.cuanvil.mock;
import be.seeseemelk.mockbukkit.inventory.PlayerInventoryViewMock;
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;
@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,56 @@
package xyz.alexcrea.cuanvil.mock;
import be.seeseemelk.mockbukkit.inventory.ItemStackMock;
import com.google.common.collect.ImmutableMap;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class EnchantedItemStackMock extends ItemStackMock {
EnchantedItemStackMock(){}
public EnchantedItemStackMock(@NotNull Material type, int amount) {
super(type, amount);
}
public EnchantedItemStackMock(@NotNull Material type) {
this(type, 1);
}
public EnchantedItemStackMock(@NotNull ItemStack stack) throws IllegalArgumentException {
super(stack);
}
@Override
public int removeEnchantment(@NotNull Enchantment ench) {
int level = this.getEnchantmentLevel(ench);
this.getItemMeta().removeEnchant(ench);
return level;
}
@Override
public void removeEnchantments() {
this.getItemMeta().removeEnchantments();
}
// badly imitate paper (and I hope spigot) behavior and avoid concurrent modification exception
@Override
public @NotNull Map<Enchantment, Integer> getEnchantments() {
return ImmutableMap.copyOf(super.getEnchantments());
}
@Override
public @NotNull ItemStack clone() {
ItemStackMock clone = new EnchantedItemStackMock(this.getType());
clone.setAmount(this.getAmount());
clone.setDurability(this.getDurability());
clone.setItemMeta(this.hasItemMeta() ? this.getItemMeta().clone() : null);
return clone;
}
}

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,138 @@
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.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){
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);
return item;
}
public static ItemStack prepareItem(@NotNull Material material,
@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, 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){
e.printStackTrace();
Assertions.fail();
}
}
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
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);
AnvilFuseTestUtil.imitateAnvilUpdate(player, anvil);
ItemStack result = anvil.getItem(2);
assertEqual(result, expectedResult);
assertPriceEqual(expectedPrice, anvil.getRepairCost());
}
public static void assertEqual(@Nullable ItemStack item1, @Nullable ItemStack item2) {
if(isAir(item1)) Assertions.assertTrue(isAir(item2));
else 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,21 @@
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
);
}
}