mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-09-27 06:49:09 +02:00
252 lines
9.1 KiB
Java
252 lines
9.1 KiB
Java
package com.gmail.nossr50.events.items;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
|
import static org.mockito.Mockito.atLeastOnce;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockState;
|
|
import org.bukkit.entity.Item;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.HandlerList;
|
|
import org.bukkit.event.block.BlockDropItemEvent;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Nested;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
class McMMOModifyBlockDropItemEventTest {
|
|
private BlockDropItemEvent blockDropItemEvent;
|
|
private Item itemEntity;
|
|
private ItemStack itemStack;
|
|
private Player player;
|
|
private Block block;
|
|
private BlockState blockState;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
// Mocks for delegate passthroughs
|
|
player = mock(Player.class, RETURNS_DEEP_STUBS);
|
|
block = mock(Block.class, RETURNS_DEEP_STUBS);
|
|
blockState = mock(BlockState.class, RETURNS_DEEP_STUBS);
|
|
|
|
// Primary Bukkit event mock
|
|
blockDropItemEvent = mock(BlockDropItemEvent.class, RETURNS_DEEP_STUBS);
|
|
when(blockDropItemEvent.getPlayer()).thenReturn(player);
|
|
when(blockDropItemEvent.getBlock()).thenReturn(block);
|
|
when(blockDropItemEvent.getBlockState()).thenReturn(blockState);
|
|
|
|
// Item + ItemStack mock
|
|
itemStack = mock(ItemStack.class);
|
|
when(itemStack.getAmount()).thenReturn(3); // original count
|
|
itemEntity = mock(Item.class);
|
|
when(itemEntity.getItemStack()).thenReturn(itemStack);
|
|
}
|
|
|
|
private McMMOModifyBlockDropItemEvent newEvent(int bonus) {
|
|
return new McMMOModifyBlockDropItemEvent(blockDropItemEvent, itemEntity, bonus);
|
|
}
|
|
|
|
@Nested
|
|
@DisplayName("Constructor & validation")
|
|
class ConstructorValidation {
|
|
|
|
@Test
|
|
void ctorNullEventThrows() {
|
|
assertThrows(NullPointerException.class,
|
|
() -> new McMMOModifyBlockDropItemEvent(null, itemEntity, 1));
|
|
}
|
|
|
|
@Test
|
|
void ctorNullItemThrows() {
|
|
assertThrows(NullPointerException.class,
|
|
() -> new McMMOModifyBlockDropItemEvent(blockDropItemEvent, null, 1));
|
|
}
|
|
|
|
@Test
|
|
void ctorZeroBonusThrows() {
|
|
assertThrows(IllegalArgumentException.class,
|
|
() -> new McMMOModifyBlockDropItemEvent(blockDropItemEvent, itemEntity, 0));
|
|
}
|
|
|
|
@Test
|
|
void ctorNegativeBonusThrows() {
|
|
assertThrows(IllegalArgumentException.class,
|
|
() -> new McMMOModifyBlockDropItemEvent(blockDropItemEvent, itemEntity, -5));
|
|
}
|
|
|
|
@Test
|
|
void ctorSetsOriginalsAndModifiedCorrectly() {
|
|
// original amount = 3, bonus = 2
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(2);
|
|
assertEquals(3, ev.getOriginalItemStackQuantity());
|
|
assertEquals(2, ev.getOriginalBonusAmountToAdd());
|
|
assertEquals(5, ev.getModifiedItemStackQuantity());
|
|
assertFalse(ev.isCancelled());
|
|
assertFalse(ev.isEffectivelyNoBonus());
|
|
}
|
|
}
|
|
|
|
@Nested
|
|
@DisplayName("Cancellable contract")
|
|
class Cancellation {
|
|
@Test
|
|
void cancelAndUncancel() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
assertFalse(ev.isCancelled());
|
|
ev.setCancelled(true);
|
|
assertTrue(ev.isCancelled());
|
|
ev.setCancelled(false);
|
|
assertFalse(ev.isCancelled());
|
|
}
|
|
}
|
|
|
|
@Nested
|
|
@DisplayName("Delta & absolute quantity semantics")
|
|
class DeltaAndAbsolute {
|
|
|
|
@Test
|
|
void getBonusAmountToAddReflectsDifferenceFromOriginal() {
|
|
// original 3, bonus 4 => modified 7
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(4);
|
|
assertEquals(4, ev.getBonusAmountToAdd());
|
|
assertEquals(7, ev.getModifiedItemStackQuantity());
|
|
}
|
|
|
|
@Test
|
|
void setBonusAmountToAddUpdatesModifiedQuantity() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(2); // original 3 -> modified 5
|
|
ev.setBonusAmountToAdd(10); // new modified should be 13
|
|
assertEquals(13, ev.getModifiedItemStackQuantity());
|
|
assertEquals(10, ev.getBonusAmountToAdd());
|
|
assertFalse(ev.isEffectivelyNoBonus());
|
|
}
|
|
|
|
@Test
|
|
void setBonusAmountToAddNegativeThrows() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
assertThrows(IllegalArgumentException.class, () -> ev.setBonusAmountToAdd(-1));
|
|
}
|
|
|
|
@Test
|
|
void setModifiedItemStackQuantityEqualToOriginalIsNoBonus() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(2); // 3 -> 5
|
|
ev.setModifiedItemStackQuantity(3); // back to original => no bonus
|
|
assertEquals(3, ev.getModifiedItemStackQuantity());
|
|
assertEquals(0, ev.getBonusAmountToAdd());
|
|
assertTrue(ev.isEffectivelyNoBonus());
|
|
}
|
|
|
|
@Test
|
|
void setModifiedItemStackQuantityLessThanOriginalThrows() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
assertThrows(IllegalArgumentException.class, () -> ev.setModifiedItemStackQuantity(2)); // original is 3
|
|
}
|
|
|
|
@Test
|
|
void setModifiedItemStackQuantityGreaterThanOriginalUpdatesBonus() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1); // original 3 -> modified 4
|
|
ev.setModifiedItemStackQuantity(12);
|
|
assertEquals(12, ev.getModifiedItemStackQuantity());
|
|
assertEquals(9, ev.getBonusAmountToAdd()); // 12 - 3
|
|
assertFalse(ev.isEffectivelyNoBonus());
|
|
}
|
|
}
|
|
|
|
@Nested
|
|
@DisplayName("Delegate passthroughs")
|
|
class Delegates {
|
|
|
|
@Test
|
|
void getPlayerPassthrough() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
assertSame(player, ev.getPlayer());
|
|
verify(blockDropItemEvent, atLeastOnce()).getPlayer();
|
|
}
|
|
|
|
@Test
|
|
void getBlockPassthrough() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
assertSame(block, ev.getBlock());
|
|
verify(blockDropItemEvent, atLeastOnce()).getBlock();
|
|
}
|
|
|
|
@Test
|
|
void getBlockStatePassthrough() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
assertSame(blockState, ev.getBlockState());
|
|
verify(blockDropItemEvent, atLeastOnce()).getBlockState();
|
|
}
|
|
|
|
@Test
|
|
void getItemReturnsOriginalItemEntity() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
assertSame(itemEntity, ev.getItem());
|
|
}
|
|
}
|
|
|
|
@Nested
|
|
@DisplayName("HandlerList plumbing")
|
|
class HandlerListTests {
|
|
@Test
|
|
void handlerList_isNonNull_andShared() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(1);
|
|
HandlerList fromInstance = ev.getHandlers();
|
|
HandlerList fromStatic = McMMOModifyBlockDropItemEvent.getHandlerList();
|
|
assertNotNull(fromInstance);
|
|
assertNotNull(fromStatic);
|
|
// Bukkit convention: same static instance
|
|
assertSame(fromStatic, fromInstance);
|
|
}
|
|
}
|
|
|
|
@Nested
|
|
@DisplayName("Object contracts")
|
|
class ObjectContracts {
|
|
|
|
@Test
|
|
void toStringContainsKeyFields() {
|
|
McMMOModifyBlockDropItemEvent ev = newEvent(2);
|
|
String s = ev.toString();
|
|
assertNotNull(s);
|
|
assertTrue(s.contains("originalBonusAmountToAdd=2"));
|
|
assertTrue(s.contains("modifiedItemStackQuantity=5"));
|
|
}
|
|
|
|
@Test
|
|
void equalsAndHashCodeReflectState() {
|
|
// Same inputs => equal (mocks are same instances)
|
|
McMMOModifyBlockDropItemEvent a = newEvent(2);
|
|
McMMOModifyBlockDropItemEvent b = newEvent(2);
|
|
assertEquals(a, b);
|
|
assertEquals(a.hashCode(), b.hashCode());
|
|
|
|
// Change cancellation and modified quantity => not equal
|
|
McMMOModifyBlockDropItemEvent c = newEvent(2);
|
|
c.setCancelled(true);
|
|
assertNotEquals(a, c);
|
|
|
|
McMMOModifyBlockDropItemEvent d = newEvent(2);
|
|
d.setModifiedItemStackQuantity(99);
|
|
assertNotEquals(a, d);
|
|
|
|
// Different underlying mocks => not equal
|
|
BlockDropItemEvent otherEvent = mock(BlockDropItemEvent.class, RETURNS_DEEP_STUBS);
|
|
when(otherEvent.getPlayer()).thenReturn(player);
|
|
when(otherEvent.getBlock()).thenReturn(block);
|
|
when(otherEvent.getBlockState()).thenReturn(blockState);
|
|
|
|
ItemStack otherStack = mock(ItemStack.class);
|
|
when(otherStack.getAmount()).thenReturn(3);
|
|
Item otherItem = mock(Item.class);
|
|
when(otherItem.getItemStack()).thenReturn(otherStack);
|
|
|
|
McMMOModifyBlockDropItemEvent e = new McMMOModifyBlockDropItemEvent(otherEvent, otherItem, 2);
|
|
assertNotEquals(a, e);
|
|
}
|
|
}
|
|
} |