Files
slate32/test/fake_device.lua
T
evan b5146b8642 refactor(lua): give the status bar its own dirty tracking and split settings out of sys
The bar repainted itself whole every second. It now compares each field against what
it last painted, adds seconds and a memory percentage, and keys the cache on
gui.getRotation() and ui.themeName so rotation and theme changes still repaint it.
Invalidation lives entirely in Lua; the firmware's push flag and gfx/statusbar.h are gone.

Bindings follow getName/setName/isName, persisted preferences move from sys to a settings
table, and gui.setRotation takes degrees like settings does. A bar that dies mid-run now
keeps its rows reserved rather than silently resizing the running app.
2026-08-02 10:49:01 -04:00

126 lines
4.3 KiB
Lua

-- Stand-in for the firmware bindings, so host tests exercise the real ui.lua.
--
-- One definition of the binding surface: when a binding is added or renamed, this is
-- the file that changes. Tests mutate the returned table to steer the device, and may
-- overwrite any stub function outright for a single assertion.
local device = {
-- Text metrics chosen to match the firmware's default GLCD font, since layout
-- assertions are written in real pixels.
fontHeight = 8,
charWidth = 6,
now = 0,
rotation = 0,
theme = "light",
clockSynced = false,
tickInterval = 0,
appName = "test",
textSize = 1,
fullscreen = false,
timezone = "UTC0",
raw = nil, -- pending raw touch reading, {x, y} or nil
networks = {}, -- what wifi.scan() returns
status = {state = "disconnected", ssid = "", ip = "", rssi = 0},
painted = {}, -- every drawText call, in order
calibration = nil, -- last settings.setCalibration()
freeHeap = 200000,
totalHeap = 320000,
connected = nil, -- last wifi.connect()
exited = false,
launched = nil,
saveFails = false, -- make every persisting call report failure
}
local function saved()
return not device.saveFails
end
function device.install()
device.painted = {}
gui = {
color = function(r, g, b) return r * 65536 + g * 256 + b end,
-- Rotation swaps the frame, exactly as TFT_eSPI reports it.
getWidth = function() return device.rotation % 180 == 0 and 320 or 480 end,
getHeight = function() return device.rotation % 180 == 0 and 480 or 320 end,
clear = function() end,
fillRect = function() end,
drawRect = function() end,
fillCircle = function() end,
drawLine = function() end,
roundRect = function() end,
drawText = function(label, x, y)
device.painted[#device.painted + 1] = {label = label, x = x, y = y}
end,
setTextSize = function(size) device.textSize = size end,
getFontHeight = function() return device.fontHeight * device.textSize end,
getTextWidth = function(text) return #text * device.charWidth * device.textSize end,
setRotation = function(degrees) device.rotation = degrees end,
getRotation = function() return device.rotation end,
setFullscreen = function(on) device.fullscreen = on and true or false end,
}
sys = {
getMillis = function() return device.now end,
exit = function() device.exited = true end,
getAppName = function() return device.appName end,
getMemory = function() return device.freeHeap, device.totalHeap end,
isClockSynced = function() return device.clockSynced end,
setTickInterval = function(ms)
assert(ms == 0 or on_tick, "setTickInterval without on_tick")
device.tickInterval = ms
end,
launch = function(path) device.launched = path end,
}
settings = {
getRotation = function() return device.rotation end,
setRotation = function(degrees)
if degrees % 90 ~= 0 or degrees < 0 or degrees > 270 then return false end
device.rotation = degrees
return saved()
end,
getTheme = function() return device.theme end,
setTheme = function(name) device.theme = name return saved() end,
setCalibration = function(...) device.calibration = {...} return saved() end,
getTimezone = function() return device.timezone end,
setTimezone = function(tz) device.timezone = tz return saved() end,
}
input = {
isTouched = function() return device.raw ~= nil end,
getTouch = function()
if not device.raw then return nil end
return device.raw[1], device.raw[2]
end,
getRawTouch = function()
if not device.raw then return nil end
return device.raw[1], device.raw[2]
end,
}
fs = {
readFile = function() return nil end,
writeFile = function() return saved() end,
exists = function() return false end,
listFiles = function() return {} end,
listDirs = function() return {} end,
}
wifi = {
scan = function() return device.networks end,
getStatus = function() return device.status end,
connect = function(ssid, password)
device.connected = {ssid, password}
return saved()
end,
forget = function() device.connected = nil return saved() end,
}
log = {debug = function() end, info = function() end, error = function() end}
return device
end
return device