dfhack/test/library/gui.lua

200 lines
5.9 KiB
Lua

2023-08-04 10:59:08 -06:00
config.target = 'core'
2023-08-04 02:35:51 -06:00
2020-03-26 23:38:40 -06:00
local gui = require('gui')
function test.getKeyDisplay()
expect.eq(gui.getKeyDisplay(df.interface_key.CUSTOM_A), 'a')
expect.eq(gui.getKeyDisplay('CUSTOM_A'), 'a')
expect.eq(gui.getKeyDisplay(df.interface_key._first_item - 1), '?')
expect.eq(gui.getKeyDisplay(df.interface_key._last_item + 1), '?')
expect.eq(gui.getKeyDisplay(df.interface_key.KEYBINDING_COMPLETE), '?')
end
function test.clear_pen()
expect.table_eq(gui.CLEAR_PEN, {
2023-08-04 02:35:51 -06:00
tile = df.global.init.texpos_border_interior,
2020-03-26 23:38:40 -06:00
ch = string.byte(' '),
fg = COLOR_BLACK,
bg = COLOR_BLACK,
bold = false,
tile_color = false,
2023-08-12 23:04:15 -06:00
write_to_lower = true,
2020-03-26 23:38:40 -06:00
})
end
WantsFocusView = defclass(WantsFocusView, gui.View)
function WantsFocusView:getPreferredFocusState()
return true
end
function test.view_wants_focus()
local parent = gui.View()
expect.false_(parent.focus)
-- expect first (regular) child to not get focus
local regular_child = gui.View()
expect.false_(regular_child.focus)
expect.ne(parent.focus_group, regular_child.focus_group)
parent:addviews{regular_child}
expect.false_(regular_child.focus)
expect.eq(parent.focus_group, regular_child.focus_group)
-- the first child who wants focus gets it
local focus_child = WantsFocusView()
expect.false_(focus_child.focus)
parent:addviews{focus_child}
expect.true_(focus_child.focus)
expect.eq(parent.focus_group.cur, focus_child)
-- the second child who wants focus doesn't
local focus_child2 = WantsFocusView()
parent:addviews{focus_child2}
expect.false_(focus_child2.focus)
expect.eq(parent.focus_group.cur, focus_child)
end
function test.inherit_focus_from_subview()
local parent = gui.View()
local regular_child = gui.View()
local focus_child = WantsFocusView()
regular_child:addviews{focus_child}
expect.true_(focus_child.focus)
parent:addviews{regular_child}
expect.eq(parent.focus_group.cur, focus_child)
end
function test.subviews_negotiate_focus()
local parent = gui.View()
local regular_child = gui.View()
local regular_child2 = gui.View()
local focus_child = WantsFocusView()
local focus_child2 = WantsFocusView()
regular_child:addviews{focus_child}
regular_child2:addviews{focus_child2}
expect.true_(focus_child.focus)
expect.true_(focus_child2.focus)
expect.ne(regular_child.focus_group, regular_child2.focus_group)
parent:addviews{regular_child}
expect.eq(parent.focus_group.cur, focus_child)
expect.true_(focus_child.focus)
expect.true_(focus_child2.focus)
parent:addviews{regular_child2}
expect.eq(parent.focus_group.cur, focus_child)
expect.eq(regular_child.focus_group, regular_child2.focus_group)
expect.true_(focus_child.focus)
expect.false_(focus_child2.focus)
end
MockInputView = defclass(MockInputView, gui.View)
function MockInputView:onInput(keys)
self.mock(keys)
MockInputView.super.onInput(self, keys)
return true
end
local function reset_child_mocks(parent)
for _,child in ipairs(parent.subviews) do
child.mock = mock.func()
reset_child_mocks(child)
end
end
-- verify that input got routed as expected
local function test_children(expected, parent)
local children = parent.subviews
for i,val in ipairs(expected) do
expect.eq(val, children[i].mock.call_count, 'child '..i)
end
end
function test.keyboard_follows_focus()
local parent = gui.View()
local regular_child = MockInputView{}
local regular_child2 = MockInputView{}
local last_child = MockInputView{}
parent:addviews{regular_child, regular_child2, last_child}
reset_child_mocks(parent)
parent:onInput({'a'})
test_children({0,0,1}, parent)
regular_child:setFocus(true)
reset_child_mocks(parent)
parent:onInput({'a'})
test_children({1,0,0}, parent)
regular_child2:setFocus(true)
reset_child_mocks(parent)
parent:onInput({'a'})
test_children({0,1,0}, parent)
regular_child2:setFocus(false)
reset_child_mocks(parent)
parent:onInput({'a'})
test_children({0,0,1}, parent)
end
function test.one_callback_on_double_focus()
local on_focus = mock.func()
local view = gui.View{on_focus=on_focus}
expect.eq(0, on_focus.call_count)
view:setFocus(true)
expect.eq(1, on_focus.call_count)
view:setFocus(true)
expect.eq(1, on_focus.call_count)
end
function test.one_callback_on_double_unfocus()
local on_unfocus = mock.func()
local view = gui.View{on_unfocus=on_unfocus}
expect.eq(0, on_unfocus.call_count)
view:setFocus(false)
expect.eq(0, on_unfocus.call_count)
view:setFocus(true)
expect.eq(0, on_unfocus.call_count)
view:setFocus(false)
expect.eq(1, on_unfocus.call_count)
view:setFocus(false)
expect.eq(1, on_unfocus.call_count)
end
function test.no_input_when_focus_owner_is_hidden()
local parent = gui.View()
local child1 = MockInputView()
local child2 = MockInputView()
parent:addviews{child1, child2}
child1:setFocus(true)
child1.visible = false
reset_child_mocks(parent)
parent:onInput({'a'})
test_children({0,1}, parent)
end
function test.no_input_when_ancestor_is_hidden()
local grandparent = gui.View()
local parent = MockInputView()
local child1 = MockInputView()
local child2 = MockInputView()
grandparent:addviews{parent}
parent:addviews{child1, child2}
child1:setFocus(true)
parent.visible = false
reset_child_mocks(grandparent)
grandparent:onInput({'a'})
test_children({0}, grandparent)
test_children({0,0}, parent)
end
function test.no_input_loop_in_children_of_focus_owner()
local grandparent = gui.View()
local parent = MockInputView()
local child = MockInputView()
grandparent:addviews{parent}
parent:addviews{child}
parent:setFocus(true)
reset_child_mocks(grandparent)
child:onInput({'a'})
test_children({0}, grandparent)
test_children({1}, parent)
end