Skip to content

Commit

Permalink
test(api,test-shared-classes): move mock creation to test-shared-classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Siroshun09 committed Mar 4, 2024
1 parent 826f78c commit b534bde
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 48 deletions.
4 changes: 4 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ tasks.javadoc {
afterEvaluate {
collector.JavadocAggregator.addProject(this)
}

dependencies {
testImplementation(projects.boxTestSharedClasses)
}
59 changes: 11 additions & 48 deletions api/src/test/java/net/okocraft/box/api/util/InventoryUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@
import com.github.siroshun09.configapi.core.serialization.key.KeyGenerator;
import com.github.siroshun09.configapi.core.serialization.record.RecordDeserializer;
import com.github.siroshun09.configapi.format.yaml.YamlFormat;
import net.okocraft.box.test.shared.mock.bukkit.inventory.ContentsHoldingInventory;
import net.okocraft.box.test.shared.mock.bukkit.item.ItemStackMock;
import org.bukkit.Material;
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.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import java.io.IOException;
import java.util.Collection;
Expand All @@ -28,18 +27,14 @@ class InventoryUtilTest {
@ParameterizedTest
@MethodSource({"loadTestCases"})
void test(TestCase testCase) {
var contents = ArgumentCaptor.forClass(ItemStack[].class);
var inventory = testCase.inventory().createTestInventory();

int remainingAmount = InventoryUtil.putItems(
testCase.inventory().createTestInventory(contents),
testCase.puttingItem().toItemStack(),
testCase.puttingItem().amount()
);
int remainingAmount = InventoryUtil.putItems(inventory, testCase.puttingItem().toItemStack(), testCase.puttingItem().amount());

Assertions.assertEquals(testCase.expectedReturnValue(), remainingAmount);

if (testCase.puttingItem().amount() != remainingAmount) {
testCase.inventory().checkExpectedResultContents(contents);
testCase.inventory().checkContents(inventory);
}
}

Expand All @@ -55,51 +50,19 @@ void test(TestCase testCase) {
return source.getList("cases").asList(MapNode.class).stream().map(deserializer::deserialize).toList();
}

private static @NotNull ItemStack createItemStack(@NotNull Material item, int amount) {
if (amount < 1 || item.getMaxStackSize() < amount) {
throw new IllegalArgumentException("Invalid amount: " + amount);
}

var mock = Mockito.mock(ItemStack.class);
Mockito.when(mock.getType()).thenReturn(item);
Mockito.when(mock.getAmount()).thenReturn(amount);
Mockito.when(mock.getMaxStackSize()).thenReturn(item.getMaxStackSize());
Mockito.when(mock.asQuantity(Mockito.anyInt())).thenAnswer(invocation -> createItemStack(item, invocation.getArgument(0)));
Mockito.when(mock.isSimilar(Mockito.any())).thenAnswer(invocation -> mock.getType() == invocation.<ItemStack>getArgument(0).getType());
return mock;
}

private record TestCase(String name, PuttingItem puttingItem, InventoryInfo inventory, int expectedReturnValue) {
}

private record InventoryInfo(int size,
@Key("initial") @CollectionType(InventoryItem.class) List<InventoryItem> initialItems,
@Key("result") @CollectionType(InventoryItem.class) List<InventoryItem> resultItems) {

public @NotNull Inventory createTestInventory(@NotNull ArgumentCaptor<ItemStack[]> captor) {
var mock = Mockito.mock(Inventory.class);
var contents = toContents(this.size, this.initialItems);
Mockito.when(mock.getStorageContents()).thenReturn(contents);
Mockito.doNothing().when(mock).setStorageContents(captor.capture());
return mock;
public @NotNull ContentsHoldingInventory createTestInventory() {
return ContentsHoldingInventory.create(toContents(this.size, this.initialItems));
}

public void checkExpectedResultContents(@NotNull ArgumentCaptor<ItemStack[]> captor) {
var actualContents = captor.getValue();
Assertions.assertEquals(this.size, actualContents.length);

var expectedContents = toContents(this.size, this.resultItems);
for (int i = 0; i < expectedContents.length; i++) {
var expectedItem = expectedContents[i];
var actualItem = actualContents[i];

if (expectedItem == null) {
Assertions.assertNull(actualItem);
} else {
Assertions.assertEquals(expectedItem.getType(), actualItem.getType());
Assertions.assertEquals(expectedItem.getAmount(), actualItem.getAmount());
}
}
public void checkContents(@NotNull ContentsHoldingInventory inventory) {
inventory.checkContents(toContents(this.size, this.resultItems));
}

private static @Nullable ItemStack @NotNull [] toContents(int size, List<InventoryItem> items) {
Expand All @@ -115,13 +78,13 @@ public void checkExpectedResultContents(@NotNull ArgumentCaptor<ItemStack[]> cap

private record PuttingItem(Material item, @DefaultInt(1) int amount) {
public @NotNull ItemStack toItemStack() {
return createItemStack(this.item, 1);
return ItemStackMock.createItemStack(this.item, 1);
}
}

private record InventoryItem(Material item, @DefaultInt(1) int amount, int position) {
public @NotNull ItemStack toItemStack() {
return createItemStack(this.item, this.amount);
return ItemStackMock.createItemStack(this.item, this.amount);
}
}
}
1 change: 1 addition & 0 deletions test-shared-classes/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ dependencies {
api(projects.boxStorageApi)
api(libs.junit.jupiter)
api(libs.configapi.test.shared.classes)
api(libs.mockito)
implementation(projects.boxCore)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package net.okocraft.box.test.shared.mock.bukkit.inventory;

import net.okocraft.box.test.shared.mock.bukkit.item.ItemStackMock;
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.mockito.Mockito;

import java.util.Arrays;

public abstract class ContentsHoldingInventory implements Inventory {

public static @NotNull ContentsHoldingInventory create(int size) {
return createMock(new ItemStack[size]);
}

public static @NotNull ContentsHoldingInventory create(@Nullable ItemStack @NotNull [] contents) {
return createMock(Arrays.copyOf(contents, contents.length));
}

private static @NotNull ContentsHoldingInventory createMock(@Nullable ItemStack @NotNull [] contents) {
var mock = Mockito.mock(ContentsHoldingInventory.class);

Mockito.doCallRealMethod().when(mock).getContents();
Mockito.doCallRealMethod().when(mock).getStorageContents();
Mockito.doCallRealMethod().when(mock).setContents(Mockito.any());
Mockito.doCallRealMethod().when(mock).setStorageContents(Mockito.any());
Mockito.doCallRealMethod().when(mock).checkContents(Mockito.any());

mock.contents = contents;
return mock;
}

ItemStack[] contents;

@Override
public @Nullable ItemStack @NotNull [] getContents() {
if (this.contents == null) {
throw new IllegalStateException("Not initialized.");
}
return Arrays.copyOf(this.contents, this.contents.length);
}

@Override
public @Nullable ItemStack @NotNull [] getStorageContents() {
return this.getContents();
}

@Override
public void setContents(@Nullable ItemStack @NotNull [] newContents) throws IllegalArgumentException {
if (this.contents == null) {
throw new IllegalStateException("Not initialized.");
}

if (this.contents.length != newContents.length) {
throw new IllegalArgumentException("The number of new items does not match the size of this inventory.");
}

this.contents = Arrays.copyOf(newContents, newContents.length);
}

@Override
public void setStorageContents(@Nullable ItemStack @NotNull [] newContents) throws IllegalArgumentException {
this.setContents(newContents);
}

public void checkContents(@Nullable ItemStack @NotNull [] expectedContents) {
var actualContents = this.contents;

if (actualContents == null) {
throw new IllegalStateException("Not initialized.");
}

Assertions.assertEquals(expectedContents.length, actualContents.length);

for (int i = 0; i < expectedContents.length; i++) {
var expectedItem = expectedContents[i];
var actualItem = actualContents[i];

if (expectedItem == null) {
Assertions.assertNull(actualItem);
} else {
Assertions.assertNotNull(actualItem);
ItemStackMock.checkSameTypeAndSameAmount(expectedItem, actualItem);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package net.okocraft.box.test.shared.mock.bukkit.item;

import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Assertions;
import org.mockito.Mockito;

public final class ItemStackMock {

public static @NotNull ItemStack createItemStack(@NotNull Material item, int amount) {
if (amount < 1 || item.getMaxStackSize() < amount) {
throw new IllegalArgumentException("Invalid amount: " + amount);
}

var mock = Mockito.mock(ItemStack.class);

Mockito.when(mock.getType()).thenReturn(item);
Mockito.when(mock.getAmount()).thenReturn(amount);
Mockito.when(mock.getMaxStackSize()).thenReturn(item.getMaxStackSize());
Mockito.when(mock.asQuantity(Mockito.anyInt())).thenAnswer(invocation -> createItemStack(item, invocation.getArgument(0)));
Mockito.when(mock.isSimilar(Mockito.any())).thenAnswer(invocation -> mock.getType() == invocation.<ItemStack>getArgument(0).getType());

return mock;
}

public static void checkSameTypeAndSameAmount(@NotNull ItemStack item1, @NotNull ItemStack item2) {
checkSameType(item1, item2);
Assertions.assertEquals(item1.getAmount(), item2.getAmount());
}

public static void checkSameType(@NotNull ItemStack item1, @NotNull ItemStack item2) {
Assertions.assertEquals(item1.getType(), item2.getType());
}

private ItemStackMock() {
throw new UnsupportedOperationException();
}
}

0 comments on commit b534bde

Please sign in to comment.