Skip to content

Commit

Permalink
more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
SchnTgaiSpock committed Nov 5, 2024
1 parent 72a56a9 commit 38a30eb
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;

import io.github.thebusybiscuit.slimefun4.api.recipes.items.RecipeOutputItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.matching.InputMatchResult;
import io.github.thebusybiscuit.slimefun4.api.recipes.matching.MatchProcedure;
import io.github.thebusybiscuit.slimefun4.api.recipes.matching.RecipeMatchResult;
Expand Down Expand Up @@ -47,37 +46,40 @@ public Recipe(Optional<String> id, String filename, AbstractRecipeInput input, A
}
}

public static Recipe fromItemStacks(String id, ItemStack[] inputs, ItemStack output, RecipeType type) {
public static Recipe fromItemStacks(String id, ItemStack[] inputs, ItemStack[] outputs, RecipeType type, MatchProcedure match) {
return new Recipe(
Optional.of(id),
id.toLowerCase(),
RecipeInput.fromItemStacks(inputs, type.getDefaultMatchProcedure()),
new RecipeOutput(List.of(new RecipeOutputItemStack(output))),
RecipeInput.fromItemStacks(inputs, match),
RecipeOutput.fromItemStacks(outputs),
List.of(type),
Optional.empty(),
Optional.empty(),
List.of()
);
}

public static Recipe fromItemStacks(ItemStack[] inputs, ItemStack output, RecipeType type, MatchProcedure match) {
public static Recipe fromItemStacks(String id, ItemStack[] inputs, ItemStack[] outputs, RecipeType type) {
return fromItemStacks(id, inputs, outputs, type, type.getDefaultMatchProcedure());
}

public static Recipe fromItemStacks(ItemStack[] inputs, ItemStack[] outputs, RecipeType type, MatchProcedure match) {
return new Recipe(
Optional.empty(),
"other_recipes",
RecipeInput.fromItemStacks(inputs, match),
new RecipeOutput(List.of(new RecipeOutputItemStack(output))),
RecipeOutput.fromItemStacks(outputs),
List.of(type),
Optional.empty(),
Optional.empty(),
List.of()
);
}

public static Recipe fromItemStacks(ItemStack[] inputs, ItemStack output, RecipeType type) {
return fromItemStacks(inputs, output, type, type.getDefaultMatchProcedure());
public static Recipe fromItemStacks(ItemStack[] inputs, ItemStack[] outputs, RecipeType type) {
return fromItemStacks(inputs, outputs, type, type.getDefaultMatchProcedure());
}


public Optional<String> getId() {
return id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;

import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.recipes.items.AbstractRecipeOutputItem;
import io.github.thebusybiscuit.slimefun4.api.recipes.items.AbstractRecipeOutputItem.SpaceRequirement;
import io.github.thebusybiscuit.slimefun4.api.recipes.items.RecipeOutputItem;
import io.github.thebusybiscuit.slimefun4.api.recipes.items.RecipeOutputItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.items.RecipeOutputSlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.recipes.matching.RecipeMatchResult;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;

public class RecipeOutput extends AbstractRecipeOutput {

Expand Down Expand Up @@ -60,6 +65,25 @@ public RecipeOutput(List<AbstractRecipeOutputItem> items) {
this.items = items;
}

public static RecipeOutput fromItemStacks(ItemStack[] items) {
List<AbstractRecipeOutputItem> outputItems = new ArrayList<>();
for (ItemStack item : items) {
if (item == null || item.getType().isAir()) {
outputItems.add(RecipeOutputItem.EMPTY);
continue;
}

SlimefunItem sfItem = SlimefunItem.getByItem(item);

if (sfItem != null) {
outputItems.add(new RecipeOutputSlimefunItem(sfItem.getId(), item.getAmount()));
} else {
outputItems.add(new RecipeOutputItemStack(item));
}
}
return new RecipeOutput(outputItems);
}

public List<AbstractRecipeOutputItem> getItems() {
return this.items;
}
Expand Down Expand Up @@ -102,19 +126,23 @@ public Inserter checkSpace(RecipeMatchResult result, Inventory inventory, int[]
// Search for matching item
int amount = outputStack.getAmount();
int stackSize = outputStack.getType().getMaxStackSize(); // TODO item components
for (int i = 0; i < filledSlots.size(); i++) {
for (int i : filledSlots) {
if (amount <= 0) break;
ItemStack filledItem = inventory.getItem(i);
if (!SlimefunUtils.isItemSimilar(filledItem, outputStack, true, false)) {
continue;
}
int filledAmount = filledItem.getAmount();
if (filledAmount >= stackSize) {
int currentAdd = addToStacks.getOrDefault(i, 0);
if (filledAmount + currentAdd >= stackSize) {
continue;
} else if (filledAmount + amount > stackSize) {
int diff = stackSize - filledAmount;
} else if (filledAmount + currentAdd + amount > stackSize) {
int diff = stackSize - filledAmount - currentAdd;
amount -= diff;
addToStacks.put(i, diff);
} else if (filledAmount + amount == stackSize) {
addToStacks.put(i, diff + currentAdd);
} else {
addToStacks.put(i, amount + currentAdd);
amount = 0;
addToStacks.put(i, amount);
}
}
if (amount > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
public abstract class RecipeOutputItem extends AbstractRecipeOutputItem {

/**
* Should not be used in recipes unless as a default.
* Should not be used in recipes.
* If you need an empty recipe output, use RecipeOutput.EMPTY instead
*/
public static final AbstractRecipeOutputItem EMPTY = new AbstractRecipeOutputItem() {
Expand All @@ -25,6 +25,11 @@ public boolean matchItem(ItemStack item) {
return item == null || item.getType().isAir();
}

@Override
public SpaceRequirement getSpaceRequirement() {
return SpaceRequirement.MATCHING_ITEM;
}

@Override
public ItemStack generateOutput(RecipeMatchResult result) {
return new ItemStack(Material.AIR);
Expand Down Expand Up @@ -59,6 +64,11 @@ public RecipeOutputItem(int amount) {
public int getAmount() { return amount; }
public void setAmount(int amount) { this.amount = amount; }

@Override
public SpaceRequirement getSpaceRequirement() {
return SpaceRequirement.MATCHING_ITEM;
}

/**
* Converts a string into a RecipeSingleItem
* @param string A namespace string in the format
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ public RecipeSearchResult searchRecipes(RecipeType type, Function<Recipe, Recipe
return new RecipeSearchResult();
}

public RecipeSearchResult searchRecipes(RecipeType type, List<ItemStack> givenItems, MatchProcedure matchAs) {
return searchRecipes(type, recipe -> recipe.matchAs(matchAs, givenItems), recipe -> RecipeUtils.hashItemsIgnoreAmount(givenItems));
}

public RecipeSearchResult searchRecipes(RecipeType type, List<ItemStack> givenItems) {
return searchRecipes(type, recipe -> recipe.match(givenItems), recipe -> RecipeUtils.hashItemsIgnoreAmount(givenItems));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,27 +333,27 @@ void testShapedRecipeMatching() {
null, null, null,
new ItemStack(Material.SUGAR, 10), new ItemStack(Material.APPLE, 2), null,
null, new ItemStack(Material.STICK, 3), null,
}, new ItemStack(Material.STICK), RecipeType.NULL);
}, new ItemStack[] { new ItemStack(Material.STICK) }, RecipeType.NULL);
ItemStack sticks = new ItemStack(Material.STICK, 64);
ItemStack apples = new ItemStack(Material.APPLE, 64);
ItemStack sugar = new ItemStack(Material.SUGAR, 64);
var falseResult = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(new ItemStack[] {
var falseResult = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(
sugar, apples, null,
null, new ItemStack(Material.ACACIA_BOAT), null,
null, null, null,
}));
null, null, null
));
Assertions.assertFalse(falseResult.itemsMatch());
falseResult = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(new ItemStack[] {
falseResult = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(
sugar, apples, null,
null, new ItemStack(Material.STICK, 1), null,
null, null, null,
}));
null, null, null
));
Assertions.assertFalse(falseResult.itemsMatch());
var result = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(new ItemStack[] {
var result = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(
sugar, apples, null,
null, sticks, null,
null, null, null,
}));
null, null, null
));
Assertions.assertTrue(result.itemsMatch());
Assertions.assertEquals(3, result.getInputMatchResult().consumeItems(3));
Assertions.assertEquals(55, sticks.getAmount());
Expand All @@ -371,17 +371,17 @@ null, new ItemStack(Material.STICK, 1), null,
sticks = new ItemStack(Material.STICK, 64);
apples = new ItemStack(Material.APPLE, 64);
sugar = new ItemStack(Material.SUGAR, 64);
falseResult = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(new ItemStack[] {
falseResult = recipe.matchAs(MatchProcedure.SHAPED, Arrays.asList(
null, null, null,
null, apples, sugar,
null, sticks, null,
}));
null, sticks, null
));
Assertions.assertFalse(falseResult.itemsMatch());
result = recipe.matchAs(MatchProcedure.SHAPED_FLIPPABLE, Arrays.asList(new ItemStack[] {
result = recipe.matchAs(MatchProcedure.SHAPED_FLIPPABLE, Arrays.asList(
null, null, null,
null, apples, sugar,
null, sticks, null,
}));
null, sticks, null
));
Assertions.assertTrue(result.itemsMatch());
Assertions.assertEquals(3, result.getInputMatchResult().consumeItems(3));
Assertions.assertEquals(55, sticks.getAmount());
Expand All @@ -404,28 +404,28 @@ void testShapelessRecipeMatching() {
null, null, new ItemStack(Material.BLAZE_POWDER, 4),
new ItemStack(Material.GUNPOWDER, 3), new ItemStack(Material.COAL, 7), null,
null, null, null,
}, new ItemStack(Material.STICK), RecipeType.NULL);
}, new ItemStack[] { new ItemStack(Material.STICK) }, RecipeType.NULL);
ItemStack blazePowder = new ItemStack(Material.BLAZE_POWDER, 64);
ItemStack gunpowder = new ItemStack(Material.GUNPOWDER, 64);
ItemStack coal = new ItemStack(Material.COAL, 64);
ItemStack sticks = new ItemStack(Material.STICK, 64);

// If subset is false, then shapeless will also be false
var falseResult = recipe.matchAs(MatchProcedure.SUBSET, Arrays.asList(new ItemStack[] {
var falseResult = recipe.matchAs(MatchProcedure.SUBSET, Arrays.asList(
null, coal, null, null, null, gunpowder
}));
));
Assertions.assertFalse(falseResult.itemsMatch());
falseResult = recipe.matchAs(MatchProcedure.SHAPELESS, Arrays.asList(new ItemStack[] {
falseResult = recipe.matchAs(MatchProcedure.SHAPELESS, Arrays.asList(
null, coal, null, null, null, gunpowder, blazePowder, sticks
}));
));
Assertions.assertFalse(falseResult.itemsMatch());
var result = recipe.matchAs(MatchProcedure.SHAPELESS, Arrays.asList(new ItemStack[] {
var result = recipe.matchAs(MatchProcedure.SHAPELESS, Arrays.asList(
null, coal, null, null, null, gunpowder, blazePowder
}));
));
Assertions.assertTrue(result.itemsMatch());
result = recipe.matchAs(MatchProcedure.SUBSET, Arrays.asList(new ItemStack[] {
null, coal, null, null, null, gunpowder, blazePowder, sticks,
}));
result = recipe.matchAs(MatchProcedure.SUBSET, Arrays.asList(
null, coal, null, null, null, gunpowder, blazePowder, sticks
));
Assertions.assertTrue(result.itemsMatch());
Assertions.assertEquals(9, result.getInputMatchResult().consumeItems(9));
Assertions.assertEquals(28, blazePowder.getAmount());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package io.github.thebusybiscuit.slimefun4.core.services;

import java.util.Arrays;

import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.recipes.Recipe;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.api.recipes.matching.MatchProcedure;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.test.mocks.MockSlimefunItem;
import be.seeseemelk.mockbukkit.MockBukkit;

class TestSFRecipeService {

private static Slimefun sf;
private static ItemGroup itemGroup;
private static MockSlimefunItem testItem1;
private static MockSlimefunItem testItem2;
private static MockSlimefunItem testItem3;
private static MockSlimefunItem testItem4;
private static MockSlimefunItem testItem5;

@BeforeAll
public static void load() {
MockBukkit.mock();
sf = MockBukkit.load(Slimefun.class);
itemGroup = new ItemGroup(new NamespacedKey(sf, "test_group"), new CustomItemStack(Material.DIAMOND_AXE, "Test Group"));
testItem1 = new MockSlimefunItem(itemGroup, new ItemStack(Material.IRON_INGOT), "TEST_ITEM_1");
testItem2 = new MockSlimefunItem(itemGroup, new ItemStack(Material.IRON_INGOT), "TEST_ITEM_2");
testItem3 = new MockSlimefunItem(itemGroup, new ItemStack(Material.IRON_INGOT), "TEST_ITEM_3");
testItem4 = new MockSlimefunItem(itemGroup, new ItemStack(Material.IRON_INGOT), "TEST_ITEM_4");
testItem5 = new MockSlimefunItem(itemGroup, new ItemStack(Material.IRON_INGOT), "TEST_ITEM_5");
testItem1.register(sf);
testItem2.register(sf);
testItem3.register(sf);
testItem4.register(sf);
testItem5.register(sf);
}

@AfterAll
public static void unload() {
MockBukkit.unmock();
}

@Test
@DisplayName("Test adding recipes")
void testRecipe() {
RecipeService service = new RecipeService(sf);

Recipe recipe1 = Recipe.fromItemStacks("TEST_ITEM_1", new ItemStack[] {
null, null, null,
null, null, testItem1.getItem(),
null, null, null,
}, new ItemStack[] { testItem1.getItem() }, RecipeType.NULL);
Recipe recipe2 = Recipe.fromItemStacks("TEST_ITEM_2", new ItemStack[] {
null, null, null,
null, null, testItem1.getItem(),
testItem2.getItem(), null, null,
}, new ItemStack[] { testItem2.getItem() }, RecipeType.NULL);
Recipe recipe3 = Recipe.fromItemStacks("TEST_ITEM_3", new ItemStack[] {
null, testItem3.getItem(), null,
null, null, testItem1.getItem(),
testItem2.getItem(), null, null,
}, new ItemStack[] { testItem3.getItem() }, RecipeType.NULL);
Recipe recipe4 = Recipe.fromItemStacks("TEST_ITEM_4", new ItemStack[] {
null, testItem3.getItem(), null,
null, null, testItem1.getItem(),
testItem2.getItem(), null, null,
}, new ItemStack[] { testItem4.getItem() }, RecipeType.NULL);

service.addRecipe(recipe1);
service.addRecipe(recipe2);
service.addRecipe(recipe3);
service.addRecipe(recipe4);

Assertions.assertEquals(recipe1, service.getRecipe("TEST_ITEM_1"));
Assertions.assertEquals(recipe2, service.getRecipe("TEST_ITEM_2"));
Assertions.assertEquals(recipe3, service.getRecipe("TEST_ITEM_3"));
Assertions.assertEquals(recipe4, service.getRecipe("TEST_ITEM_4"));

ItemStack sfItem = testItem1.getItem().clone();
var search = service.searchRecipes(RecipeType.NULL, Arrays.asList(
null, null, null,
null, sfItem, null,
null, null, null
), MatchProcedure.SHAPED);
Assertions.assertTrue(search.matchFound());
var result = search.getResult().get();
Assertions.assertTrue(result.itemsMatch());
var recipe = search.getRecipe().get();
Assertions.assertEquals(recipe1, recipe);

}

}

0 comments on commit 38a30eb

Please sign in to comment.