Skip to content

Commit 25698ea

Browse files
committed
test option for creative mode, tests for full inventory
1 parent 3b01885 commit 25698ea

1 file changed

Lines changed: 97 additions & 44 deletions

File tree

src/test/java/org/spongepowered/common/recipe/RecipePlaceTest.java

Lines changed: 97 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.spongepowered.common.accessor.world.inventory.AbstractFurnaceMenuAccessor;
6161
import org.spongepowered.common.item.util.ItemStackUtil;
6262

63+
import java.util.ArrayList;
6364
import java.util.Collections;
6465
import java.util.List;
6566
import java.util.UUID;
@@ -129,12 +130,12 @@ private static Stream<TestContext> streamCraftingRecipes() {
129130
&& stack.maxStackQuantity() == bigPearl.maxStackQuantity(),
130131
pearl);
131132

132-
return Stream.of(
133-
new TestPopulator("regular_shaped_crafting", CraftingRecipe.shapedBuilder()
133+
return Stream.<TestPopulator>of(
134+
new DefaultedTestPopulator(new TestContext("regular_shaped_crafting", CraftingRecipe.shapedBuilder()
134135
.aisle("S S", " P ")
135136
.where('S', stoneIngredient)
136137
.where('P', anyPearlIngredient)
137-
.result(result))
138+
.result(result)))
138139

139140
.expectCrafts(8, 16)
140141
.expectInput(List.of(
@@ -151,11 +152,11 @@ private static Stream<TestContext> streamCraftingRecipes() {
151152
.badInventory(Collections.nCopies(9, bedrock))
152153
.badInput(Collections.nCopies(9, bedrock)),
153154

154-
new TestPopulator("custom_shaped_crafting", CraftingRecipe.shapedBuilder()
155+
new DefaultedTestPopulator(new TestContext("custom_shaped_crafting", CraftingRecipe.shapedBuilder()
155156
.aisle("SSS", "BBB", "SSS")
156157
.where('S', smallPearlIngredient)
157158
.where('B', bigPearlIngredient)
158-
.result(result))
159+
.result(result)))
159160

160161
.expectCrafts(4, 4)
161162
.expectInput(List.of(
@@ -172,8 +173,8 @@ private static Stream<TestContext> streamCraftingRecipes() {
172173
.badInventory(List.of(pearl16))
173174
.badInput(Collections.nCopies(9, pearl)),
174175

175-
new TestPopulator("regular_shapeless_crafting", CraftingRecipe.shapelessBuilder()
176-
.addIngredients(anyPearlIngredient, stoneIngredient, anyPearlIngredient))
176+
new DefaultedTestPopulator(new TestContext("regular_shapeless_crafting", CraftingRecipe.shapelessBuilder()
177+
.addIngredients(anyPearlIngredient, stoneIngredient, anyPearlIngredient)))
177178

178179
.expectCrafts(16, 16)
179180
.expectInput(List.of(
@@ -191,10 +192,10 @@ private static Stream<TestContext> streamCraftingRecipes() {
191192
.badInput(Collections.nCopies(3, bedrock))/*,
192193
193194
//TODO uncomment after shapeless recipe fix
194-
new TestPopulator("custom_shapeless_crafting", CraftingRecipe.shapelessBuilder()
195+
new DefaultedTestPopulator(new TestContext("custom_shapeless_crafting", CraftingRecipe.shapelessBuilder()
195196
.addIngredients(
196197
smallPearlIngredient, smallPearlIngredient, smallPearlIngredient,
197-
bigPearlIngredient, bigPearlIngredient, bigPearlIngredient))
198+
bigPearlIngredient, bigPearlIngredient, bigPearlIngredient)))
198199
199200
.expectCrafts(8, 16)
200201
.expectInput(List.of(
@@ -221,11 +222,11 @@ private static Stream<TestContext> streamSmeltingRecipes() {
221222
bigSnowball.offer(Keys.MAX_STACK_SIZE, 4);
222223
final ItemStack result = ItemStack.of(ItemTypes.BARRIER);
223224

224-
return Stream.of(
225-
new TestPopulator("regular_smelting", CookingRecipe.builder()
225+
return Stream.<TestPopulator>of(
226+
new DefaultedTestPopulator(new TestContext("regular_smelting", CookingRecipe.builder()
226227
.type(RecipeTypes.SMELTING)
227228
.ingredient(Ingredient.of(snowball.type()))
228-
.result(result))
229+
.result(result)))
229230

230231
.expectCrafts(4, 8)
231232
.expectInput(List.of(bigSnowball))
@@ -234,13 +235,13 @@ private static Stream<TestContext> streamSmeltingRecipes() {
234235
.badInventory(List.of(bedrock))
235236
.badInput(List.of(bedrock)),
236237

237-
new TestPopulator("custom_smelting", CookingRecipe.builder()
238+
new DefaultedTestPopulator(new TestContext("custom_smelting", CookingRecipe.builder()
238239
.type(RecipeTypes.SMELTING)
239240
.ingredient(Ingredient.of(ResourceKey.sponge("big_snowball"),
240241
stack -> stack.type() == bigSnowball.type()
241242
&& stack.maxStackQuantity() == bigSnowball.maxStackQuantity(),
242243
snowball))
243-
.result(result))
244+
.result(result)))
244245

245246
.expectCrafts(4, 8)
246247
.expectInput(List.of(bigSnowball))
@@ -252,7 +253,7 @@ private static Stream<TestContext> streamSmeltingRecipes() {
252253
}
253254

254255
@TestFactory
255-
public Stream<DynamicTest> testRecipes() {
256+
public Stream<DynamicTest> generateTests() {
256257
return Stream.of(
257258
RecipePlaceTest.streamCraftingRecipes().map(context ->
258259
dynamicTest(context.asTestName(), context::testCrafting)),
@@ -261,7 +262,38 @@ public Stream<DynamicTest> testRecipes() {
261262
).flatMap(Function.identity());
262263
}
263264

264-
private static final class TestPopulator {
265+
@FunctionalInterface
266+
private interface TestPopulator {
267+
268+
Stream<TestContext> populate();
269+
}
270+
271+
private static final class SimpleTestPopulator implements TestPopulator {
272+
273+
private final TestContext base;
274+
private final List<TestContext> tests = new ArrayList<>();
275+
276+
public SimpleTestPopulator(final TestContext base) {
277+
this.base = base;
278+
}
279+
280+
public SimpleTestPopulator add(final Function<TestContext, TestContext> testProvider) {
281+
this.tests.add(testProvider.apply(this.base));
282+
return this;
283+
}
284+
285+
public SimpleTestPopulator addAll(final Function<TestContext, Stream<TestContext>> testProvider) {
286+
testProvider.apply(this.base).forEach(this.tests::add);
287+
return this;
288+
}
289+
290+
@Override
291+
public Stream<TestContext> populate() {
292+
return this.tests.stream();
293+
}
294+
}
295+
296+
private static final class DefaultedTestPopulator implements TestPopulator {
265297

266298
private final TestContext base;
267299

@@ -280,33 +312,27 @@ private static final class TestPopulator {
280312
private List<ItemStack> badInventory = List.of();
281313
private List<ItemStack> badInput = List.of();
282314

283-
public TestPopulator(final String key, final Builder<? extends org.spongepowered.api.item.recipe.Recipe<?>, ?> recipe) {
284-
this(new RecipeHolder<>(
285-
net.minecraft.resources.ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath("sponge", key)),
286-
(Recipe<?>) recipe.build()));
287-
}
288-
289-
public TestPopulator(final RecipeHolder<?> recipe) {
290-
this.base = new TestContext(recipe);
315+
public DefaultedTestPopulator(final TestContext base) {
316+
this.base = base;
291317
}
292318

293-
public TestPopulator expectCrafts(final int regularCrafts, final int shiftCrafts) {
319+
public DefaultedTestPopulator expectCrafts(final int regularCrafts, final int shiftCrafts) {
294320
this.expectedRegularCrafts = regularCrafts;
295321
this.expectedShiftCrafts = shiftCrafts;
296322
return this;
297323
}
298324

299-
public TestPopulator expectInput(final List<ItemStack> items) {
325+
public DefaultedTestPopulator expectInput(final List<ItemStack> items) {
300326
this.expectedInput = items;
301327
return this;
302328
}
303329

304-
public TestPopulator partialInventory(final List<ItemStack> items) {
330+
public DefaultedTestPopulator partialInventory(final List<ItemStack> items) {
305331
this.partialInventory = items;
306332
return this;
307333
}
308334

309-
public TestPopulator partialInput(final List<ItemStack> items) {
335+
public DefaultedTestPopulator partialInput(final List<ItemStack> items) {
310336
this.partialInput = items;
311337
return this;
312338
}
@@ -321,6 +347,7 @@ public TestPopulator badInput(final List<ItemStack> items) {
321347
return this;
322348
}
323349

350+
@Override
324351
public Stream<TestContext> populate() {
325352
final List<ItemStack> totalInitialInventory = Stream.concat(this.partialInventory.stream(), this.partialInput.stream()).toList();
326353
final List<ItemStack> expectedShiftInput = RecipePlaceTest.createExpectedInput(this.expectedInput, this.expectedShiftCrafts);
@@ -329,28 +356,31 @@ public Stream<TestContext> populate() {
329356
this.base.name("Bad input").input(this.badInput)
330357
);
331358

332-
final Stream<TestContext> toFail = baseInputs.stream()
359+
final Stream<TestContext> testBadLayouts = baseInputs.stream()
333360
.flatMap(context -> Stream.of(
334361
context.name("Empty inventory").inventory(List.of()),
335362
context.name("Bad inventory").inventory(this.badInventory)
336363
))
337364
.flatMap(context -> Stream.of(context, context.shift()))
338-
// 2 clicks is enough to ensure we always fail
365+
.flatMap(context -> Stream.of(context, context.creative()))
366+
// 2 clicks is enough to ensure we always get empty input
339367
.map(context -> context.expectInputs(List.of(List.of(), List.of())));
340368

341-
final Stream<TestContext> toMatchSingleClick = baseInputs.stream()
369+
final Stream<TestContext> testSingleClick = baseInputs.stream()
342370
.map(context -> context.name("Total inventory").inventory(totalInitialInventory))
371+
.flatMap(context -> Stream.of(context, context.creative()))
343372
.flatMap(context -> Stream.of(
344373
context.expectInput(RecipePlaceTest.createExpectedInput(this.expectedInput, 1)),
345374
context.shift().expectInput(expectedShiftInput)
346375
));
347376

348377
// After first click we end up with the same layout no matter the initial input.
349378
// So we can perform multiple-click tests on a single input.
350-
final Stream<TestContext> toMatchMultipleClicks = Stream.of(this.base)
379+
final Stream<TestContext> testMultipleClicks = Stream.of(this.base)
351380
.map(context -> context
352381
.name("Partial input").input(this.partialInput)
353382
.name("Partial inventory").inventory(this.partialInventory))
383+
.flatMap(context -> Stream.of(context, context.creative()))
354384
.flatMap(context -> Stream.of(
355385
context
356386
.expectInputs(IntStream.rangeClosed(1, this.expectedRegularCrafts)
@@ -360,50 +390,73 @@ public Stream<TestContext> populate() {
360390
context.shift().expectInputs(List.of(expectedShiftInput, expectedShiftInput))
361391
));
362392

363-
return Stream.concat(toFail, Stream.concat(toMatchSingleClick, toMatchMultipleClicks));
393+
final Stream<TestContext> testFullInventory = Stream.of(this.base)
394+
.map(context -> context
395+
.name("Partial input").input(this.partialInput)
396+
.name("Full inventory").inventory(Collections.nCopies(36, ItemStack.of(ItemTypes.BARRIER, 64))))
397+
.flatMap(context -> Stream.of(context, context.shift()))
398+
.flatMap(context -> Stream.of(
399+
context.expectInput(this.partialInput),
400+
context.creative().expectInput(List.of())
401+
));
402+
403+
return Stream.of(testBadLayouts, testSingleClick, testMultipleClicks, testFullInventory)
404+
.flatMap(Function.identity());
364405
}
365406
}
366407

367408
private record TestContext(
368-
RecipeHolder<?> recipe, String testName, boolean shiftClick,
409+
RecipeHolder<?> recipe, String testName,
410+
boolean shiftClick, boolean creativeMode,
369411
List<ItemStack> inventory, List<ItemStack> input,
370412
List<List<ItemStack>> expectedInputs
371413
) {
414+
public TestContext(final String key, final Builder<? extends org.spongepowered.api.item.recipe.Recipe<?>, ?> recipe) {
415+
this(new RecipeHolder<>(
416+
net.minecraft.resources.ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath("sponge", key)),
417+
(Recipe<?>) recipe.build()));
418+
}
419+
372420
public TestContext(final RecipeHolder<?> recipe) {
373-
this(recipe, "", false, List.of(), List.of(), List.of());
421+
this(recipe, "", false, false, List.of(), List.of(), List.of());
374422
}
375423

376424
public TestContext name(final String testName) {
377425
final String newTestName = this.testName.isEmpty() ? testName : (this.testName + ", " + testName);
378-
return new TestContext(this.recipe, newTestName, this.shiftClick, this.inventory, this.input, this.expectedInputs);
426+
return new TestContext(this.recipe, newTestName, this.shiftClick, this.creativeMode, this.inventory, this.input, this.expectedInputs);
379427
}
380428

381429
public TestContext shift() {
382-
return new TestContext(this.recipe, this.testName, true, this.inventory, this.input, this.expectedInputs);
430+
return new TestContext(this.recipe, this.testName, true, this.creativeMode, this.inventory, this.input, this.expectedInputs);
431+
}
432+
433+
public TestContext creative() {
434+
return new TestContext(this.recipe, this.testName, this.shiftClick, true, this.inventory, this.input, this.expectedInputs);
383435
}
384436

385437
public TestContext inventory(final List<ItemStack> items) {
386-
return new TestContext(this.recipe, this.testName, this.shiftClick, items, this.input, this.expectedInputs);
438+
return new TestContext(this.recipe, this.testName, this.shiftClick, this.creativeMode, items, this.input, this.expectedInputs);
387439
}
388440

389441
public TestContext input(final List<ItemStack> items) {
390-
return new TestContext(this.recipe, this.testName, this.shiftClick, this.inventory, items, this.expectedInputs);
442+
return new TestContext(this.recipe, this.testName, this.shiftClick, this.creativeMode, this.inventory, items, this.expectedInputs);
391443
}
392444

393445
public TestContext expectInputs(final List<List<ItemStack>> expectedInputs) {
394-
return new TestContext(this.recipe, this.testName, this.shiftClick, this.inventory, this.input, expectedInputs);
446+
return new TestContext(this.recipe, this.testName, this.shiftClick, this.creativeMode, this.inventory, this.input, expectedInputs);
395447
}
396448

397449
public TestContext expectInput(final List<ItemStack> expectedInput) {
398450
return this.expectInputs(Stream.concat(this.expectedInputs.stream(), Stream.of(expectedInput)).toList());
399451
}
400452

401453
public String asTestName() {
402-
return String.format("Place recipe %s (Shift click: %s, Total clicks: %s, %s)",
454+
return String.format("Place recipe %s, %s (Shift click: %s, Creative mode: %s, Total clicks: %s)",
403455
this.recipe.id().location().getPath(),
456+
this.testName,
404457
this.shiftClick,
405-
this.expectedInputs.size(),
406-
this.testName);
458+
this.creativeMode,
459+
this.expectedInputs.size());
407460
}
408461

409462
// Tests
@@ -443,7 +496,7 @@ public void test(
443496
}
444497

445498
for (int i = 0; i < this.expectedInputs().size(); ++i) {
446-
menu.handlePlacement(this.shiftClick(), true, this.recipe(), player.serverLevel(), player.getInventory());
499+
menu.handlePlacement(this.shiftClick(), this.creativeMode(), this.recipe(), player.serverLevel(), player.getInventory());
447500

448501
final List<ItemStack> actualInput = input.slots().stream().map(Slot::peek).toList();
449502
final List<ItemStack> expectedInput = this.expectedInputs().get(i);

0 commit comments

Comments
 (0)