Files
slate32/test/fake_device.lua
T
evan 8045faddb4 refactor: replace the TICK_MS global with app.setTickInterval()
A magic global that the runtime reads once at startup could not be changed later, gave
no feedback when misspelled, and was a second spelling of a mechanism the sibling
firmware already had. app.setTickInterval(ms) clamps to 33..3600000, takes 0 to stop,
and errors when on_tick() is not defined -- by the time init() runs the chunk body has
finished, so a missing callback is a typo rather than a race.

Also drops the code comments pointing at the other repo. Where the two APIs agree or
differ belongs in docs/lua-api-parity.md; a comment beside a constant explaining that
another firmware picked the same number is noise a reader here cannot act on.
2026-08-01 17:58:11 -04:00

116 lines
3.7 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,
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 sys.setCalibration()
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.
width = function() return device.rotation % 180 == 0 and 320 or 480 end,
height = 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,
fontHeight = function() return device.fontHeight end,
textWidth = function(text) return #text * device.charWidth end,
setRotation = function() end,
}
sys = {
millis = function() return device.now end,
exit = function() device.exited = true end,
launch = function(path) device.launched = path end,
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,
clockSynced = function() return device.clockSynced end,
getTimezone = function() return device.timezone end,
setTimezone = function(tz) device.timezone = tz return saved() end,
}
input = {
touched = 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,
status = function() return device.status end,
connect = function(ssid, password)
device.connected = {ssid, password}
return saved()
end,
forget = function() device.connected = nil return saved() end,
}
app = {
setTickInterval = function(ms)
assert(ms == 0 or on_tick, "setTickInterval without on_tick")
device.tickInterval = ms
end,
}
log = {debug = function() end, info = function() end, error = function() end}
return device
end
return device