mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-09-22 01:04:01 +00:00
Address review on the test harness
- The generic parts move to test/ in the repository root so other plugins can reuse them: the factorio and clusterio stubs, the test framework, the fengari runner, and clusterio's testMatrix and round trip helpers. A plugin composes them from its own env.lua, which adds its stubs and fixtures. - Tests are declared with Test.test(name, fn) and every test function receives a fresh environment, so nothing carries over between them. A test which errors is reported as a failure rather than aborting the file. - Every stub raises on properties it does not implement, which mirrors the game api. game.player is the one property allowed to read as nil. - Test.deep_eq compares tables recursively with keys checked from both sides. - The message records round trip through the same testMatrix and testRoundTripJsonSerialisable helpers the clusterio tests use, covering every optional field combination of the records, events and requests. - controller.test.js and instance.test.js cover the node side of the plugin against faked controller and instance internals: property creation and sweeping, record building, broadcasts, subscription replay, assignment validation, auto assignment and its blocking role, seeding, the initialise payload, sync mode gating, and the rejection rollback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
59a0e0be13
commit
24d36db601
@@ -1,47 +1,76 @@
|
||||
--- Listing and printing to the players who hold a role
|
||||
local Env = ...
|
||||
local env = Env.new()
|
||||
local check, eq, R = env.check, env.eq, env.R
|
||||
local Roles = env.Roles
|
||||
local Test = Env.Test
|
||||
local test, check, eq = Test.test, Test.check, Test.eq
|
||||
|
||||
local alice = env.add_player("alice", 1)
|
||||
env.add_player("bob", 2)
|
||||
env.add_player("dave", 4, false) -- offline
|
||||
env.initialise{
|
||||
Env.assignment("alice", { 5 }),
|
||||
Env.assignment("bob", { 6 }),
|
||||
Env.assignment("dave", { 5 }),
|
||||
Env.assignment("zed", { 5 }), -- has never joined this map
|
||||
}
|
||||
Roles.set_emit_events(true)
|
||||
|
||||
local mod = R("Moderator")
|
||||
check(eq(env.sorted(mod:get_player_names()), { "alice", "dave", "zed" }),
|
||||
"player names include players not on this map")
|
||||
check(eq(env.sorted(env.names(mod:get_players())), { "alice", "dave" }),
|
||||
"players are limited to this map")
|
||||
check(eq(env.names(mod:get_players(true)), { "alice" }), "players can be filtered by connected state")
|
||||
check(eq(env.names(mod:get_players(false)), { "dave" }), "players can be filtered to offline")
|
||||
|
||||
-- A player holding the role in both the synced and the local list counts once
|
||||
R("Regular"):assign(alice, { silent = true, local_only = true })
|
||||
Roles.receive_assignment_updates{ Env.assignment("alice", { 5, 6 }) }
|
||||
local sd = Roles._script_data()
|
||||
check(sd.local_players.alice ~= nil and sd.synced_players.alice ~= nil, "the role is held in both lists")
|
||||
check(eq(env.sorted(R("Regular"):get_player_names()), { "alice", "bob" }),
|
||||
"a player in both lists is counted once")
|
||||
|
||||
env.reset_log()
|
||||
check(mod:print("hello") == 1, "print returns the number of players reached")
|
||||
check(#env.printed == 1 and env.printed[1].to == "alice", "print reaches only online holders")
|
||||
|
||||
env.reset_log()
|
||||
for _, role in ipairs(Roles.get_higher_roles(R("Regular"))) do
|
||||
role:print("hello")
|
||||
--- alice and dave are moderators with dave offline, zed has never joined
|
||||
local function setup(env)
|
||||
local players = {
|
||||
alice = env.add_player("alice", 1),
|
||||
bob = env.add_player("bob", 2),
|
||||
dave = env.add_player("dave", 4, false),
|
||||
}
|
||||
env.initialise{
|
||||
Env.assignment("alice", { 5 }),
|
||||
Env.assignment("bob", { 6 }),
|
||||
Env.assignment("dave", { 5 }),
|
||||
Env.assignment("zed", { 5 }),
|
||||
}
|
||||
env.Roles.set_emit_events(true)
|
||||
return players
|
||||
end
|
||||
local got = {}
|
||||
for _, entry in ipairs(env.printed) do got[#got + 1] = entry.to end
|
||||
-- alice holds two of the roles, so like the legacy system the message can repeat
|
||||
check(eq(env.sorted(got), { "alice", "alice", "bob" }), "printing to the higher roles reaches their online holders")
|
||||
|
||||
return Env.results_json(env)
|
||||
test("player names include players not on this map", function(env)
|
||||
setup(env)
|
||||
check(eq(Test.sorted(env.R("Moderator"):get_player_names()), { "alice", "dave", "zed" }),
|
||||
"every player given the role is listed")
|
||||
end)
|
||||
|
||||
test("players are limited to this map and can be filtered", function(env)
|
||||
setup(env)
|
||||
local mod = env.R("Moderator")
|
||||
check(eq(Test.sorted(Test.names(mod:get_players())), { "alice", "dave" }), "players are limited to this map")
|
||||
check(eq(Test.names(mod:get_players(true)), { "alice" }), "filtered to connected players")
|
||||
check(eq(Test.names(mod:get_players(false)), { "dave" }), "filtered to offline players")
|
||||
end)
|
||||
|
||||
test("a player holding the role in both lists is counted once", function(env)
|
||||
local players = setup(env)
|
||||
env.R("Regular"):assign(players.alice, { silent = true, local_only = true })
|
||||
env.Roles.receive_assignment_updates{ Env.assignment("alice", { 5, 6 }) }
|
||||
|
||||
local sd = env.Roles._script_data()
|
||||
check(sd.local_players.alice ~= nil and sd.synced_players.alice ~= nil, "the role is held in both lists")
|
||||
check(eq(Test.sorted(env.R("Regular"):get_player_names()), { "alice", "bob" }), "the player is counted once")
|
||||
end)
|
||||
|
||||
test("print reaches online holders", function(env)
|
||||
setup(env)
|
||||
env.reset_log()
|
||||
check(env.R("Moderator"):print("hello") == 1, "print returns the number of players reached")
|
||||
check(#env.printed == 1 and env.printed[1].to == "alice", "only online holders are reached")
|
||||
end)
|
||||
|
||||
test("printing to the higher roles", function(env)
|
||||
local players = setup(env)
|
||||
env.R("Regular"):assign(players.alice, { silent = true, local_only = true })
|
||||
env.reset_log()
|
||||
for _, role in ipairs(env.Roles.get_higher_roles(env.R("Regular"))) do
|
||||
role:print("hello")
|
||||
end
|
||||
|
||||
local got = {}
|
||||
for _, entry in ipairs(env.printed) do got[#got + 1] = entry.to end
|
||||
-- alice holds two of the roles, so like the legacy system the message can repeat
|
||||
check(eq(Test.sorted(got), { "alice", "alice", "bob" }), "the online holders of each role are reached")
|
||||
end)
|
||||
|
||||
test("deep equality helper", function(env)
|
||||
check(Test.deep_eq({ a = { 1, 2 }, b = "x" }, { a = { 1, 2 }, b = "x" }), "equal nested tables")
|
||||
check(not Test.deep_eq({ a = { 1, 2 } }, { a = { 1, 3 } }), "differing nested values")
|
||||
check(not Test.deep_eq({ a = 1 }, { a = 1, b = 2 }), "extra keys on the right")
|
||||
check(not Test.deep_eq({ a = 1, b = 2 }, { a = 1 }), "extra keys on the left")
|
||||
check(Test.deep_eq(env.Roles._script_data().pending, {}), "works against module state")
|
||||
end)
|
||||
|
||||
return Env.finish()
|
||||
|
||||
Reference in New Issue
Block a user