aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_layout.lua
blob: 976f78fdcac197a27d3bc09920444afb1ad13c85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
-- 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')