-- Grid maths check. -- Run from the repo root: lua test/test_layout.lua -- -- dashboard.lua requires cairo, which only exists inside Conky, so stub the -- pieces it touches at load time before requiring it. package.path = './?.lua;' .. package.path package.preload['cairo'] = function() return {} end package.preload['lib.card'] = function() return {} end conky_window = nil function conky_parse(s) return '#000000' end -- dashboard.lua parses its colours out of the config file at load time, so -- conky_config must point at something readable. The rendered conky.conf is -- gitignored and may not exist, so aim the stub at the template: it parses to -- no colours (its values are still @PLACEHOLDER@), which is fine here because -- this test only exercises the grid maths. conky_config = 'conky.conf.in' dofile('dashboard.lua') local G = conky_dashboard_internal assert(G, 'dashboard.lua must export conky_dashboard_internal') -- Every cell must land inside the surface, on both real monitors. for _, screen in ipairs({ { 2560, 1080 }, { 1920, 1080 } }) do local sw, sh = screen[1], screen[2] for col = 1, G.COLS do for row = 1, G.ROWS do local r = G.rect_for({ col = col, row = row, w = 1, h = 1 }, sw, sh) assert(r.x >= G.MARGIN - 0.01, ('x underflows margin at %dx%d col %d'):format(sw, sh, col)) assert(r.y >= G.MARGIN - 0.01, ('y underflows margin at %dx%d row %d'):format(sw, sh, row)) assert(r.x + r.w <= sw - G.MARGIN + 0.01, ('cell overflows width at %dx%d col %d: x=%f w=%f'):format(sw, sh, col, r.x, r.w)) assert(r.y + r.h <= sh - G.MARGIN + 0.01, ('cell overflows height at %dx%d row %d'):format(sw, sh, row)) assert(r.w > 0 and r.h > 0, 'cell must have positive size') end end end -- A spanning cell must cover its cells plus the gap between them, so two -- side-by-side 1-wide cards and one 2-wide card occupy the same pixels. local a = G.rect_for({ col = 1, row = 1, w = 1, h = 1 }, 2560, 1080) local b = G.rect_for({ col = 2, row = 1, w = 1, h = 1 }, 2560, 1080) local span = G.rect_for({ col = 1, row = 1, w = 2, h = 1 }, 2560, 1080) assert(math.abs((b.x + b.w) - (span.x + span.w)) < 0.01, ('a 2-wide card must end where the second 1-wide card ends: %f vs %f') :format(b.x + b.w, span.x + span.w)) assert(math.abs(span.w - (a.w * 2 + G.GAP)) < 0.01, 'span must absorb the gap') -- The shipped layout must not place anything outside the declared grid, which -- is the mistake a user editing the table will actually make. -- -- No `or {}` fallback here: with one, an unexported layout makes ipairs walk an -- empty table and the whole block passes vacuously, which is exactly the bug -- this assertion is supposed to catch. assert(G.layout, 'dashboard.lua must export layout') for _, e in ipairs(G.layout) do assert(e.col >= 1 and e.col + (e.w or 1) - 1 <= G.COLS, 'layout entry out of columns: ' .. tostring(e.widget)) assert(e.row >= 1 and e.row + (e.h or 1) - 1 <= G.ROWS, 'layout entry out of rows: ' .. tostring(e.widget)) end print('test_layout: all assertions passed')