Add spec for graph.step_hook property

This commit is contained in:
Alex Belykh 2021-05-17 00:53:04 +07:00
parent d734922e60
commit d051a340bc
1 changed files with 226 additions and 0 deletions

View File

@ -587,6 +587,190 @@ describe("wibox.widget.graph", function()
assert.is.equal(widget, options._graph)
end
describe("property step_hook()", function()
it("is not called when there are no values", function()
widget.step_hook = spy.new()
widget:draw(context, cr, unpack(dimensions))
widget:draw(context, cr, unpack(dimensions))
-- No values to draw, so no shapes drawn
assert.spy(widget.step_hook).was_not_called()
end)
it("is called to draw values", function()
widget.step_hook = spy.new()
-- It is called once for each value.
push_data(widget, data)
widget:draw(context, cr, unpack(dimensions))
assert.spy(widget.step_hook).was_called(#data)
-- All data is drawn despite the gap between data groups
push_data(widget, data2, 3)
widget:draw(context, cr, unpack(dimensions))
assert.spy(widget.step_hook).was_called(2*#data + #data2)
widget:draw(context, cr, unpack(dimensions))
assert.spy(widget.step_hook).was_called(3*#data + 2*#data2)
end)
it("receives proper arguments from draw()", function()
widget.step_hook = spy.new(function(_, _, _, _, step_width, options)
validate_draw_callback_options(options, nil, step_width)
end)
push_data(widget, data)
widget:draw(context, cr, unpack(dimensions))
assert.spy(widget.step_hook).was_called_with(
cr, -- cairo
match.is_number(), -- x
match.is_number(), -- value_y
match.is_number(), -- baseline_y
match.is_number(), -- step_width
match.is_table() -- options
)
end)
it("receives NaNs from draw()", function()
local nans_encountered = 0
widget.step_hook = spy.new(function(_, x, y, b, step_width)
if not(y == y) then
nans_encountered = nans_encountered + 1
end
-- These are never NaNs though.
assert.is_equal(x, x)
assert.is_equal(b, b)
assert.is_equal(step_width, step_width)
end)
-- When there are no NaNs in data, there are no NaNs.
push_data(widget, data)
push_data(widget, data2, 3)
widget:draw(context, cr, unpack(dimensions))
assert.is.equal(0, nans_encountered)
-- Write out arguments in full once so that one doesn't
-- forget to update this test if arguments get changed.
assert.spy(widget.step_hook).was_called_with(
cr, -- cairo
match.is_number(), -- x
match.is_number(), -- value_y
match.is_number(), -- baseline_y
match.is_number(), -- step_width
match.is_table() -- options
)
-- When there is as much as a single NaN, we get it,
widget:add_value(0/0, 3)
widget:draw(context, cr, unpack(dimensions))
assert.is.equal(1, nans_encountered)
-- no matter in which group,
widget:add_value(0/0, 1)
widget:draw(context, cr, unpack(dimensions))
assert.is.equal(3, nans_encountered)
-- even in a previously empty one.
widget:add_value(0/0, 2)
widget:draw(context, cr, unpack(dimensions))
assert.is.equal(6, nans_encountered)
end)
it("overrides step_shape()", function()
-- Even if step_shape is set after step_hook
widget.step_hook = spy.new()
widget.step_shape = spy.new()
push_data(widget, data)
push_data(widget, data2, 3)
widget:draw(context, cr, unpack(dimensions))
-- step_hook should have been called
assert.spy(widget.step_hook).was_called(#data + #data2)
-- and step_shape should not.
assert.spy(widget.step_shape).was_not.called()
end)
it("'s errors are not silenced by draw()", function()
widget.step_hook = spy.new(function() assert(false) end)
push_data(widget, data)
assert.has.errors(function()
widget:draw(context, cr, unpack(dimensions))
end)
assert.spy(widget.step_hook).was_called(1)
end)
it("is called only between group_start() and group_end()", function()
local inside_group = nil
widget.group_start = spy.new(function(_, group_idx)
assert.is_nil(inside_group)
inside_group = group_idx
end)
widget.group_finish = spy.new(function(_, group_idx)
assert.is_equal(group_idx, inside_group)
inside_group = nil
end)
widget.step_hook = spy.new(function(_, _, _, _, _, options)
assert.is_equal(options._group_idx, inside_group)
end)
push_data(widget, data)
push_data(widget, data2, 3)
widget:draw(context, cr, unpack(dimensions))
-- Callbacks should have been called for each data group,
-- including the empty second group,
assert.spy(widget.group_start).was_called(3)
assert.spy(widget.step_hook).was_called(#data + #data2)
assert.spy(widget.group_finish).was_called(3)
-- and group_finish() was the last of them.
assert.is_nil(inside_group)
end)
it("is disabled by falsy group_colors", function()
-- TODO: if should_draw_data_group() gets decided on,
-- this should be rewritten in terms of it and
-- should_draw_data_group() should be tested by colors in turn.
widget.step_hook = spy.new()
widget.group_colors = { "#feedf00d", "#deadbeef", "#0badcafe" }
push_data(widget, data, 1)
push_data(widget, data, 2)
push_data(widget, data2, 3)
widget:draw(context, cr, unpack(dimensions))
assert.spy(widget.step_hook).was_called(2*#data + #data2)
widget.step_hook:clear()
widget.group_colors = { nil, false, "#feedf00d" }
widget:draw(context, cr, unpack(dimensions))
assert.spy(widget.step_hook).was_called(#data2)
end)
it("always starts drawing values starting with x=0", function()
local first_value = nil
widget.step_hook = function(_, x)
if first_value == nil then
first_value = x
end
end
widget.group_finish = spy.new(function(_, group_idx)
assert.is.equal(group_idx ~= 2 and 0 or nil, first_value)
first_value = nil
end)
push_data(widget, data, 1)
push_data(widget, data2, 3)
-- With default settings.
widget:draw(context, cr, unpack(dimensions))
-- And with step_width.
widget.step_width = 3
widget:draw(context, cr, unpack(dimensions))
-- And with step_spacing.
widget.step_spacing = 3
widget:draw(context, cr, unpack(dimensions))
assert.spy(widget.group_finish).was_called(9)
end)
end) -- end describe(step_hook)
describe("property group_start()", function()
it("is called by draw() for each data group", function()
widget.group_start = spy.new()
@ -625,6 +809,27 @@ describe("wibox.widget.graph", function()
end)
assert.spy(widget.group_start).was_called(1)
end)
it("shifts coordinates when set to a number", function()
local x_coords = {}
widget.step_hook = function(_, x)
table.insert(x_coords, x)
end
-- First a run without setting it.
assert.is_nil(widget.group_start)
push_data(widget, data)
widget:draw(context, cr, unpack(dimensions))
-- Now a run with setting it to a number.
local x_coords_unshifted = {unpack(x_coords)}
x_coords = {}
widget.group_start = 3
widget:draw(context, cr, unpack(dimensions))
assert.is.equal(#x_coords_unshifted, #x_coords)
for i, x in ipairs(x_coords_unshifted) do
assert.is.equal(x+3, x_coords[i])
end
end)
end) -- end describe(group_start)
describe("property group_finish()", function()
@ -1007,6 +1212,27 @@ describe("wibox.widget.graph", function()
assert.is.equal(2, magic_color_used)
end)
it("'s returned color is set early, so as to be available in the corresponding step_hook()", function()
widget.pick_data_group_color = function(_, data_group)
return (data_group % 2 == 1) and magic_color or "#feedf00d"
end
widget.step_hook = function(_, _, _, _, _, options)
if options._group_idx % 2 == 1 then
assert.is.equal(magic_color, current_cr_source)
else
assert.is_not.equal(magic_color, current_cr_source)
end
end
assert.is.equal(0, magic_color_used)
assert.is_nil(current_cr_source)
push_data(widget, data, 1)
push_data(widget, data2, 2)
push_data(widget, data2, 3)
push_data(widget, data, 4)
widget:draw(context, cr, unpack(dimensions))
assert.is.equal(2, magic_color_used)
end)
it("returns some valid color even in a fresh widget", function()
local groups = {1, 2, 50, 0, -1}
local colors = {}