mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 16:31:05 +02:00
165 lines
5.5 KiB
Lua
165 lines
5.5 KiB
Lua
-- Headless tests for the save editor's map browser behaviour.
|
|
-- Run from repo root: luajit tests/save_editor_task8_tests.lua
|
|
-- (also chained from tests/run_save_editor_tests.lua so CI covers it)
|
|
--
|
|
-- The spawn-point writes and the outdoor rule live in tools/save-editor/Ops.lua
|
|
-- and are asserted there; the panel-owned bits still tested here are the ones
|
|
-- with no other home: map selection, keyboard panning and the zoom clamp.
|
|
|
|
package.path = package.path .. ";./?.lua;./?/init.lua;./tools/save-editor/?.lua"
|
|
.. ";./tools/save-editor/panels/?.lua"
|
|
|
|
local love_stub = require("tests.love_stub")
|
|
love = love_stub
|
|
|
|
local passed, failed = 0, 0
|
|
|
|
local function check(cond, msg)
|
|
if cond then
|
|
passed = passed + 1
|
|
else
|
|
failed = failed + 1
|
|
print("FAIL: " .. msg)
|
|
end
|
|
end
|
|
|
|
local function eq(a, b, msg)
|
|
check(a == b, msg .. string.format(" (got %s, want %s)", tostring(a), tostring(b)))
|
|
end
|
|
|
|
print("== save editor task 8 (map browser) tests ==")
|
|
|
|
local Data = require("src.core.Data")
|
|
Data:load()
|
|
|
|
local SaveData = require("src.core.SaveData")
|
|
local State = require("State")
|
|
local Ops = require("Ops")
|
|
local MapLoader = require("src.world.MapLoader")
|
|
local MapBrowser = require("MapBrowser")
|
|
|
|
local function newState()
|
|
local S = State.new()
|
|
S.data = Data
|
|
S.save = SaveData.newGame()
|
|
S.mapId = S.save.player.map -- PALLET_TOWN
|
|
return S
|
|
end
|
|
|
|
-- outdoor detection ---------------------------------------------------
|
|
|
|
do
|
|
local S = newState()
|
|
local pallet = MapLoader.load(Data, "PALLET_TOWN")
|
|
check(Ops.isOutdoor(S, pallet), "PALLET_TOWN is outdoor (OVERWORLD tileset)")
|
|
|
|
local indoor
|
|
for id in pairs(Data.maps) do
|
|
local ok, map = pcall(MapLoader.load, Data, id)
|
|
if ok and not Ops.isOutdoor(S, map) then indoor = map break end
|
|
end
|
|
check(indoor ~= nil, "the dataset has at least one indoor map")
|
|
|
|
-- a visited fly spot counts as outdoor even when the tileset does not
|
|
if indoor then
|
|
S.save.visited = S.save.visited or {}
|
|
S.save.visited[indoor.id] = true
|
|
check(Ops.isOutdoor(S, indoor),
|
|
"a visited map counts as outdoor even with an indoor tileset")
|
|
S.save.visited[indoor.id] = nil
|
|
end
|
|
end
|
|
|
|
-- spawn points --------------------------------------------------------
|
|
|
|
do
|
|
local S = newState()
|
|
S.mapId = "VIRIDIAN_CITY"
|
|
S.mapClickCell = nil
|
|
S.dirty = false
|
|
|
|
check(Ops.setPlayerHere(S) == false, "setPlayerHere refuses with no cell selected")
|
|
check(S.dirty == false, "a refused setPlayerHere does not dirty the save")
|
|
check(S.status:match("Click a cell first") ~= nil,
|
|
"a refused setPlayerHere explains itself")
|
|
|
|
S.mapClickCell = { cx = 7, cy = 9 }
|
|
check(Ops.setPlayerHere(S) == true, "setPlayerHere writes with a cell selected")
|
|
eq(S.save.player.map, "VIRIDIAN_CITY", "setPlayerHere moves the player's map")
|
|
eq(S.save.player.x, 7, "setPlayerHere moves the player's x")
|
|
eq(S.save.player.y, 9, "setPlayerHere moves the player's y")
|
|
check(S.dirty, "setPlayerHere dirties the save")
|
|
|
|
check(Ops.setLastHeal(S) == true, "setLastHeal writes with a cell selected")
|
|
eq(S.save.lastHeal.map, "VIRIDIAN_CITY", "setLastHeal records the map")
|
|
eq(S.save.lastHeal.x, 7, "setLastHeal records the cell")
|
|
end
|
|
|
|
do
|
|
-- lastOutdoor refuses a map the game would not accept as an outdoor source
|
|
local S = newState()
|
|
local indoor
|
|
for id in pairs(Data.maps) do
|
|
local ok, map = pcall(MapLoader.load, Data, id)
|
|
if ok and not Ops.isOutdoor(S, map) then indoor = map break end
|
|
end
|
|
check(indoor ~= nil, "found an indoor map to try")
|
|
|
|
S.mapId = indoor.id
|
|
S.mapClickCell = { cx = 1, cy = 1 }
|
|
S.dirty = false
|
|
check(Ops.setLastOutdoor(S, indoor) == false,
|
|
"setLastOutdoor refuses a non-outdoor map")
|
|
check(S.dirty == false, "a refused setLastOutdoor does not dirty the save")
|
|
check(S.status:match("outdoor") ~= nil, "a refused setLastOutdoor explains itself")
|
|
|
|
local pallet = MapLoader.load(Data, "PALLET_TOWN")
|
|
S.mapId = "PALLET_TOWN"
|
|
check(Ops.setLastOutdoor(S, pallet) == true, "setLastOutdoor accepts an outdoor map")
|
|
eq(S.save.lastOutdoor.id, "PALLET_TOWN", "setLastOutdoor records the map id")
|
|
eq(S.save.lastOutdoor.x, 1, "setLastOutdoor records the cell")
|
|
end
|
|
|
|
-- panel-owned view state ----------------------------------------------
|
|
|
|
do
|
|
local S = newState()
|
|
MapBrowser.select(S, "VIRIDIAN_CITY")
|
|
eq(S.mapId, "VIRIDIAN_CITY", "select switches the viewed map")
|
|
eq(S.mapClickCell, nil, "select drops the previous cell selection")
|
|
eq(S._mapCenteredFor, nil,
|
|
"select defers centring to the next draw, which knows the viewport size")
|
|
check(S.status:match("VIRIDIAN_CITY") ~= nil, "select says what it is showing")
|
|
end
|
|
|
|
do
|
|
local S = newState()
|
|
S.mapCamX, S.mapCamY = 0, 0
|
|
MapBrowser.keypressed(S, "right")
|
|
eq(S.mapCamX, 16, "right pans one cell east")
|
|
MapBrowser.keypressed(S, "left")
|
|
eq(S.mapCamX, 0, "left pans back")
|
|
MapBrowser.keypressed(S, "down")
|
|
eq(S.mapCamY, 16, "down pans one cell south")
|
|
MapBrowser.keypressed(S, "w")
|
|
eq(S.mapCamY, 0, "WASD pans as well as the arrows")
|
|
|
|
local before = S.mapCamX
|
|
MapBrowser.keypressed(S, "escape")
|
|
eq(S.mapCamX, before, "a non-pan key does not move the camera")
|
|
end
|
|
|
|
do
|
|
local S = newState()
|
|
S.mapZoom = 2
|
|
MapBrowser.wheelmoved(S, 1)
|
|
check(S.mapZoom > 2, "wheel up zooms in")
|
|
for _ = 1, 40 do MapBrowser.wheelmoved(S, 1) end
|
|
eq(S.mapZoom, 4, "zoom clamps at 4x")
|
|
for _ = 1, 80 do MapBrowser.wheelmoved(S, -1) end
|
|
eq(S.mapZoom, 1, "zoom clamps at 1x")
|
|
end
|
|
|
|
print(string.format("save editor task 8 tests: %d passed, %d failed", passed, failed))
|
|
if failed > 0 then os.exit(1) end
|