1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-02-03 04:39:12 +00:00

Some printer gametests

These are a little ugly, but do catch some issues we've seen in the
past. Fixes #1682 (for now), and on its birthday too!
This commit is contained in:
Jonathan Coates 2025-01-14 09:38:22 +00:00
parent 8204944b5f
commit a2b9490d5c
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
5 changed files with 287 additions and 58 deletions

View File

@ -166,8 +166,7 @@ public final class PrinterBlockEntity extends AbstractContainerBlockEntity imple
}
private boolean canInputPage() {
var inkStack = inventory.get(0);
return !inkStack.isEmpty() && isInk(inkStack) && getPaperLevel() > 0;
return getInkLevel() > 0 && getPaperLevel() > 0;
}
private boolean inputPage() {

View File

@ -4,12 +4,13 @@
package dan200.computercraft.gametest
import dan200.computercraft.gametest.api.assertBlockHas
import dan200.computercraft.gametest.api.assertExactlyItems
import dan200.computercraft.gametest.api.getBlockEntity
import dan200.computercraft.gametest.api.sequence
import dan200.computercraft.api.lua.Coerced
import dan200.computercraft.api.lua.LuaException
import dan200.computercraft.gametest.api.*
import dan200.computercraft.shared.ModRegistry
import dan200.computercraft.shared.media.items.PrintoutItem
import dan200.computercraft.shared.peripheral.printer.PrinterBlock
import dan200.computercraft.shared.peripheral.printer.PrinterPeripheral
import net.minecraft.core.BlockPos
import net.minecraft.gametest.framework.GameTest
import net.minecraft.gametest.framework.GameTestHelper
@ -17,10 +18,12 @@ import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.level.block.RedStoneWireBlock
import org.junit.jupiter.api.Assertions.*
import java.util.*
class Printer_Test {
/**
* Check comparators can read the contents of the disk drive
* Check comparators can read the contents of the printer
*/
@GameTest
fun Comparator(helper: GameTestHelper) = helper.sequence {
@ -29,19 +32,19 @@ class Printer_Test {
// Adding items should provide power
thenExecute {
val drive = helper.getBlockEntity(printerPos, ModRegistry.BlockEntities.PRINTER.get())
drive.setItem(0, ItemStack(Items.BLACK_DYE))
drive.setItem(1, ItemStack(Items.PAPER))
drive.setChanged()
val printer = helper.getBlockEntity(printerPos, ModRegistry.BlockEntities.PRINTER.get())
printer.setItem(0, ItemStack(Items.BLACK_DYE))
printer.setItem(1, ItemStack(Items.PAPER))
printer.setChanged()
}
thenIdle(2)
thenExecute { helper.assertBlockHas(dustPos, RedStoneWireBlock.POWER, 1) }
// And removing them should reset power.
thenExecute {
val drive = helper.getBlockEntity(printerPos, ModRegistry.BlockEntities.PRINTER.get())
drive.clearContent()
drive.setChanged()
val printer = helper.getBlockEntity(printerPos, ModRegistry.BlockEntities.PRINTER.get())
printer.clearContent()
printer.setChanged()
}
thenIdle(2)
thenExecute { helper.assertBlockHas(dustPos, RedStoneWireBlock.POWER, 0) }
@ -50,35 +53,125 @@ class Printer_Test {
/**
* Changing the inventory contents updates the block state
*/
@GameTest
@GameTest(template = "printer_test.empty")
fun Contents_updates_state(helper: GameTestHelper) = helper.sequence {
val pos = BlockPos(2, 2, 2)
thenExecute {
val drive = helper.getBlockEntity(pos, ModRegistry.BlockEntities.PRINTER.get())
val printer = helper.getBlockEntity(pos, ModRegistry.BlockEntities.PRINTER.get())
drive.setItem(1, ItemStack(Items.PAPER))
drive.setChanged()
printer.setItem(1, ItemStack(Items.PAPER))
printer.setChanged()
helper.assertBlockHas(pos, PrinterBlock.TOP, true, message = "One item in the top row")
helper.assertBlockHas(pos, PrinterBlock.BOTTOM, false, message = "One item in the top row")
drive.setItem(7, ItemStack(Items.PAPER))
drive.setChanged()
printer.setItem(7, ItemStack(Items.PAPER))
printer.setChanged()
helper.assertBlockHas(pos, PrinterBlock.TOP, true, message = "One item in each row")
helper.assertBlockHas(pos, PrinterBlock.BOTTOM, true, message = "One item in each row")
drive.setItem(1, ItemStack.EMPTY)
drive.setChanged()
printer.setItem(1, ItemStack.EMPTY)
printer.setChanged()
helper.assertBlockHas(pos, PrinterBlock.TOP, false, message = "One item in the bottom")
helper.assertBlockHas(pos, PrinterBlock.BOTTOM, true, message = "One item in the bottom row")
drive.setItem(7, ItemStack.EMPTY)
drive.setChanged()
printer.setItem(7, ItemStack.EMPTY)
printer.setChanged()
helper.assertBlockHas(pos, PrinterBlock.TOP, false, message = "Empty")
helper.assertBlockHas(pos, PrinterBlock.BOTTOM, false, message = "Empty")
}
}
/**
* Printing a page
*/
@GameTest(template = "printer_test.empty")
fun Print_page(helper: GameTestHelper) = helper.sequence {
val pos = BlockPos(2, 2, 2)
thenExecute {
val printer = helper.getBlockEntity(pos, ModRegistry.BlockEntities.PRINTER.get())
val peripheral = printer.peripheral() as PrinterPeripheral
// Try to print with no pages
assertFalse(peripheral.newPage(), "newPage fails with no items")
// Try to print with just ink
printer.setItem(0, ItemStack(Items.BLUE_DYE))
printer.setChanged()
assertFalse(peripheral.newPage(), "newPage fails with no paper")
printer.clearContent()
// Try to print with just paper
printer.setItem(1, ItemStack(Items.PAPER))
printer.setChanged()
assertFalse(peripheral.newPage(), "newPage fails with no ink")
printer.clearContent()
// Try to print with both items
printer.setItem(0, ItemStack(Items.BLUE_DYE))
printer.setItem(1, ItemStack(Items.PAPER))
printer.setChanged()
assertTrue(peripheral.newPage(), "newPage succeeds")
// newPage() should consume both items and update the block state
helper.assertContainerEmpty(pos)
helper.assertBlockHas(pos, PrinterBlock.TOP, false, message = "Empty")
helper.assertBlockHas(pos, PrinterBlock.BOTTOM, false, message = "Empty")
assertFalse(peripheral.newPage(), "Cannot start a page when already printing")
peripheral.setPageTitle(Optional.of("New Page"))
peripheral.write(Coerced("Hello, world!"))
peripheral.setCursorPos(5, 2)
peripheral.write(Coerced("Second line"))
// Try to finish the page
assertTrue(peripheral.endPage(), "endPage prints item")
// endPage() should
helper.assertBlockHas(pos, PrinterBlock.TOP, false, message = "Empty")
helper.assertBlockHas(pos, PrinterBlock.BOTTOM, true, message = "Has pages")
// And check the inventory matches
val lines = createPageOf(' ')
lines[0] = "Hello, world! "
lines[1] = " Second line "
helper.assertContainerExactly(
pos,
listOf(
// Ink
ItemStack.EMPTY,
// Paper
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
// Pages
PrintoutItem.createSingleFromTitleAndText("New Page", lines, createPageOf('b')),
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
),
)
val error = assertThrows(LuaException::class.java) { peripheral.endPage() }
assertEquals("Page not started", error.message)
}
}
/**
* Can't print when full.
*/
@GameTest
fun No_print_when_full(helper: GameTestHelper) = helper.sequence {
val pos = BlockPos(2, 2, 2)
thenExecute {
val printer = helper.getBlockEntity(pos, ModRegistry.BlockEntities.PRINTER.get())
val peripheral = printer.peripheral() as PrinterPeripheral
assertTrue(peripheral.newPage())
assertFalse(peripheral.endPage(), "Cannot print when full")
}
}
/**
* When the block is broken, we drop the contents and an optionally named stack.
*/
@ -94,4 +187,9 @@ class Printer_Test {
)
}
}
private fun createPageOf(c: Char): Array<String> {
val line = c.toString().repeat(PrintoutItem.LINE_MAX_LENGTH)
return Array(PrintoutItem.LINES_PER_PAGE) { line }
}
}

View File

@ -29,7 +29,6 @@ import dan200.computercraft.shared.util.WaterloggableHelpers
import dan200.computercraft.test.core.assertArrayEquals
import dan200.computercraft.test.core.computer.LuaTaskContext
import dan200.computercraft.test.core.computer.getApi
import dan200.computercraft.test.shared.ItemStackMatcher.isStack
import net.minecraft.core.BlockPos
import net.minecraft.gametest.framework.GameTest
import net.minecraft.gametest.framework.GameTestHelper
@ -46,7 +45,8 @@ import net.minecraft.world.level.block.FenceBlock
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.*
import org.hamcrest.Matchers.array
import org.hamcrest.Matchers.instanceOf
import org.junit.jupiter.api.Assertions.*
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
@ -138,7 +138,7 @@ class Turtle_Test {
)
}
thenExecute {
helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.COMPOSTER && it.getValue(ComposterBlock.LEVEL) == 2 }
helper.assertBlockHas(BlockPos(2, 2, 2), ComposterBlock.LEVEL, 2)
}
}
@ -154,7 +154,7 @@ class Turtle_Test {
.assertArrayEquals(false, "Cannot place item here", message = "Failed to place item")
}
thenExecute {
helper.assertBlockIs(BlockPos(2, 2, 3)) { it.block == Blocks.COMPOSTER && it.getValue(ComposterBlock.LEVEL) == 0 }
helper.assertBlockHas(BlockPos(2, 2, 3), ComposterBlock.LEVEL, 0)
}
}
@ -175,7 +175,7 @@ class Turtle_Test {
)
}
thenExecute {
helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.BEEHIVE && it.getValue(BeehiveBlock.HONEY_LEVEL) == 0 }
helper.assertBlockHas(BlockPos(2, 2, 2), BeehiveBlock.HONEY_LEVEL, 0)
}
}
@ -765,15 +765,13 @@ class Turtle_Test {
callPeripheral("left", "craft", 1).assertArrayEquals(true)
}
thenExecute {
val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get())
assertThat(
"Inventory is as expected.",
turtle.contents,
contains(
isStack(Items.DIAMOND, 1), isStack(Items.DIAMOND, 1), isStack(Items.DIAMOND, 1), isStack(Items.DIAMOND_PICKAXE, 1),
isStack(ItemStack.EMPTY), isStack(Items.STICK, 1), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(Items.STICK, 1), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
helper.assertContainerExactly(
BlockPos(2, 2, 2),
listOf(
ItemStack(Items.DIAMOND), ItemStack(Items.DIAMOND), ItemStack(Items.DIAMOND), ItemStack(Items.DIAMOND_PICKAXE),
ItemStack.EMPTY, ItemStack(Items.STICK), ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack(Items.STICK), ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
),
)
}
@ -786,23 +784,20 @@ class Turtle_Test {
*/
@GameTest
fun Craft_remainder(helper: GameTestHelper) = helper.sequence {
thenOnComputer {
callPeripheral("left", "craft", 1).assertArrayEquals(true)
}
thenExecute {
val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get())
assertTrue(TurtleCraftCommand(1).execute(turtle.access).isSuccess, "Crafting succeeded")
val turtleStack = ItemStack(ModRegistry.Items.TURTLE_NORMAL.get())
turtleStack.orCreateTag
assertThat(
"Inventory is as expected.",
turtle.contents,
contains(
isStack(turtleStack), isStack(Items.WET_SPONGE, 1), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
helper.assertContainerExactly(
BlockPos(2, 2, 2),
listOf(
turtleStack, ItemStack(Items.WET_SPONGE), ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
),
)
}
@ -817,7 +812,8 @@ class Turtle_Test {
fun Craft_offset(helper: GameTestHelper) = helper.sequence {
for (offset in listOf(0, 1, 4, 5)) {
thenExecute {
val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get())
val turtlePos = BlockPos(2, 2, 2)
val turtle = helper.getBlockEntity(turtlePos, ModRegistry.BlockEntities.TURTLE_NORMAL.get())
// Set up turtle inventory
turtle.clearContent()
@ -831,14 +827,13 @@ class Turtle_Test {
assertTrue(TurtleCraftCommand(1).execute(turtle.access).isSuccess, "Crafting succeeded")
// And check item was crafted
assertThat(
"Inventory is as expected.",
turtle.contents,
contains(
isStack(Items.STONE_PICKAXE, 1), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY),
helper.assertContainerExactly(
turtlePos,
listOf(
ItemStack(Items.STONE_PICKAXE), ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY,
),
)
}

File diff suppressed because one or more lines are too long