Files
slate32/test/settings_calibration.lua
T
evan 2cdb7b3702 feat: timezone setting and main-axis justify in the ui toolkit
The launcher clock read UTC and sat next to the title because the toolkit could only
stack children from the start of an axis. justify adds the CSS main-axis modes that
had a caller -- start, end, center, between -- so a header keeps its title left and
its clock right without any app doing arithmetic.

Timezones are stored as POSIX TZ rules rather than offsets, so newlib applies DST
changeovers and os.date() in Lua reports local time with no binding of its own.
/lib/timezones.lua is only the picker list: a zone missing from it still works if its
rule is written into settings, the same split themes already use.

settings_calibration.lua now finds rows by label. Adding the timezone row shifted
every hardcoded y coordinate in it, which is the failure that had been predicted and
would have silently retargeted taps at the wrong control.
2026-08-01 17:03:55 -04:00

102 lines
3.4 KiB
Lua

-- Run: lua test/settings_calibration.lua
-- Drives the settings app on a desktop Lua, through the shared fake device.
package.path = "sdcard/lib/?.lua;test/?.lua;" .. package.path
local device = require("fake_device").install()
dofile("sdcard/apps/settings/main.lua")
local function tap(point)
on_touch_down(point.x, point.y)
on_touch_up(point.x, point.y)
end
-- Rows are found by their label rather than by a pixel row, because every hardcoded
-- coordinate silently retargets to the wrong control the day a row is inserted.
-- Each state change rebuilds the screen, so a draw repaints every label with its
-- placed position.
local function tapRow(prefix)
device.painted = {}
draw()
for _, item in ipairs(device.painted) do
if item.label:sub(1, #prefix) == prefix then
tap{x = item.x + 2, y = item.y + 2}
return
end
end
error("no row labelled '" .. prefix .. "'")
end
-- A perfectly linear panel spanning raw 200..3800 over 320x480 must round-trip
-- to those same extremes from the two inset samples.
local inset, w, h = 30, 320, 480
local function raw(pixel, size) return 200 + (3800 - 200) * pixel / size end
local s1 = {x = raw(inset, w), y = raw(inset, h)}
local s2 = {x = raw(w - inset, w), y = raw(h - inset, h)}
local x0, y0, x1, y1 = computeCalibration(s1, s2, w, h, inset)
assert(math.abs(x0 - 200) <= 1, "x0 " .. x0)
assert(math.abs(y0 - 200) <= 1, "y0 " .. y0)
assert(math.abs(x1 - 3800) <= 1, "x1 " .. x1)
assert(math.abs(y1 - 3800) <= 1, "y1 " .. y1)
-- A flipped panel (raw decreasing with pixel) must yield a descending range.
local s3 = {x = 3800 - raw(inset, w) + 200, y = s1.y}
local s4 = {x = 3800 - raw(w - inset, w) + 200, y = s2.y}
local fx0, _, fx1 = computeCalibration(s3, s4, w, h, inset)
assert(fx0 > fx1, "flipped axis should descend")
-- Rotation cycles through the four quarter turns and wraps back to 0.
setup()
for _, expected in ipairs({90, 180, 270, 0}) do
tapRow("rotation:")
assert(sys.getRotation() == expected, "rotation " .. sys.getRotation())
end
-- Timezone cycles through the picker list and stores the POSIX rule, not the name.
local zones = require("timezones")
setup()
tapRow("timezone:")
assert(sys.getTimezone() == zones[2].tz, "timezone " .. sys.getTimezone())
tapRow("timezone:")
assert(sys.getTimezone() == zones[3].tz, "timezone " .. sys.getTimezone())
-- Calibration collects one sample per target and saves on the second release.
setup()
tapRow("calibrate")
on_tick() -- release after the menu tap arms sampling
device.raw = {s1.x, s1.y}
on_tick()
device.raw = nil
on_tick()
device.raw = {s2.x, s2.y}
on_tick()
device.raw = nil
on_tick()
local saved = device.calibration
assert(saved, "calibration was not saved")
assert(math.abs(saved[1] - 200) <= 1, "saved x0 " .. saved[1])
-- Open networks connect directly from scan results.
setup()
device.networks = {{ssid = "qemu", rssi = -25, secure = false}}
tapRow("wifi:")
tapRow("scan networks")
on_tick()
tapRow("qemu")
assert(device.connected, "open network should connect without a keyboard")
assert(device.connected[1] == "qemu" and device.connected[2] == "", "open wifi connect")
-- Secure networks route through the keyboard and preserve typed punctuation.
setup()
device.networks = {{ssid = "secure", rssi = -40, secure = true}}
tapRow("wifi:")
tapRow("scan networks")
on_tick()
tapRow("secure")
tapRow("q") -- keyboard key
tapRow("connect")
assert(device.connected[1] == "secure" and device.connected[2] == "q", "secure wifi password")
print("ok")