Files
last-hearth/tests/environment_spec.lua
2026-11-03 12:41:09 -05:00

91 lines
4.1 KiB
Lua
Executable File

-- Bounded room/ventilation tests with an isolated fake node map.
local target = assert(arg[1], "environment.lua path required")
local function key(p) return p.x .. ":" .. p.y .. ":" .. p.z end
local h = {world = {}, reads = 0, clock = 0, fire = nil, fuel_until = 100, roof_center = nil}
local function put(x, y, z, name) h.world[key({x = x, y = y, z = z})] = name end
local function room()
h.world = {}
for x = -3, 3 do for z = -3, 3 do
put(x, 0, z, "stone")
put(x, 4, z, x == 0 and z == 0 and (h.roof_center or "roof") or "roof")
end end
for y = 1, 3 do for c = -3, 3 do
put(-3, y, c, "wall"); put(3, y, c, "wall")
put(c, y, -3, "wall"); put(c, y, 3, "wall")
end end
end
core = {registered_nodes = {
air = {walkable = false, buildable_to = true},
stone = {walkable = true}, roof = {walkable = true}, wall = {walkable = true},
["hearth:door_open"] = {walkable = false},
["hearth:vent"] = {walkable = true, groups = {hearth_vent = 1}},
}}
function core.get_node_or_nil(pos)
h.reads = h.reads + 1
local name = h.world[key(pos)]
if name == false then return nil end
return {name = name or "air"}
end
function core.get_us_time() return h.clock * 1000000 end
function core.find_node_near() return h.fire end
function core.get_meta()
return {get_string = function(_, name) return name == "fuel_until" and tostring(h.fuel_until) or "" end}
end
function core.line_of_sight() return true end
vector = {
round = function(p) return {x = math.floor(p.x + 0.5), y = math.floor(p.y + 0.5), z = math.floor(p.z + 0.5)} end,
offset = function(p, x, y, z) return {x = p.x + x, y = p.y + y, z = p.z + z} end,
distance = function(a, b) return math.sqrt((a.x-b.x)^2 + (a.y-b.y)^2 + (a.z-b.z)^2) end,
}
hearth = {model = {fuel_remaining = function(deadline) return math.max(0, deadline - 1) end},
weather = "clear", clock = {temperature = 10}}
dofile(target)
local passed = 0
local function test(name, fn)
local ok, err = pcall(fn)
assert(ok, name .. ": " .. tostring(err))
passed = passed + 1
print("ok " .. passed .. " - " .. name)
end
local player_pos = {x = 0, y = 0, z = 0}
test("closed room is fully sheltered and flood-fill work is bounded", function()
h.roof_center, h.fire = nil, nil; room(); h.reads = 0
local env = hearth.environment(player_pos)
assert(env.enclosed and env.roof and env.shelter == 1 and not env.ventilated)
assert(h.reads < 2500, "room probe exceeded its fixed-volume budget")
end)
test("open door marks one exposed side without losing all roof shelter", function()
h.roof_center, h.fire = nil, nil; room(); put(0, 1, 3, "hearth:door_open")
hearth.invalidate_environment()
local env = hearth.environment(player_pos)
assert(not env.enclosed and env.roof and env.open_sides == 1)
assert(math.abs(env.shelter - 0.8125) < 0.00001 and env.ventilated)
end)
test("a roof vent preserves weather shelter and safely exhausts hearth smoke", function()
h.roof_center, h.fire = "hearth:vent", {x = 0, y = 1, z = 0}; room()
hearth.invalidate_environment()
local env = hearth.environment(player_pos)
assert(env.enclosed and env.shelter == 1 and env.ventilated and env.heat > 0 and not env.smoke)
h.roof_center, h.fire = nil, {x = 0, y = 1, z = 0}; room(); hearth.invalidate_environment()
env = hearth.environment(player_pos)
assert(env.enclosed and env.heat > 0 and env.smoke)
end)
test("changed structure invalidates cached room geometry", function()
h.roof_center, h.fire = nil, nil; room(); hearth.invalidate_environment()
assert(hearth.environment(player_pos).enclosed)
put(0, 1, 3, "hearth:door_open")
assert(hearth.environment(player_pos).enclosed, "cache should hold until an edit invalidates it")
hearth.invalidate_environment()
assert(not hearth.environment(player_pos).enclosed)
end)
test("unloaded room probes fail closed instead of granting shelter", function()
h.roof_center, h.fire = nil, nil; room(); h.world["3:1:0"] = false
hearth.invalidate_environment()
local env = hearth.environment(player_pos)
assert(env.shelter == 0 and not env.enclosed)
end)
print("PASS " .. passed .. " room and ventilation tests")