Files
slate32/test/statusbar_dirty.lua
evan 9e58e72bf6 build: add a format target and one shared editor config
clang-format had no config here, so adopting the submodule's puts both repos
on the same pointer alignment. .editorconfig is what lua-language-server reads
on save, which is why the Lua tree had drifted between tabs and two widths.
2026-08-04 13:20:08 -04:00

89 lines
3.1 KiB
Lua

-- Run: lua test/statusbar_dirty.lua
-- Asserts the bar repaints only what changed, and that it notices the two things it can
-- only learn by looking: rotation and theme. The clock is pinned unsynced so its text is
-- constant and every other field can be steered on its own.
package.path = "sdcard/.lua/lib/?.lua;test/?.lua;" .. package.path
local device = require("fake_device").install()
local ui = require "ui"
local statusbar = require "statusbar"
device.clockSynced = false
-- Returns the labels drawn by one draw() call.
local function paint()
device.painted = {}
device.lines = {}
statusbar.draw(true, false)
local labels = {}
for _, entry in ipairs(device.painted) do
labels[#labels + 1] = entry.label
end
return labels
end
local function has(labels, want)
for _, label in ipairs(labels) do
if label == want then
return true
end
end
return false
end
local first = paint()
assert(has(first, device.appName), "first draw paints the app name")
assert(has(first, "--:--:--"), "first draw paints the clock")
assert(has(first, "117kB"), "first draw paints used memory")
assert(#device.lines == 5, "offline wifi adds one diagonal to the back chevron lines")
assert(#paint() == 0, "an unchanged bar paints nothing")
device.freeHeap = device.freeHeap - 32000
local memOnly = paint()
assert(#memOnly == 1 and memOnly[1] == "148kB", "only the memory slot repaints")
device.status = { state = "connected", ssid = "x", ip = "", rssi = -50 }
assert(#paint() == 0 and #device.lines == 0, "connected signal bars have no cross")
device.status = { state = "disconnected", ssid = "", ip = "", rssi = 0 }
assert(#paint() == 0 and #device.lines == 1, "disconnected wifi draws one diagonal cross")
local beforePressed = #device.roundRects
statusbar.draw(true, true)
assert(#device.roundRects == beforePressed + 1, "pressing back repaints its button")
statusbar.draw(true, false)
-- Rotation and theme invalidate everything, because every slot moves or recolors.
device.rotation = 180
assert(has(paint(), device.appName), "rotation repaints the whole bar")
assert(#paint() == 0, "and settles again afterwards")
ui.setTheme "dark"
assert(has(paint(), device.appName), "a theme change repaints the whole bar")
-- An app renaming itself is a bar change like any other, with no invalidation call.
sys.setAppTitle "settings - wifi"
assert(has(paint(), "settings - wifi"), "a renamed app repaints the whole bar")
assert(#paint() == 0, "and settles again afterwards")
-- A name wide enough to reach the memory slot is clipped, not drawn over it.
sys.setAppTitle(string.rep("w", 60))
local clipped
for _, label in ipairs(paint()) do
if label:sub(1, 1) == "w" then
clipped = label
end
end
assert(clipped and #clipped < 60, "an over-long name is clipped, got " .. #(clipped or ""))
sys.setAppTitle "test"
-- Leaving fullscreen is the one change draw() cannot see: the app painted over the bar
-- while nothing about the bar's own state moved.
ui.setTheme "light"
paint()
statusbar.setFullscreen(true)
statusbar.setFullscreen(false)
assert(has(paint(), device.appName), "leaving fullscreen repaints the whole bar")
print "ok"