326 lines
13 KiB
Lua
326 lines
13 KiB
Lua
---------------------------------------------------------------------------
|
|
-- @author Uli Schlachter
|
|
-- @copyright 2015 Uli Schlachter
|
|
---------------------------------------------------------------------------
|
|
|
|
local hierarchy = require("wibox.hierarchy")
|
|
|
|
local Region = require("lgi").cairo.Region
|
|
local matrix = require("gears.matrix")
|
|
local utils = require("wibox.test_utils")
|
|
|
|
local function make_widget(children)
|
|
local result = utils.widget_stub()
|
|
result.layout = function()
|
|
return children
|
|
end
|
|
return result
|
|
end
|
|
|
|
local function make_child(widget, width, height, mat)
|
|
return { _widget = widget, _width = width, _height = height, _matrix = mat }
|
|
end
|
|
|
|
describe("wibox.hierarchy", function()
|
|
describe("Accessor functions", function()
|
|
local widget, instance
|
|
before_each(function()
|
|
local function nop() end
|
|
local context = {}
|
|
widget = make_widget(nil)
|
|
instance = hierarchy.new(context, widget, 10, 20, nop, nop)
|
|
end)
|
|
|
|
it("get_widget", function()
|
|
assert.is.equal(instance:get_widget(), widget)
|
|
end)
|
|
|
|
it("get_matrix_to_parent", function()
|
|
assert.is.equal(matrix.identity, instance:get_matrix_to_parent())
|
|
end)
|
|
|
|
it("get_matrix_to_device", function()
|
|
assert.is.equal(matrix.identity, instance:get_matrix_to_device())
|
|
end)
|
|
|
|
it("get_matrix_from_parent", function()
|
|
assert.is.equal(matrix.identity, instance:get_matrix_from_parent())
|
|
end)
|
|
|
|
it("get_matrix_from_device", function()
|
|
assert.is.equal(matrix.identity, instance:get_matrix_from_device())
|
|
end)
|
|
|
|
it("get_draw_extents", function()
|
|
assert.is.same({ instance:get_draw_extents() }, { 0, 0, 10, 20 })
|
|
end)
|
|
|
|
it("get_size", function()
|
|
assert.is.same({ instance:get_size() }, { 10, 20 })
|
|
end)
|
|
|
|
it("get_children", function()
|
|
assert.is.same(instance:get_children(), {})
|
|
end)
|
|
end)
|
|
|
|
it("disconnect works", function()
|
|
local child = make_widget(nil)
|
|
local parent = make_widget({
|
|
make_child(child, 2, 5, matrix.create_translate(10, 0))
|
|
})
|
|
|
|
local extra_arg = {}
|
|
local child_redraws, child_layouts = 0, 0
|
|
local parent_redraws, parent_layouts = 0, 0
|
|
local function redraw(arg, extra)
|
|
assert.is.equal(extra_arg, extra)
|
|
if arg:get_widget() == child then
|
|
child_redraws = child_redraws + 1
|
|
elseif arg:get_widget() == parent then
|
|
parent_redraws = parent_redraws + 1
|
|
else
|
|
error("Unknown widget")
|
|
end
|
|
end
|
|
local function layout(arg, extra)
|
|
assert.is.equal(extra_arg, extra)
|
|
if arg:get_widget() == child then
|
|
child_layouts = child_layouts + 1
|
|
elseif arg:get_widget() == parent then
|
|
parent_layouts = parent_layouts + 1
|
|
else
|
|
error("Unknown widget")
|
|
end
|
|
end
|
|
local context = {}
|
|
local instance = hierarchy.new(context, parent, 15, 20, redraw, layout, extra_arg) -- luacheck: no unused
|
|
|
|
-- There should be a connection
|
|
parent:emit_signal("widget::redraw_needed")
|
|
assert.is.same({ 0, 0, 1, 0 }, { child_redraws, child_layouts, parent_redraws, parent_layouts })
|
|
child:emit_signal("widget::redraw_needed")
|
|
assert.is.same({ 1, 0, 1, 0 }, { child_redraws, child_layouts, parent_redraws, parent_layouts })
|
|
child:emit_signal("widget::layout_changed")
|
|
assert.is.same({ 1, 1, 1, 0 }, { child_redraws, child_layouts, parent_redraws, parent_layouts })
|
|
parent:emit_signal("widget::layout_changed")
|
|
assert.is.same({ 1, 1, 1, 1 }, { child_redraws, child_layouts, parent_redraws, parent_layouts })
|
|
|
|
-- Garbage-collect the hierarchy
|
|
instance = nil
|
|
collectgarbage("collect")
|
|
|
|
-- No connections should be left
|
|
parent:emit_signal("widget::redraw_needed")
|
|
child:emit_signal("widget::redraw_needed")
|
|
child:emit_signal("widget::layout_changed")
|
|
parent:emit_signal("widget::layout_changed")
|
|
assert.is.same({ 1, 1, 1, 1 }, { child_redraws, child_layouts, parent_redraws, parent_layouts })
|
|
end)
|
|
|
|
describe("children", function()
|
|
local child, intermediate, parent
|
|
local hierarchy_child, hierarchy_intermediate, hierarchy_parent
|
|
before_each(function()
|
|
child = make_widget(nil)
|
|
intermediate = make_widget({
|
|
make_child(child, 10, 20, matrix.create_translate(0, 5):scale(2, 2))
|
|
})
|
|
parent = make_widget({
|
|
make_child(intermediate, 5, 2, matrix.create_translate(4, 0))
|
|
})
|
|
|
|
local function nop() end
|
|
local context = {}
|
|
hierarchy_parent = hierarchy.new(context, parent, 15, 16, nop, nop)
|
|
|
|
-- This also tests get_children
|
|
local children = hierarchy_parent:get_children()
|
|
assert.is.equal(#children, 1)
|
|
hierarchy_intermediate = children[1]
|
|
|
|
children = hierarchy_intermediate:get_children()
|
|
assert.is.equal(#children, 1)
|
|
hierarchy_child = children[1]
|
|
end)
|
|
|
|
it("get_widget", function()
|
|
assert.is.equal(hierarchy_child:get_widget(), child)
|
|
assert.is.equal(hierarchy_intermediate:get_widget(), intermediate)
|
|
assert.is.equal(hierarchy_parent:get_widget(), parent)
|
|
end)
|
|
|
|
it("get_matrix_to_parent", function()
|
|
assert.is.equal(hierarchy_child:get_matrix_to_parent(), matrix.create(2, 0, 0, 2, 0, 5))
|
|
assert.is.equal(hierarchy_intermediate:get_matrix_to_parent(), matrix.create_translate(4, 0))
|
|
assert.is.equal(hierarchy_parent:get_matrix_to_parent(), matrix.identity)
|
|
end)
|
|
|
|
it("get_matrix_to_device", function()
|
|
assert.is.equal(hierarchy_child:get_matrix_to_device(), matrix.create(2, 0, 0, 2, 4, 5))
|
|
assert.is.equal(hierarchy_intermediate:get_matrix_to_device(), matrix.create_translate(4, 0))
|
|
assert.is.equal(hierarchy_parent:get_matrix_to_device(), matrix.identity)
|
|
end)
|
|
|
|
it("get_matrix_from_parent", function()
|
|
assert.is.equal(hierarchy_child:get_matrix_from_parent(), matrix.create(0.5, 0, 0, 0.5, 0, -2.5))
|
|
assert.is.equal(hierarchy_intermediate:get_matrix_from_parent(), matrix.create_translate(-4, 0))
|
|
assert.is.equal(hierarchy_parent:get_matrix_from_parent(), matrix.identity)
|
|
end)
|
|
|
|
it("get_matrix_from_device", function()
|
|
assert.is.equal(hierarchy_child:get_matrix_from_device(), matrix.create(0.5, 0, 0, 0.5, -2, -2.5))
|
|
assert.is.equal(hierarchy_intermediate:get_matrix_from_device(), matrix.create_translate(-4, 0))
|
|
assert.is.equal(hierarchy_parent:get_matrix_from_device(), matrix.identity)
|
|
end)
|
|
|
|
it("get_draw_extents", function()
|
|
assert.is.same({ hierarchy_child:get_draw_extents() }, { 0, 0, 10, 20 })
|
|
assert.is.same({ hierarchy_intermediate:get_draw_extents() }, { 0, 0, 20, 45 })
|
|
assert.is.same({ hierarchy_parent:get_draw_extents() }, { 0, 0, 24, 45 })
|
|
end)
|
|
|
|
it("get_size", function()
|
|
assert.is.same({ hierarchy_child:get_size() }, { 10, 20 })
|
|
assert.is.same({ hierarchy_intermediate:get_size() }, { 5, 2 })
|
|
assert.is.same({ hierarchy_parent:get_size() }, { 15, 16 })
|
|
end)
|
|
end)
|
|
|
|
describe("update", function()
|
|
local child, intermediate, parent
|
|
local instance
|
|
local function nop() end
|
|
before_each(function()
|
|
child = make_widget(nil)
|
|
intermediate = make_widget({
|
|
make_child(child, 10, 20, matrix.create_translate(0, 5))
|
|
})
|
|
parent = make_widget({
|
|
make_child(intermediate, 5, 2, matrix.create_translate(4, 0))
|
|
})
|
|
|
|
local context = {}
|
|
instance = hierarchy.new(context, parent, 15, 16, nop, nop)
|
|
end)
|
|
|
|
it("No difference 1", function()
|
|
local region = instance:update(context, parent, 15, 16)
|
|
assert.is.equal(region:num_rectangles(), 0)
|
|
end)
|
|
|
|
it("No difference 2", function()
|
|
local region1 = Region.create()
|
|
local region2 = instance:update(context, parent, 15, 16, region1)
|
|
assert.is.equal(region1, region2)
|
|
assert.is.equal(region2:num_rectangles(), 0)
|
|
end)
|
|
|
|
it("child moved", function()
|
|
-- Clear caches and change result of intermediate
|
|
intermediate.layout = function()
|
|
return { make_child(child, 10, 20, matrix.create_translate(0, 4)) }
|
|
end
|
|
intermediate:emit_signal("widget::layout_changed")
|
|
|
|
local region = instance:update(context, parent, 15, 16)
|
|
assert.is.equal(region:num_rectangles(), 1)
|
|
local rect = region:get_rectangle(0)
|
|
-- The widget drew to 4, 5, 10, 20 before and 4, 4, 10, 20 after
|
|
assert.is.same({ rect.x, rect.y, rect.width, rect.height }, { 4, 4, 10, 21 })
|
|
end)
|
|
|
|
it("child disappears", function()
|
|
-- Clear caches and change result of intermediate
|
|
intermediate.layout = function() end
|
|
intermediate:emit_signal("widget::layout_changed")
|
|
|
|
local region = instance:update(context, parent, 15, 16)
|
|
assert.is.equal(region:num_rectangles(), 1)
|
|
local rect = region:get_rectangle(0)
|
|
-- The child was drawn to 4, 5, 10, 20
|
|
assert.is.same({ rect.x, rect.y, rect.width, rect.height }, { 4, 5, 10, 20 })
|
|
end)
|
|
|
|
it("widget changed", function()
|
|
-- Clear caches and change result of parent
|
|
local new_intermediate = make_widget({
|
|
make_child(child, 10, 20, matrix.create_translate(0, 5))
|
|
})
|
|
parent.layout = function()
|
|
return { make_child(new_intermediate, 5, 2, matrix.create_translate(4, 0)) }
|
|
end
|
|
parent:emit_signal("widget::layout_changed")
|
|
|
|
local region = instance:update(context, parent, 15, 16)
|
|
assert.is.equal(region:num_rectangles(), 1)
|
|
local rect = region:get_rectangle(0)
|
|
-- Intermediate drew to 4, 0, 5, 2 (and so does new_intermediate)
|
|
assert.is.same({ rect.x, rect.y, rect.width, rect.height }, { 4, 0, 5, 2 })
|
|
end)
|
|
end)
|
|
|
|
describe("widget counts", function()
|
|
local child, intermediate, parent
|
|
local unrelated
|
|
local context, instance
|
|
before_each(function()
|
|
local function nop() end
|
|
context = {}
|
|
child = make_widget(nil)
|
|
intermediate = make_widget({
|
|
make_child(child, 10, 20, matrix.identity)
|
|
})
|
|
parent = make_widget({
|
|
make_child(intermediate, 10, 20, matrix.identity),
|
|
make_child(child, 0, 20, matrix.identity)
|
|
})
|
|
unrelated = make_widget(nil)
|
|
|
|
hierarchy.count_widget(child)
|
|
hierarchy.count_widget(parent)
|
|
hierarchy.count_widget(unrelated)
|
|
instance = hierarchy.new(context, parent, 10, 20, nop, nop)
|
|
end)
|
|
|
|
it("basic counts", function()
|
|
local unrelated_other = make_widget(nil)
|
|
assert.is.equal(1, instance:get_count(child))
|
|
-- intermediate was not passed to hierarchy.count_widget()!
|
|
assert.is.equal(0, instance:get_count(intermediate))
|
|
assert.is.equal(1, instance:get_count(parent))
|
|
assert.is.equal(0, instance:get_count(unrelated))
|
|
assert.is.equal(0, instance:get_count(unrelated_other))
|
|
end)
|
|
|
|
it("after update", function()
|
|
-- Replace child and intermediate by just a new_child
|
|
local new_child = make_widget(nil)
|
|
parent.layout = function()
|
|
return { make_child(new_child, 10, 20, matrix.identity) }
|
|
end
|
|
parent:emit_signal("widget::layout_changed")
|
|
instance:update(context, parent, 10, 20)
|
|
|
|
assert.is.equal(0, instance:get_count(child))
|
|
-- new_child was not passed to hierarchy.count_widget()!
|
|
assert.is.equal(0, instance:get_count(new_child))
|
|
assert.is.equal(1, instance:get_count(parent))
|
|
assert.is.equal(0, instance:get_count(unrelated))
|
|
end)
|
|
|
|
it("collectible", function()
|
|
-- This test that hierarchy.count_widget() does not prevent garbage collection of the widget.
|
|
local weak = setmetatable({}, { __mode = "v"})
|
|
weak[1], weak[2], weak[3], weak[4] = child, intermediate, parent, instance
|
|
child, intermediate, parent, instance = nil, nil, nil, nil
|
|
|
|
assert.is.equal(4, #weak)
|
|
collectgarbage("collect")
|
|
assert.is.equal(0, #weak)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|