mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-21 13:09:54 +02:00
122 lines
4.5 KiB
Lua
122 lines
4.5 KiB
Lua
-- The bag's item list is LIST_MENU_BOX (#1521): home/list_menu.asm:29-31,
|
||
-- :51-52, :364-365, :471-479, :518-521, data/text_boxes.asm:13
|
||
|
||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||
|
||
local T = require("tests.harness")
|
||
local check, eq = T.check, T.eq
|
||
love = love or require("tests.love_stub")
|
||
|
||
-- Font wants a real atlas; the geometry is what this suite is about, so it
|
||
-- records the calls instead. ListMenu and Theme bind Font at require time.
|
||
local realFont = package.loaded["src.render.Font"]
|
||
local calls = {}
|
||
package.loaded["src.render.Font"] = {
|
||
BORDER = { tl = 1, tr = 2, bl = 3, br = 4, h = 5, v = 6 },
|
||
draw = function(text, x, y) calls[#calls + 1] = { "draw", text, x, y } end,
|
||
drawCode = function(code, x, y) calls[#calls + 1] = { "code", code, x, y } end,
|
||
drawBox = function(tx, ty, tw, th) calls[#calls + 1] = { "box", tx, ty, tw, th } end,
|
||
width = function(text) return #tostring(text) * 8 end,
|
||
}
|
||
package.loaded["src.ui.ListMenu"] = nil
|
||
package.loaded["src.ui.Theme"] = nil
|
||
local ListMenu = require("src.ui.ListMenu")
|
||
local Theme = require("src.ui.Theme")
|
||
|
||
local function found(kind, pred)
|
||
for _, c in ipairs(calls) do
|
||
if c[1] == kind and pred(c) then return c end
|
||
end
|
||
return nil
|
||
end
|
||
|
||
local function newList(count)
|
||
local items = {}
|
||
for i = 1, count do
|
||
items[i] = { value = "ITEM_" .. i, label = "ITEM " .. i, right = "x" .. i }
|
||
end
|
||
return ListMenu.new({}, "ITEMS", items, { kind = "bag", itemBox = true })
|
||
end
|
||
|
||
do
|
||
local list = newList(6)
|
||
eq(list.rows, 4, "PrintListMenuEntries prints 4 names, not 7")
|
||
eq(list.isOpaque, false,
|
||
"the box is partial, so the map keeps drawing behind it")
|
||
|
||
calls = {}
|
||
list:draw()
|
||
|
||
local box = found("box", function(c) return true end)
|
||
if check(box ~= nil, "the list draws LIST_MENU_BOX") then
|
||
eq(box[2], 4, "upper-left X 4")
|
||
eq(box[3], 2, "upper-left Y 2")
|
||
eq(box[4], 16, "through lower-right X 19")
|
||
eq(box[5], 11, "through lower-right Y 12")
|
||
end
|
||
|
||
-- names at hlcoord 6, 4 and every two rows after it
|
||
for row = 1, 4 do
|
||
local y = 32 + (row - 1) * 16
|
||
check(found("draw", function(c)
|
||
return c[2] == "ITEM " .. row and c[3] == 48 and c[4] == y
|
||
end) ~= nil, "name " .. row .. " sits at (48, " .. y .. ")")
|
||
end
|
||
check(found("draw", function(c) return c[2] == "ITEM 5" end) == nil,
|
||
"the fifth name is scrolled out, not printed below the box")
|
||
|
||
-- the quantity: '×' at column 14, the count right-aligned after it
|
||
check(found("draw", function(c)
|
||
return c[2] == "x" and c[3] == 112 and c[4] == 40
|
||
end) ~= nil, "the first quantity's '×' is a row down at column 14")
|
||
check(found("draw", function(c)
|
||
return c[2] == "1" and c[3] == 128 and c[4] == 40
|
||
end) ~= nil, "with the count right-aligned in the two columns after it")
|
||
|
||
check(found("code", function(c)
|
||
return c[2] == Theme.cursor and c[3] == 40 and c[4] == 32
|
||
end) ~= nil, "the cursor is in column 5 (wTopMenuItemX)")
|
||
check(found("code", function(c)
|
||
return c[2] == Theme.moreArrow and c[3] == 144 and c[4] == 88
|
||
end) ~= nil, "a full page ends with the '▼'")
|
||
|
||
-- nothing else: no title, no money footer (wPrintItemPrices = 0)
|
||
check(found("draw", function(c) return tostring(c[2]):find("¥") end) == nil,
|
||
"the everyday bag has no money box (that is the mart's screen)")
|
||
check(found("draw", function(c) return c[2] == "ITEMS" end) == nil,
|
||
"and no title row: the box carries no header text")
|
||
end
|
||
|
||
-- the box keeps the palette beneath and caps the cursor at wMaxMenuItem
|
||
do
|
||
local list = newList(6)
|
||
eq(list.sgbPalettes, false,
|
||
"no SET_PAL_GENERIC: ItemMenuLoop keeps RunDefaultPaletteCommand's "
|
||
.. "palette (start_sub_menus.asm:300)")
|
||
eq(list.cursorRows, 3,
|
||
"wMaxMenuItem 2: three cursor rows (home/list_menu.asm:46-48)")
|
||
list.game = { input = { wasPressed = function(_, b) return b == "down" end,
|
||
isDown = function() return false end } }
|
||
for _ = 1, 3 do list:update(1 / 60) end
|
||
eq(list.index, 4, "three downs reach the fourth item")
|
||
eq(list.index - list.scroll, 3,
|
||
"scrolling instead of dropping the cursor onto the look-ahead row")
|
||
end
|
||
|
||
-- a short list stops at its last name, and the terminator's CANCEL row is
|
||
-- what would follow -- never the '▼'
|
||
do
|
||
local list = newList(2)
|
||
calls = {}
|
||
list:draw()
|
||
check(found("code", function(c) return c[2] == Theme.moreArrow end) == nil,
|
||
"a page that runs out of names prints no '▼' (:372)")
|
||
end
|
||
|
||
package.loaded["src.render.Font"] = realFont
|
||
package.loaded["src.ui.ListMenu"] = nil
|
||
package.loaded["src.ui.Theme"] = nil
|
||
require("src.ui.Screens").invalidate()
|
||
|
||
T.finish()
|