1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-12-14 04:00:30 +00:00

Rethink how computers run tests in game

Instead of using ids for each computer each computer is spawned with id
0 but has a label which matches up to its test name. This has several
advantages:

 - No more confusing IDs: the test code now just does thenComputerOk()
   and that's it - the computer to track is inferred from the test name.
 - All files are stored on one computer, which means we can write code
   which is shared between tests.
This commit is contained in:
Jonathan Coates 2021-08-20 16:44:56 +01:00
parent 0ff6b0ca70
commit 56010382fb
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
43 changed files with 104 additions and 120 deletions

View File

@ -10,5 +10,5 @@ class CraftOs_Test {
* Sends a rednet message to another a computer and back again.
*/
@GameTest
fun Sends_basic_rednet_messages(context: GameTestHelper) = context.sequence { thenComputerOk(13) }
fun Sends_basic_rednet_messages(context: GameTestHelper) = context.sequence { thenComputerOk("main") }
}

View File

@ -11,13 +11,13 @@ class Disk_Drive_Test {
* @see [#688](https://github.com/SquidDev-CC/CC-Tweaked/issues/688)
*/
@GameTest
fun Audio_disk(helper: GameTestHelper) = helper.sequence { thenComputerOk(3) }
fun Audio_disk(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
@GameTest
fun Ejects_disk(helper: GameTestHelper) = helper.sequence {
val stackAt = BlockPos(2, 2, 2)
this
.thenComputerOk(4)
.thenComputerOk()
.thenWaitUntil { helper.assertItemEntityPresent(Items.MUSIC_DISC_13, stackAt, 0.0) }
}
}

View File

@ -7,19 +7,19 @@ import net.minecraft.util.math.BlockPos
class Modem_Test {
@GameTest
fun Have_peripherals(helper: GameTestHelper) = helper.sequence { thenComputerOk(15) }
fun Have_peripherals(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
@GameTest
fun Gains_peripherals(helper: GameTestHelper) = helper.sequence {
val position = BlockPos(2, 2, 2)
this
.thenComputerOk(16, "initial")
.thenComputerOk(marker = "initial")
.thenExecute {
helper.setBlock(position, BlockCable.correctConnections(
helper.level, helper.absolutePos(position),
Registry.ModBlocks.CABLE.get().defaultBlockState().setValue(BlockCable.CABLE, true)
))
}
.thenComputerOk(16)
.thenComputerOk()
}
}

View File

@ -7,7 +7,7 @@ import dan200.computercraft.ingame.api.thenComputerOk
class Turtle_Test {
@GameTest(timeoutTicks = TIMEOUT)
fun Unequip_refreshes_peripheral(helper: GameTestHelper) = helper.sequence { thenComputerOk(1) }
fun Unequip_refreshes_peripheral(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can sheer sheep (and drop items)
@ -15,7 +15,7 @@ class Turtle_Test {
* @see [#537](https://github.com/SquidDev-CC/CC-Tweaked/issues/537)
*/
@GameTest(timeoutTicks = TIMEOUT)
fun Shears_sheep(helper: GameTestHelper) = helper.sequence { thenComputerOk(5) }
fun Shears_sheep(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can place lava.
@ -23,7 +23,7 @@ class Turtle_Test {
* @see [#518](https://github.com/SquidDev-CC/CC-Tweaked/issues/518)
*/
@GameTest(timeoutTicks = TIMEOUT)
fun Place_lava(helper: GameTestHelper) = helper.sequence { thenComputerOk(5) }
fun Place_lava(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can place when waterlogged.
@ -31,7 +31,7 @@ class Turtle_Test {
* @see [#385](https://github.com/SquidDev-CC/CC-Tweaked/issues/385)
*/
@GameTest(timeoutTicks = TIMEOUT)
fun Place_waterlogged(helper: GameTestHelper) = helper.sequence { thenComputerOk(7) }
fun Place_waterlogged(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can pick up lava
@ -39,7 +39,7 @@ class Turtle_Test {
* @see [#297](https://github.com/SquidDev-CC/CC-Tweaked/issues/297)
*/
@GameTest(timeoutTicks = TIMEOUT)
fun Gather_lava(helper: GameTestHelper) = helper.sequence { thenComputerOk(8) }
fun Gather_lava(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can hoe dirt.
@ -47,7 +47,7 @@ class Turtle_Test {
* @see [#258](https://github.com/SquidDev-CC/CC-Tweaked/issues/258)
*/
@GameTest(timeoutTicks = TIMEOUT)
fun Hoe_dirt(helper: GameTestHelper) = helper.sequence { thenComputerOk(9) }
fun Hoe_dirt(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can place monitors
@ -55,14 +55,14 @@ class Turtle_Test {
* @see [#691](https://github.com/SquidDev-CC/CC-Tweaked/issues/691)
*/
@GameTest(timeoutTicks = TIMEOUT)
fun Place_monitor(helper: GameTestHelper) = helper.sequence { thenComputerOk(10) }
fun Place_monitor(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can place into compostors. These are non-typical inventories, so
* worth testing.
*/
@GameTest(timeoutTicks = TIMEOUT)
fun Use_compostors(helper: GameTestHelper) = helper.sequence { thenComputerOk(11) }
fun Use_compostors(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
/**
* Checks turtles can be cleaned in cauldrons.
@ -70,7 +70,7 @@ class Turtle_Test {
* Currently not required as turtles can no longer right-click cauldrons.
*/
@GameTest
fun Cleaned_with_cauldrons(helper: GameTestHelper) = helper.sequence { thenComputerOk(12) }
fun Cleaned_with_cauldrons(helper: GameTestHelper) = helper.sequence { thenComputerOk() }
companion object {
const val TIMEOUT = 200

View File

@ -18,13 +18,13 @@ import java.util.concurrent.ConcurrentHashMap;
* Assertion state of a computer.
*
* @see TestAPI For the Lua interface for this.
* @see TestExtensionsKt#thenComputerOk(TestList, int, String)
* @see TestExtensionsKt#thenComputerOk(TestList, String, String)
*/
public class ComputerState
{
public static final String DONE = "DONE";
protected static final Map<Integer, ComputerState> lookup = new ConcurrentHashMap<>();
protected static final Map<String, ComputerState> lookup = new ConcurrentHashMap<>();
protected final Set<String> markers = new HashSet<>();
protected String error;
@ -40,8 +40,8 @@ public class ComputerState
if( error != null ) throw new RuntimeException( error );
}
public static ComputerState get( int id )
public static ComputerState get( String label )
{
return lookup.get( id );
return lookup.get( label );
}
}

View File

@ -21,13 +21,15 @@ import javax.imageio.ImageIO
/**
* Wait until a computer has finished running and check it is OK.
*/
fun GameTestSequence.thenComputerOk(id: Int, marker: String = ComputerState.DONE): GameTestSequence =
thenWaitUntil {
val computer = ComputerState.get(id)
if (computer == null || !computer.isDone(marker)) throw GameTestAssertException("Computer #${id} has not finished yet.")
fun GameTestSequence.thenComputerOk(name: String? = null, marker: String = ComputerState.DONE): GameTestSequence {
val label = parent.testName + (if (name == null) "" else ".$name")
return this.thenWaitUntil {
val computer = ComputerState.get(label)
if (computer == null || !computer.isDone(marker)) throw GameTestAssertException("Computer '$label' has not finished yet.")
}.thenExecute {
ComputerState.get(id).check(marker)
ComputerState.get(label).check(marker)
}
}
/**
* Run a task on the client

View File

@ -21,31 +21,39 @@ import java.util.Optional;
*
* Note, we extend this API within startup file of computers (see {@code cctest.lua}).
*
* @see TestExtensionsKt#thenComputerOk(TestList, int, String) To check tests on the computer have passed.
* @see TestExtensionsKt#thenComputerOk(TestList, String, String) To check tests on the computer have passed.
*/
public class TestAPI extends ComputerState implements ILuaAPI
{
private final int id;
private final IComputerSystem system;
private String label;
TestAPI( IComputerSystem system )
{
id = system.getID();
this.system = system;
}
@Override
public void startup()
{
ComputerCraft.log.info( "Computer #{} has turned on.", id );
if( label == null ) label = system.getLabel();
if( label == null )
{
label = "#" + system.getID();
ComputerCraft.log.warn( "Computer {} has no label", label );
}
ComputerCraft.log.info( "Computer '{}' has turned on.", label );
markers.clear();
error = null;
lookup.put( id, this );
lookup.put( label, this );
}
@Override
public void shutdown()
{
ComputerCraft.log.info( "Computer #{} has shut down.", id );
if( lookup.get( id ) == this ) lookup.remove( id );
ComputerCraft.log.info( "Computer '{}' has shut down.", label );
if( lookup.get( label ) == this ) lookup.remove( label );
}
@Override
@ -57,7 +65,7 @@ public class TestAPI extends ComputerState implements ILuaAPI
@LuaFunction
public final void fail( String message ) throws LuaException
{
ComputerCraft.log.error( "Computer #{} failed with {}", id, message );
ComputerCraft.log.error( "Computer '{}' failed with {}", label, message );
if( markers.contains( ComputerState.DONE ) ) throw new LuaException( "Cannot call fail/ok multiple times." );
markers.add( ComputerState.DONE );
error = message;
@ -79,6 +87,6 @@ public class TestAPI extends ComputerState implements ILuaAPI
@LuaFunction
public final void log( String message )
{
ComputerCraft.log.info( "[Computer #{}] {}", id, message );
ComputerCraft.log.info( "[Computer '{}'] {}", label, message );
}
}

View File

@ -10,6 +10,7 @@ import net.minecraft.command.CommandSource;
import net.minecraft.server.MinecraftServer;
import net.minecraft.test.*;
import net.minecraft.util.Rotation;
import net.minecraft.util.SharedConstants;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
@ -74,7 +75,7 @@ public class TestHooks
countdown--;
if( countdown == 0 && System.getProperty( "cctest.run", "false" ).equals( "true" ) ) startTests();
TestCollection.singleton.tick();
if( !SharedConstants.IS_RUNNING_IN_IDE ) TestCollection.singleton.tick();
if( runningTests != null && runningTests.isDone() ) finishTests();
}

View File

@ -0,0 +1,11 @@
local label = os.getComputerLabel()
if label == nil then return test.fail("Label a computer to use it.") end
local fn, err = loadfile("tests/" .. label .. ".lua", nil, _ENV)
if not fn then return test.fail(err) end
local ok, err = pcall(fn)
if not ok then return test.fail(err) end
print("Run " .. label)
test.ok()

View File

@ -1,4 +1,5 @@
-- CraftOsTest.`Sends basic rednet messages`
os.getComputerID = function() return 1 end
os.computerID = os.getComputerID
rednet.open("top")
while true do

View File

@ -0,0 +1,10 @@
rednet.open("top")
local id, msg
repeat
rednet.send(1, "Test msg") -- Keep sending, as other computer may not have started yet.
id, msg = rednet.receive(nil, 1)
until id == 1
test.eq("Test msg", msg)

View File

@ -1,5 +1,2 @@
-- DiskDriveTest.`Audio disk`
test.eq(true, disk.hasAudio("right"), "Has audio")
test.eq("C418 - 13", disk.getAudioTitle("right"), "Audio title")
test.ok()

View File

@ -0,0 +1 @@
disk.eject("right")

View File

@ -1,5 +1,3 @@
-- Modem_test.Gains_peripherals
local function check_peripherals(expected, msg)
local peripherals = peripheral.getNames()
table.sort(peripherals)
@ -18,5 +16,3 @@ check_peripherals({
"monitor_1",
"printer_1",
}, "Gains new peripherals")
test.ok()

View File

@ -1,5 +1,3 @@
-- Modem_test.Have_peripherals
local function check_peripherals(expected, msg)
local peripherals = peripheral.getNames()
table.sort(peripherals)
@ -12,5 +10,3 @@ check_peripherals({
"printer_0",
"right",
}, "Starts with peripherals")
test.ok()

View File

@ -1,5 +1,3 @@
-- TurtleTest.`Cleaned with cauldrons`
local old_details = turtle.getItemDetail(1, true)
test.assert(turtle.place(), "Dyed turtle")
@ -7,5 +5,3 @@ test.assert(turtle.place(), "Dyed turtle")
local new_details = turtle.getItemDetail(1, true)
test.eq("computercraft:turtle_normal", new_details.name, "Still a turtle")
test.neq(old_details.nbt, new_details.nbt, "Colour has changed")
test.ok()

View File

@ -1,5 +1,3 @@
-- TurtleTest.`Gather lava`
turtle.placeDown()
local item = turtle.getItemDetail()
@ -7,5 +5,3 @@ test.eq("minecraft:lava_bucket", item.name)
local has_down, down = turtle.inspectDown()
test.eq(false, has_down, "Air below")
test.ok()

View File

@ -1,9 +1,5 @@
-- Turtle.`Hoe dirt`
test.assert(turtle.dig())
local has_block, block = turtle.inspect()
test.assert(has_block, "Has block")
test.eq("minecraft:farmland", block.name)
test.ok()

View File

@ -1,9 +1,5 @@
-- TurtleTest.`Lava place`
test.assert(turtle.placeDown())
local ok, down = turtle.inspectDown()
test.assert(ok, "Has below")
test.eq("minecraft:lava", down.name, "Is lava")
test.ok()

View File

@ -1,10 +1,6 @@
-- Turtle.`Place Monitor`
test.assert(turtle.place())
local has_block, block = turtle.inspect()
test.assert(has_block, "Has block")
test.eq("computercraft:monitor_advanced", block.name)
test.eq("lr", block.state.state)
test.ok()

View File

@ -1,10 +1,6 @@
-- TurtleTest.`Place Waterlogged`
test.assert(turtle.place())
local has_block, block = turtle.inspect()
test.eq(true, has_block, "Has block")
test.eq("minecraft:oak_fence", block.name)
test.eq(true, block.state.waterlogged)
test.ok()

View File

@ -1,7 +1,3 @@
-- TurtleTest.`Unequip refreshes peripheral`
test.eq("modem", peripheral.getType("right"), "Starts with a modem")
turtle.equipRight()
test.eq("drive", peripheral.getType("right"), "Unequipping gives a drive")
test.ok()

View File

@ -1,5 +1 @@
-- TurtleTest.`Use compostors`
test.eq(true, turtle.dropDown(), "Drop items into compostor")
test.ok()

View File

@ -1,14 +0,0 @@
-- CraftOsTest.`Sends basic rednet messages`
rednet.open("top")
local id, msg
repeat
rednet.send(14, "Test msg") -- Keep sending, as other computer may not have started yet.
id, msg = rednet.receive(nil, 1)
print(id, msg)
until id == 14
test.eq("Test msg", msg)
test.ok()

View File

@ -1,4 +0,0 @@
-- DiskDriveTest.`Ejects disk`
disk.eject("right")
test.ok()

View File

@ -1,5 +1,5 @@
{
"computer": 16,
"computer": 0,
"peripheral.monitor": 1,
"peripheral.printer": 1
}

View File

@ -11,7 +11,7 @@ enforce-whitelist=false
force-gamemode=false
function-permission-level=2
gamemode=creative
generate-structures=true
generate-structures=false
generator-settings=
hardcore=false
level-name=world

View File

@ -109,7 +109,8 @@
{
nbt: {
id: "computercraft:computer_advanced",
ComputerId: 2,
Label: "computer_test.no_through_signal",
ComputerId: 0,
On: 1b
},
pos: [2, 1, 2],

View File

@ -104,9 +104,9 @@
},
{
nbt: {
Label: "Echo",
Label: "craftos_test.sends_basic_rednet_messages.echo",
id: "computercraft:computer_advanced",
ComputerId: 14,
ComputerId: 0,
On: 1b
},
pos: [1, 1, 2],
@ -114,9 +114,9 @@
},
{
nbt: {
Label: "Main",
Label: "craftos_test.sends_basic_rednet_messages.main",
id: "computercraft:computer_advanced",
ComputerId: 13,
ComputerId: 0,
On: 1b
},
pos: [3, 1, 2],

View File

@ -52,7 +52,8 @@
{
nbt: {
id: "computercraft:computer_advanced",
ComputerId: 3,
Label: "disk_drive_test.audio_disk",
ComputerId: 0,
On: 1b
},
pos: [1, 1, 1],

View File

@ -172,7 +172,8 @@
{
nbt: {
id: "computercraft:computer_advanced",
ComputerId: 4,
Label: "disk_drive_test.ejects_disk",
ComputerId: 0,
On: 1b
},
pos: [3, 1, 1],

View File

@ -607,7 +607,8 @@
{
nbt: {
id: "computercraft:computer_advanced",
ComputerId: 16,
Label: "modem_test.gains_peripherals",
ComputerId: 0,
On: 1b
},
pos: [4, 1, 1],

View File

@ -615,7 +615,8 @@
{
nbt: {
id: "computercraft:computer_advanced",
ComputerId: 15,
Label: "modem_test.have_peripherals",
ComputerId: 0,
On: 1b
},
pos: [4, 1, 2],

View File

@ -46,7 +46,7 @@
Name: "Dev"
},
Fuel: 0,
Label: "Clean turtle",
Label: "turtle_test.cleaned_with_cauldrons",
Slot: 0,
Items: [
{
@ -58,12 +58,12 @@
Name: '{"text":"Clean turtle"}'
},
Color: 13388876,
ComputerId: 12
ComputerId: 0
}
}
],
id: "computercraft:turtle_normal",
ComputerId: 12,
ComputerId: 0,
On: 1b
},
pos: [1, 1, 0],

View File

@ -151,7 +151,8 @@
}
],
id: "computercraft:turtle_normal",
ComputerId: 8,
Label: "turtle_test.gather_lava",
ComputerId: 0,
On: 1b
},
pos: [2, 2, 2],

View File

@ -54,7 +54,8 @@
Slot: 0,
Items: [],
id: "computercraft:turtle_normal",
ComputerId: 9,
Label: "turtle_test.hoe_dirt",
ComputerId: 0,
On: 1b
},
pos: [1, 1, 0],

View File

@ -151,7 +151,8 @@
}
],
id: "computercraft:turtle_normal",
ComputerId: 6,
Label: "turtle_test.place_lava",
ComputerId: 0,
On: 1b
},
pos: [2, 2, 2],

View File

@ -123,7 +123,8 @@
}
],
id: "computercraft:turtle_normal",
ComputerId: 10,
Label: "turtle_test.place_monitor",
ComputerId: 0,
On: 1b
},
pos: [1, 1, 2],

View File

@ -159,7 +159,8 @@
}
],
id: "computercraft:turtle_normal",
ComputerId: 7,
Label: "turtle_test.place_waterlogged",
ComputerId: 0,
On: 1b
},
pos: [2, 1, 1],

View File

@ -287,7 +287,8 @@
}
],
id: "computercraft:turtle_normal",
ComputerId: 5,
Label: "turtle_test.shears_sheep",
ComputerId: 0,
On: 1b
},
pos: [2, 3, 2],

View File

@ -118,14 +118,14 @@
},
RightUpgrade: "computercraft:wireless_modem_normal",
Fuel: 0,
Label: "Unequip refreshes peripheral",
Label: "turtle_test.unequip_refreshes_peripheral",
Slot: 0,
Items: [],
id: "computercraft:turtle_normal",
RightUpgradeNbt: {
active: 0b
},
ComputerId: 1,
ComputerId: 0,
On: 1b
},
pos: [2, 1, 2],

View File

@ -110,7 +110,7 @@
Name: "Dev"
},
Fuel: 0,
Label: "Uses Compostors",
Label: "turtle_test.use_compostors",
Slot: 0,
Items: [
{
@ -120,7 +120,7 @@
}
],
id: "computercraft:turtle_normal",
ComputerId: 11,
ComputerId: 0,
On: 1b
},
pos: [2, 2, 2],