Skip to content

Commit 5534f54

Browse files
committed
make tests more flexible
1 parent 0733598 commit 5534f54

File tree

1 file changed

+75
-29
lines changed

1 file changed

+75
-29
lines changed

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

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,13 @@ public Stream<TestContext> populate() {
336336
))
337337
.flatMap(context -> Stream.of(context, context.shift()))
338338
// 2 clicks is enough to ensure we always fail
339-
.map(context -> context.expectInputs(List.of(List.of(), List.of())));
339+
.map(context -> context.clicks(2).expectInputs(List.of(List.of(), List.of())));
340340

341341
final Stream<TestContext> toMatchSingleClick = baseInputs.stream()
342342
.map(context -> context.name("Total inventory").inventory(totalInitialInventory))
343343
.flatMap(context -> Stream.of(
344-
context.expectInput(RecipePlaceTest.createExpectedInput(this.expectedInput, 1)),
345-
context.shift().expectInput(expectedShiftInput)
344+
context.expectInputAt(0, RecipePlaceTest.createExpectedInput(this.expectedInput, 1)),
345+
context.shift().expectInputAt(0, expectedShiftInput)
346346
));
347347

348348
// After first click we end up with the same layout no matter the initial input.
@@ -353,56 +353,82 @@ public Stream<TestContext> populate() {
353353
.name("Partial inventory").inventory(this.partialInventory))
354354
.flatMap(context -> Stream.of(
355355
context
356-
.expectInputs(IntStream.rangeClosed(1, this.expectedRegularCrafts)
357-
.mapToObj(clicks -> RecipePlaceTest.createExpectedInput(this.expectedInput, clicks))
358-
.toList())
359-
.expectInput(RecipePlaceTest.createExpectedInput(this.expectedInput, this.expectedRegularCrafts)),
360-
context.shift().expectInputs(List.of(expectedShiftInput, expectedShiftInput))
356+
.clicks(this.expectedRegularCrafts+1)
357+
.expectInputs(Stream.concat(
358+
IntStream.rangeClosed(1, this.expectedRegularCrafts)
359+
.mapToObj(clicks -> RecipePlaceTest.createExpectedInput(this.expectedInput, clicks)),
360+
Stream.of(RecipePlaceTest.createExpectedInput(this.expectedInput, this.expectedRegularCrafts))
361+
).toList()),
362+
context.shift().clicks(2).expectInputs(List.of(expectedShiftInput, expectedShiftInput))
361363
));
362364

363365
return Stream.concat(toFail, Stream.concat(toMatchSingleClick, toMatchMultipleClicks));
364366
}
365367
}
366368

367369
private record TestContext(
368-
RecipeHolder<?> recipe, String testName, boolean shiftClick,
370+
RecipeHolder<?> recipe, String testName,
371+
boolean shiftClick, int clicks,
369372
List<ItemStack> inventory, List<ItemStack> input,
370-
List<List<ItemStack>> expectedInputs
373+
List<TestEntry> tests
371374
) {
372375
public TestContext(final RecipeHolder<?> recipe) {
373-
this(recipe, "", false, List.of(), List.of(), List.of());
376+
this(recipe, "", false, 1, List.of(), List.of(), List.of());
374377
}
375378

376379
public TestContext name(final String testName) {
377380
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);
381+
return new TestContext(this.recipe, newTestName, this.shiftClick, this.clicks, this.inventory, this.input, this.tests);
379382
}
380383

381384
public TestContext shift() {
382-
return new TestContext(this.recipe, this.testName, true, this.inventory, this.input, this.expectedInputs);
385+
return new TestContext(this.recipe, this.testName, true, this.clicks, this.inventory, this.input, this.tests);
386+
}
387+
388+
public TestContext clicks(final int clicks) {
389+
return new TestContext(this.recipe, this.testName, this.shiftClick, clicks, this.inventory, this.input, this.tests);
383390
}
384391

385392
public TestContext inventory(final List<ItemStack> items) {
386-
return new TestContext(this.recipe, this.testName, this.shiftClick, items, this.input, this.expectedInputs);
393+
return new TestContext(this.recipe, this.testName, this.shiftClick, this.clicks, items, this.input, this.tests);
387394
}
388395

389396
public TestContext input(final List<ItemStack> items) {
390-
return new TestContext(this.recipe, this.testName, this.shiftClick, this.inventory, items, this.expectedInputs);
397+
return new TestContext(this.recipe, this.testName, this.shiftClick, this.clicks, this.inventory, items, this.tests);
391398
}
392399

393-
public TestContext expectInputs(final List<List<ItemStack>> expectedInputs) {
394-
return new TestContext(this.recipe, this.testName, this.shiftClick, this.inventory, this.input, expectedInputs);
400+
public TestContext test(final TestEntry test) {
401+
final List<TestEntry> newTests = Stream.concat(this.tests.stream(), Stream.of(test)).toList();
402+
return new TestContext(this.recipe, this.testName, this.shiftClick, this.clicks, this.inventory, this.input, newTests);
403+
}
404+
405+
public TestContext testAt(final int clickToTest, final TestEntry test) {
406+
return this.test((context, input, click) -> {
407+
if (click != clickToTest) {
408+
return true;
409+
}
410+
411+
return test.test(context, input, click);
412+
});
395413
}
396414

397-
public TestContext expectInput(final List<ItemStack> expectedInput) {
398-
return this.expectInputs(Stream.concat(this.expectedInputs.stream(), Stream.of(expectedInput)).toList());
415+
public TestContext expectInputAt(final int clickToTest, final List<ItemStack> expectedInput) {
416+
return this.testAt(clickToTest, TestEntry.matchInput(expectedInput));
417+
}
418+
419+
public TestContext expectInputs(final List<List<ItemStack>> expectedInputs) {
420+
TestContext test = this;
421+
for (int i = 0; i < expectedInputs.size(); ++i) {
422+
test = test.expectInputAt(i, expectedInputs.get(i));
423+
}
424+
return test;
399425
}
400426

401427
public String asTestName() {
402428
return String.format("Place recipe %s (Shift click: %s, Total clicks: %s, %s)",
403429
this.recipe.id().location().getPath(),
404430
this.shiftClick,
405-
this.expectedInputs.size(),
431+
this.clicks,
406432
this.testName);
407433
}
408434

@@ -442,34 +468,54 @@ public void test(
442468
input.set(i, initialInput.get(i));
443469
}
444470

445-
for (int i = 0; i < this.expectedInputs().size(); ++i) {
471+
for (int i = 0; i < this.clicks(); ++i) {
446472
menu.handlePlacement(this.shiftClick(), true, this.recipe(), player.serverLevel(), player.getInventory());
473+
for (final TestEntry test : this.tests()) {
474+
if (!test.test(this, input, i)) {
475+
break;
476+
}
477+
}
478+
}
479+
}
480+
}
447481

482+
@FunctionalInterface
483+
private interface TestEntry {
484+
485+
static TestEntry matchInput(final List<ItemStack> expectedInput) {
486+
return (context, input, click) -> {
448487
final List<ItemStack> actualInput = input.slots().stream().map(Slot::peek).toList();
449-
final List<ItemStack> expectedInput = this.expectedInputs().get(i);
450-
final int click = i+1;
451488
for (int j = 0; j < actualInput.size(); ++j) {
452489
final ItemStack actualStack = actualInput.get(j);
453490
final ItemStack expectedStack = expectedInput.size() <= j ? ItemStack.empty() : expectedInput.get(j);
454491
assertTrue(net.minecraft.world.item.ItemStack.matches(
455492
ItemStackUtil.toNative(actualStack), ItemStackUtil.toNative(expectedStack)),
456493
() -> String.format("""
457-
Actual input doesn't match expected input after click %s
494+
Actual input doesn't match expected input after click %s
458495
Test: %s,
459496
Expected input: %s
460497
Actual input: %s
461498
Initial input: %s
462499
Initial inventory: %s""",
463-
click,
464-
this.asTestName(),
500+
click+1,
501+
context.asTestName(),
465502
RecipePlaceTest.stacksToString(false, expectedInput),
466503
RecipePlaceTest.stacksToString(false, actualInput),
467-
RecipePlaceTest.stacksToString(false, initialInput),
468-
RecipePlaceTest.stacksToString(true, initialInventory)
504+
RecipePlaceTest.stacksToString(false, context.input()),
505+
RecipePlaceTest.stacksToString(true, context.inventory())
469506
));
470507
}
471-
}
508+
509+
return true;
510+
};
472511
}
512+
513+
/**
514+
* Performs the test on recipe input after each placement. Clicks start at 0.
515+
*
516+
* @return True if the following tests should be performed within the given click
517+
*/
518+
boolean test(TestContext context, Inventory input, int click);
473519
}
474520

475521
private static final class FakePlayer extends ServerPlayer {

0 commit comments

Comments
 (0)