Cover the romText fixes with targeted regression tests

Every existing test around these callsites only ever runs with an
empty/fixture Data.text, so none of them could tell a properly-wired
romText/t._X call apart from a literal that never looked at the
catalog at all -- every assertion passed either way, the same coverage
gap the museum ticket clerk and status abbreviation fixes hit earlier.

Seven new tests fake the real label for each fix and assert the pushed
or queued message uses the translated value, plus a vanilla case per
fix confirming the no-catalog fallback still matches the original
English literal exactly:
- box_release_confirmation_romtext.lua (BoxMenu _OnceReleasedText, via
  a TextBox.new spy so real pagination/choice behavior stays intact)
- slot_machine_lined_up_romtext.lua (SlotMachine _LinedUpText, symbol
  concatenated in front of the translated suffix)
- battle_fainted_message_romtext.lua (BattleState onFaint, both
  _PlayerMonFaintedText and _EnemyMonFaintedText, confirming the raw
  name reaches each without a duplicated "Enemy")
- battle_catch_messages_romtext.lua (BattleState storeCaughtMon,
  _ItemUseBallText06 plus both _ItemUseBallText07/08 branches on
  EVENT_MET_BILL)
- battle_ball_dodge_romtext.lua (BattleState throwBall,
  _ItemUseBallText00's \f-merge collapsing to exactly one queued
  message)
- overworld_field_faint_heal_romtext.lua (OverworldController
  applyFieldPoison's _PokemonFaintedText, and
  useSoftboiledFieldMove's _ItemUseNoEffectText/_PotionText including
  the recovered-amount slot the old literal never showed)
- overworld_hidden_item_romtext.lua (OverworldController
  tryHiddenObject's _FoundHiddenItemText, both the {PLAYER} token and
  the item name landing in the right slots)

Confirmed several of these fail against the pre-fix code and pass
against the current code, not just reasoned about it. Not every one of
the 15 fixed callsites has its own dedicated test -- the ShopMenu,
LinkBattle, trainer-withdraw/sent-out and the normal (non-hidden)
found-item sites share the same romText mechanism already proven
correct by the seven tests above, and building the heavier fixtures
each would need (a full mart flow, a link session, a trainer AI
switch, an object_event NPC) wasn't judged worth it for what would be
the same assertion shape again.
This commit is contained in:
thibautbus
2026-08-19 14:31:09 +02:00
parent 8f88d01cf2
commit 72592665d7
7 changed files with 620 additions and 0 deletions
@@ -0,0 +1,64 @@
-- BattleState:onFaint's "%s\nfainted!" collapsed two distinct ROM
-- strings (_EnemyMonFaintedText already carries its own "Enemy" wording;
-- _PlayerMonFaintedText does not) into one literal, substituted with
-- displayName(battler) -- which itself runs the enemy name through a
-- SEPARATE Strings("Enemy %s", ...) call. The fix passes the raw
-- battler.name and lets each label supply its own wording. This test
-- fakes both labels and checks the raw name reaches the right one, with
-- no "Enemy" ever duplicated.
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.modkit")
local Data = T.fixtures.fresh()
require("src.render.Font").load(Data)
local BattleState = require("src.battle.BattleState")
local Pokemon = require("src.pokemon.Pokemon")
local SaveData = require("src.core.SaveData")
local function mkbattle()
local save = SaveData.newGame()
save.party = { Pokemon.new(Data, "FIXMON_A", 10) }
local game = { data = Data, save = save,
stack = { top = function() return nil end, push = function() end } }
return BattleState.newWild(game, "FIXMON_C", 8)
end
-- finds the queued say-message text (onFaint queues several entries: a
-- wait, then the say)
local function findText(battle)
for _, entry in ipairs(battle.queue) do
if entry.text then return entry.text end
end
return nil
end
-- enemy: translated _EnemyMonFaintedText reaches onFaint, raw name only
do
local battle = mkbattle()
Data.text._EnemyMonFaintedText = "FAKE-ENEMY {RAM:wEnemyMonNick} FAKE!"
battle:onFaint(battle.enemy)
T.eq(findText(battle), "FAKE-ENEMY " .. battle.enemy.name .. " FAKE!",
"a translated _EnemyMonFaintedText reaches the enemy faint message")
Data.text._EnemyMonFaintedText = nil
end
-- enemy vanilla: the English literal already carries "Enemy " itself
do
local battle = mkbattle()
battle:onFaint(battle.enemy)
T.eq(findText(battle), "Enemy " .. battle.enemy.name .. "\nfainted!",
"no catalog entry falls back to the English literal, Enemy included")
end
-- player: translated _PlayerMonFaintedText reaches onFaint
do
local battle = mkbattle()
Data.text._PlayerMonFaintedText = "FAKE-PLAYER {RAM:wBattleMonNick} FAKE!"
battle:onFaint(battle.player)
T.eq(findText(battle), "FAKE-PLAYER " .. battle.player.name .. " FAKE!",
"a translated _PlayerMonFaintedText reaches the player faint message")
Data.text._PlayerMonFaintedText = nil
end
T.finish("battle_fainted_message_romtext")