mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 16:31:05 +02:00
cef286b170
Regression coverage for the four Yellow Pallet Town fixes on this branch: - tests/parity_J.lua: the old-man-style demo bag shows x1 in Yellow (SimulatedInputBattleItemList), not just the pre-existing x50 (pokered's OldManItemList) case. - tests/engine/push_battle_transition.lua: Commands.pushBattle calls ctx.overworld:pushBattle when available and falls back with a logged warning otherwise. Logger.warn is spied (pcall-safe, always restored) rather than read off the shared Logger.history ring buffer, so the fallback checks don't leave noise behind for whatever else runs in the same process. - tests/parity_yellow_pallet_pikachu.lua: drives the real onStep closure through the real StateStack/OverworldState, with no mocked battle -- Red never plays Music_MuseumGuy for this escort (Blue shares the same code path: onStep only branches on GameVersion.isYellow(), never isBlue(), so a separate Blue run would exercise nothing new), and Yellow's hold before the Pikachu battle is armed for exactly 2 frames before handing off to BattleTransition rather than a bare stack push. Stops there rather than also driving the demo battle to completion just to assert Music_MuseumGuy fires in Yellow (that fix's own coverage): the extra coupling to unrelated battle menu/bag/throw frame budgets wasn't worth it for one more assertion. That side stays manually verified. scenario() restores Game/GameVersion and re-inits StateStack on the way out. All three pass standalone (luajit tests/<path>). The Yellow E2E test hits the same pre-existing "Music.playMap is nil" gap three other map-warping parity tests already hit inside the aggregated tests/run_tests.lua run (missing data/generated/audio.lua in this dev environment) -- confirmed by diffing the identical error text against parity_warp_after_warp_step.lua, which also passes clean standalone.
77 lines
3.1 KiB
Lua
77 lines
3.1 KiB
Lua
-- Commands.pushBattle (src/script/Commands.lua): the shared entry point
|
|
-- for start_battle, old_man_demo, and the PALLET_TOWN Pikachu catch
|
|
-- (data/scripts/story2.lua). Every one of those call sites used to carry
|
|
-- its own copy of "if ctx.overworld.pushBattle then ... else
|
|
-- ctx.game.stack:push(battle) end"; this locks the dedup in so a future
|
|
-- edit to one call site can't silently drop the transition wipe for the
|
|
-- others.
|
|
-- luajit tests/engine/push_battle_transition.lua
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
love = love or require("tests.love_stub")
|
|
|
|
local T = require("tests.harness")
|
|
local check = T.check
|
|
local eq = T.eq
|
|
|
|
local Commands = require("src.script.Commands")
|
|
local Logger = require("src.core.Logger")
|
|
|
|
local battle = { id = "the battle" }
|
|
|
|
-- Runs fn() with Logger.warn spied instead of hitting the real
|
|
-- print()/Logger.history ring buffer, and returns the last formatted
|
|
-- warning (or nil if none). pcall-wrapped so an error inside fn() still
|
|
-- restores Logger.warn before propagating -- a leaked spy would swallow
|
|
-- every later warning in the same process silently.
|
|
local function withWarnSpy(fn)
|
|
local warned
|
|
local origWarn = Logger.warn
|
|
Logger.warn = function(fmt, ...) warned = string.format(fmt, ...) end
|
|
local ok, err = pcall(fn)
|
|
Logger.warn = origWarn
|
|
if not ok then error(err, 0) end
|
|
return warned
|
|
end
|
|
|
|
-- ctx.overworld has a real pushBattle: it must be used, not a bare stack
|
|
-- push, so the flash/wipe transition and the battle-theme start survive.
|
|
do
|
|
local pushed
|
|
local ow = { pushBattle = function(self, b) pushed = b end }
|
|
local stackPushed
|
|
local ctx = { overworld = ow, game = { stack = {
|
|
push = function(_, b) stackPushed = b end } } }
|
|
Commands.pushBattle(ctx, battle)
|
|
eq(pushed, battle, "ctx.overworld:pushBattle is called with the battle")
|
|
check(stackPushed == nil, "the bare stack push is not also taken")
|
|
end
|
|
|
|
-- ctx.overworld without a pushBattle method (a partial test double, per
|
|
-- BattleState:finish's "no live children" contract) falls back to a
|
|
-- bare stack push and logs, rather than silently skipping the transition.
|
|
do
|
|
local stackPushed
|
|
local ctx = { overworld = {}, game = { stack = {
|
|
push = function(_, b) stackPushed = b end } } }
|
|
local warned = withWarnSpy(function() Commands.pushBattle(ctx, battle) end)
|
|
eq(stackPushed, battle, "falls back to ctx.game.stack:push")
|
|
check(warned ~= nil, "the fallback logs a warning")
|
|
check(warned and warned:find("pushBattle") ~= nil,
|
|
"the warning names pushBattle")
|
|
end
|
|
|
|
-- ctx.overworld absent entirely (headless script tests that never set
|
|
-- one up): same fallback, no crash on the ctx.overworld.pushBattle read
|
|
-- -- and still spied, since this also takes the warning path.
|
|
do
|
|
local stackPushed
|
|
local ctx = { game = { stack = {
|
|
push = function(_, b) stackPushed = b end } } }
|
|
local warned = withWarnSpy(function() Commands.pushBattle(ctx, battle) end)
|
|
eq(stackPushed, battle, "falls back to ctx.game.stack:push with no overworld")
|
|
check(warned ~= nil, "this fallback also logs a warning")
|
|
end
|
|
|
|
T.finish("push_battle_transition")
|