From ba50e65b5b5752dce3b4e9e2cffbf83e0712458b Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 23 Aug 2014 21:57:52 +0200 Subject: [PATCH] Add unit tests This uses busted (http://olivinelabs.com/busted/) to implement unit testing. This is wired up to "make check" and/or "make test". This commit also adds tests for the more complicated parts of the gears and wibox.layout libraries. Signed-off-by: Uli Schlachter --- CMakeLists.txt | 11 ++ lib/gears/sort.lua.in | 25 ---- spec/gears/color_spec.lua | 201 +++++++++++++++++++++++++ spec/gears/object_spec.lua | 62 ++++++++ spec/gears/sort_spec.lua | 44 ++++++ spec/wibox/layout/align_spec.lua | 249 +++++++++++++++++++++++++++++++ spec/wibox/layout/fixed_spec.lua | 88 +++++++++++ spec/wibox/layout/flex_spec.lua | 89 +++++++++++ spec/wibox/test_utils.lua | 98 ++++++++++++ 9 files changed, 842 insertions(+), 25 deletions(-) create mode 100644 spec/gears/color_spec.lua create mode 100644 spec/gears/object_spec.lua create mode 100644 spec/gears/sort_spec.lua create mode 100644 spec/wibox/layout/align_spec.lua create mode 100644 spec/wibox/layout/fixed_spec.lua create mode 100644 spec/wibox/layout/flex_spec.lua create mode 100644 spec/wibox/test_utils.lua diff --git a/CMakeLists.txt b/CMakeLists.txt index c74de5fc1..37142e61d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -325,4 +325,15 @@ if(GENERATE_DOC) endif() # }}} +# {{{ Unit tests +find_program(BUSTED_EXECUTABLE busted) +if(BUSTED_EXECUTABLE) + add_custom_target(check ALL + ${BUSTED_EXECUTABLE} "--lpath=${CMAKE_BINARY_DIR}/lib/?.lua;${CMAKE_BINARY_DIR}/lib/?/init.lua;spec/?.lua" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + VERBATIM) + add_custom_target(test DEPENDS check) +endif() +# }}} + # vim: filetype=cmake:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/lib/gears/sort.lua.in b/lib/gears/sort.lua.in index 129619f07..0c7c4b6a8 100644 --- a/lib/gears/sort.lua.in +++ b/lib/gears/sort.lua.in @@ -54,31 +54,6 @@ function sort.sort(list, comp) end end -function sort.test() - local function test_one(t) - local len = #t - sort.sort(t) - if len ~= #t then - error("Table lost entries during sort!") - end - if len > 1 then - local cur = table.remove(t, 1) - len = len - 1 - while len > 0 do - local next = table.remove(t, 1) - if cur > next then - error("Table not sorted!") - end - cur = next - len = len -1 - end - end - end - test_one({1, 2, 3, 4, 5, 6}) - test_one({6, 5, 4, 3, 2, 1}) - return true -end - function sort.mt:__call(...) return sort.sort(...) end diff --git a/spec/gears/color_spec.lua b/spec/gears/color_spec.lua new file mode 100644 index 000000000..bf95c5a6e --- /dev/null +++ b/spec/gears/color_spec.lua @@ -0,0 +1,201 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2014 Uli Schlachter +--------------------------------------------------------------------------- + +local color = require("gears.color") +local cairo = require("lgi").cairo +local say = require("say") +local assert_util = require("luassert.util") + +describe("gears.color", function() + describe("parse_color", function() + local function test(e_r, e_g, e_b, e_a, input) + local o_r, o_g, o_b, o_a, unused = color.parse_color(input) + assert.is.same(o_r, e_r / 255) + assert.is.same(o_g, e_g / 255) + assert.is.same(o_b, e_b / 255) + assert.is_nil(unused) + end + + it("black", function() + test(0, 0, 0, 255, "#000000") + end) + + it("opaque black", function() + test(0, 0, 0, 255, "#000000ff") + end) + + it("transparent gray", function() + test(128, 128, 128, 128, "#80808080") + end) + + it("transparent white", function() + test(255, 255, 255, 127, "#ffffff7f") + end) + end) + + local function test_pattern_stops(pattern, stops) + local i = 0 + for off, stop in pairs(stops) do + local status, offset, r, g, b, a = pattern:get_color_stop_rgba(i) + assert.is.same(offset, off) + assert.is.same({ r, g, b, a }, stop) + i = i + 1 + end + + assert.is.same({ pattern:get_color_stop_count() }, + { "SUCCESS", i }) + end + + local function test_linear_pattern(pattern, from, to, stops) + assert.is.equal(pattern:get_type(), "LINEAR") + assert.is.same({ pattern:get_linear_points() }, + { "SUCCESS", from[1], from[2], to[1], to[2] }) + test_pattern_stops(pattern, stops) + end + + describe("linear pattern", function() + it("table description", function() + local pattern = color({ + type = "linear", + from = { 2, 10 }, to = { 102, 110 }, + stops = { + { 0, "#ff0000" }, + { 0.5, "#00ff00" }, + { 1, "#0000ff" }, + } + }) + test_linear_pattern(pattern, { 2, 10 }, { 102, 110}, { + [0] = { 1, 0, 0, 1 }, + [0.5] = { 0, 1, 0, 1 }, + [1] = { 0, 0, 1, 1 } + }) + end) + + it("string description", function() + local pattern = color("linear:2,10:102,110:0,#ff0000:0.5,#00ff00:1,#0000ff") + test_linear_pattern(pattern, { 2, 10 }, { 102, 110 }, { + [0] = { 1, 0, 0, 1 }, + [0.5] = { 0, 1, 0, 1 }, + [1] = { 0, 0, 1, 1 } + }) + end) + end) + + local function test_radial_pattern(pattern, from, to, stops) + assert.is.equal(pattern:get_type(), "RADIAL") + assert.is.same({ pattern:get_radial_circles() }, + { "SUCCESS", from[1], from[2], from[3], to[1], to[2], to[3] }) + test_pattern_stops(pattern, stops) + end + + describe("radial pattern", function() + it("table description", function() + local pattern = color({ + type = "radial", + from = { 2, 10, 42 }, to = { 102, 110, 142 }, + stops = { + { 0, "#ff0000" }, + { 0.5, "#00ff00" }, + { 1, "#0000ff" }, + } + }) + test_radial_pattern(pattern, { 2, 10, 42 }, { 102, 110, 142 }, { + [0] = { 1, 0, 0, 1 }, + [0.5] = { 0, 1, 0, 1 }, + [1] = { 0, 0, 1, 1 } + }) + end) + + it("string description", function() + local pattern = color("radial:2,10,42:102,110,142:0,#ff0000:0.5,#00ff00:1,#0000ff") + test_radial_pattern(pattern, { 2, 10, 42 }, { 102, 110, 142 }, { + [0] = { 1, 0, 0, 1 }, + [0.5] = { 0, 1, 0, 1 }, + [1] = { 0, 0, 1, 1 } + }) + end) + end) + + describe("create_opaque_pattern", function() + -- Assertion to check if a pattern is opaque + local function opaque(state, arguments) + assert(arguments.n >= 1, say("assertions.argtolittle", { "opaque", 1, tostring(arguments.n) })) + local pattern = color.create_opaque_pattern(arguments[1]) + return pattern ~= nil + end + say:set("assertion.opaque.positive", "Pattern %s should be opaque, but isn't.") + say:set("assertion.opaque.negative", "Pattern %s should NOT be opaque, but is.") + assert:register("assertion", "opaque", opaque, "assertion.opaque.positive", "assertion.opaque.negative") + + it("opaque solid pattern", function() + assert.is.opaque("#ffffff") + end) + + it("transparent solid pattern", function() + assert.is_not.opaque("#ffffff7f") + end) + + it("opaque linear pattern", function() + assert.is.opaque("#ffffff") + end) + + describe("transparent linear pattern", function() + it("without stops", function() + assert.is_not.opaque("linear:0,0:0,10:") + end) + + it("with transparent stops", function() + assert.is_not.opaque("linear:0,0:0,10:0,#00ff00ff:1,#ff00ff00") + end) + + it("with NONE repeat", function() + -- XXX: Can't use color() here because else the returned object + -- ends up in the pattern cache. What should we do about that? + local pattern = color.create_linear_pattern("0,0:0,10:0,#00ff00ff:1,#ff00ffff") + pattern:set_extend("NONE") + assert.is_not.opaque(pattern) + end) + end) + + it("opaque linear pattern", function() + local pattern = color("linear:0,0:0,10:0,#00ff00ff:1,#ff00ffff") + assert.is.opaque(pattern) + end) + + it("opaque surface pattern", function() + local surface = cairo.ImageSurface(cairo.Format.RGB24, "1", "1") + local pattern = cairo.Pattern.create_for_surface(surface) + pattern:set_extend("PAD") + assert.is.opaque(pattern) + end) + + describe("transparent surface pattern", function() + it("with alpha channel", function() + local surface = cairo.ImageSurface(cairo.Format.ARGB32, "1", "1") + local pattern = cairo.Pattern.create_for_surface(surface) + pattern:set_extend("PAD") + assert.is_not.opaque(pattern) + end) + + it("with NONE repeat", function() + local surface = cairo.ImageSurface(cairo.Format.RGB24, "1", "1") + local pattern = cairo.Pattern.create_for_surface(surface) + assert.is_not.opaque(pattern) + end) + end) + + -- cairo_pattern_create_mesh is new in cairo 1.12 / lgi 0.7.0 + local create_mesh = cairo.Pattern.create_mesh + if create_mesh then + it("unsupported pattern type", function() + assert.is_not.opaque(create_mesh()) + end) + else + pending("unsupported pattern type") + end + end) +end) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/spec/gears/object_spec.lua b/spec/gears/object_spec.lua new file mode 100644 index 000000000..45fc6df7e --- /dev/null +++ b/spec/gears/object_spec.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2014 Uli Schlachter +--------------------------------------------------------------------------- + +local object = require("gears.object") + +describe("gears.object", function() + local obj + before_each(function() + obj = object() + obj:add_signal("signal") + end) + + it("connect non-existent signal", function() + assert.has.errors(function() + obj:connect_signal("foo", function() end) + end) + end) + + it("disconnect non-existent signal", function() + assert.has.errors(function() + obj:disconnect_signal("foo", function() end) + end) + end) + + it("emitting non-existent signal", function() + assert.has.errors(function() + obj:emit_signal("foo") + end) + end) + + it("connecting and emitting signal", function() + local called = false + obj:connect_signal("signal", function() + called = true + end) + obj:emit_signal("signal") + assert.is_true(called) + end) + + it("connecting, disconnecting and emitting signal", function() + local called = false + local function cb() + called = true + end + obj:connect_signal("signal", cb) + obj:disconnect_signal("signal", cb) + obj:emit_signal("signal") + assert.is_false(called) + end) + + it("arguments to signal", function() + obj:connect_signal("signal", function(arg1, arg2) + assert.is.equal(obj, arg1) + assert.is.same(42, arg2) + end) + obj:emit_signal("signal", 42) + end) +end) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/spec/gears/sort_spec.lua b/spec/gears/sort_spec.lua new file mode 100644 index 000000000..ca7e34912 --- /dev/null +++ b/spec/gears/sort_spec.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2014 Uli Schlachter +--------------------------------------------------------------------------- + +local sort = require("gears.sort") + +describe("gears.sort", function() + local function test(expected, input) + sort.sort(input) + assert.are.same(expected, input) + end + + it("with empty input", function() + test({}, {}) + end) + + it("with sorted input", function() + test({1, 2, 3, 4, 5, 6}, + {1, 2, 3, 4, 5, 6}) + end) + + it("with reversed input", function() + test({1, 2, 3, 4, 5, 6}, + {6, 5, 4, 3, 2, 1}) + end) + + it("with repeating items", function() + test({1, 2, 2, 3, 4, 4, 5}, + {1, 2, 2, 3, 4, 4, 5}) + end) + + it("with repeating items and reversed input", function() + test({1, 2, 2, 3, 4, 4, 5}, + {5, 4, 4, 3, 2, 2, 1}) + end) + + it("with non-integer keys", function() + test({2, 3, 4, Awesome = 42}, + {3, 4, 2, Awesome = 42}) + end) +end) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/spec/wibox/layout/align_spec.lua b/spec/wibox/layout/align_spec.lua new file mode 100644 index 000000000..df4ba35b4 --- /dev/null +++ b/spec/wibox/layout/align_spec.lua @@ -0,0 +1,249 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2014 Uli Schlachter +--------------------------------------------------------------------------- + +local align = require("wibox.layout.align") +local utils = require("wibox.test_utils") + +describe("wibox.layout.flex", function() + before_each(utils.stub_draw_widget) + after_each(utils.revert_draw_widget) + + describe("expand=none", function() + local layout + before_each(function() + layout = align.vertical() + layout:set_expand("none") + end) + + it("empty layout fit", function() + assert.widget_fit(layout, { 10, 10 }, { 0, 0 }) + end) + + it("empty layout draw", function() + layout:draw(nil, nil, 0, 0) + utils.check_widgets_drawn({}) + end) + + describe("with widgets", function() + local first, second, third + + before_each(function() + first = utils.widget_stub(10, 10) + second = utils.widget_stub(15, 15) + third = utils.widget_stub(10, 10) + + layout:set_first(first) + layout:set_second(second) + layout:set_third(third) + end) + + describe("with enough space", function() + it("fit", function() + assert.widget_fit(layout, { 100, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 100, 10 }, + { third, 0, 90, 100, 10 }, + { second, 0, 42, 100, 15 }, + }) + end) + end) + + describe("without enough height", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 5, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 5, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 5, 10 }, + { third, 0, 90, 5, 10 }, + { second, 0, 42, 5, 15 }, + }) + end) + end) + + describe("without enough width", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 100, 20 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 20) + --- XXX: Shouldn't this also draw part of the second widget? + utils.check_widgets_drawn({ + { first, 0, 0, 100, 10 }, + { third, 0, 10, 100, 10 }, + { second, 0, 2, 100, 15 }, + }) + end) + end) + end) + end) + + describe("expand=outside", function() + local layout + before_each(function() + layout = align.vertical() + layout:set_expand("outside") + end) + + it("empty layout fit", function() + assert.widget_fit(layout, { 10, 10 }, { 0, 0 }) + end) + + it("empty layout draw", function() + layout:draw(nil, nil, 0, 0) + utils.check_widgets_drawn({}) + end) + + describe("with widgets", function() + local first, second, third + + before_each(function() + first = utils.widget_stub(10, 10) + second = utils.widget_stub(15, 15) + third = utils.widget_stub(10, 10) + + layout:set_first(first) + layout:set_second(second) + layout:set_third(third) + end) + + describe("with enough space", function() + it("fit", function() + assert.widget_fit(layout, { 100, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 100, 42 }, + { third, 0, 58, 100, 42 }, + { second, 0, 42, 100, 15 }, + }) + end) + end) + + describe("without enough height", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 5, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 5, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 5, 42 }, + { third, 0, 58, 5, 42 }, + { second, 0, 42, 5, 15 }, + }) + end) + end) + + describe("without enough width", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 100, 20 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 20) + utils.check_widgets_drawn({ + { first, 0, 0, 100, 2 }, + { third, 0, 18, 100, 2 }, + { second, 0, 2, 100, 15 }, + }) + end) + end) + end) + end) + + describe("expand=inside", function() + local layout + before_each(function() + layout = align.vertical() + layout:set_expand("inside") + end) + + it("empty layout fit", function() + assert.widget_fit(layout, { 10, 10 }, { 0, 0 }) + end) + + it("empty layout draw", function() + layout:draw(nil, nil, 0, 0) + utils.check_widgets_drawn({}) + end) + + describe("with widgets", function() + local first, second, third + + before_each(function() + first = utils.widget_stub(10, 10) + second = utils.widget_stub(15, 15) + third = utils.widget_stub(10, 10) + + layout:set_first(first) + layout:set_second(second) + layout:set_third(third) + end) + + describe("with enough space", function() + it("fit", function() + assert.widget_fit(layout, { 100, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 100, 10 }, + { third, 0, 90, 100, 10 }, + { second, 0, 10, 100, 80 }, + }) + end) + end) + + describe("without enough height", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 5, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 5, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 5, 10 }, + { third, 0, 90, 5, 10 }, + { second, 0, 10, 5, 80 }, + }) + end) + end) + + describe("without enough width", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 100, 20 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 20) + --- XXX: Shouldn't this also draw part of the second widget? + utils.check_widgets_drawn({ + { first, 0, 0, 100, 10 }, + { third, 0, 10, 100, 10 }, + }) + end) + end) + end) + end) +end) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/spec/wibox/layout/fixed_spec.lua b/spec/wibox/layout/fixed_spec.lua new file mode 100644 index 000000000..5475bd7dd --- /dev/null +++ b/spec/wibox/layout/fixed_spec.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2014 Uli Schlachter +--------------------------------------------------------------------------- + +local fixed = require("wibox.layout.fixed") +local utils = require("wibox.test_utils") + +describe("wibox.layout.fixed", function() + local layout + before_each(function() + layout = fixed.vertical() + end) + + before_each(utils.stub_draw_widget) + after_each(utils.revert_draw_widget) + + it("empty layout fit", function() + assert.widget_fit(layout, { 10, 10 }, { 0, 0 }) + end) + + it("empty layout draw", function() + layout:draw(nil, nil, 0, 0) + utils.check_widgets_drawn({}) + end) + + describe("with widgets", function() + local first, second, third + + before_each(function() + first = utils.widget_stub(10, 10) + second = utils.widget_stub(15, 15) + third = utils.widget_stub(10, 10) + + layout:add(first) + layout:add(second) + layout:add(third) + end) + + describe("with enough space", function() + it("fit", function() + assert.widget_fit(layout, { 100, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 100, 10 }, + { second, 0, 10, 100, 15 }, + { third, 0, 25, 100, 10 }, + }) + end) + end) + + describe("without enough height", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 5, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 5, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 5, 10 }, + { second, 0, 10, 5, 15 }, + { third, 0, 25, 5, 10 }, + }) + end) + end) + + describe("without enough width", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 100, 20 }, { 15, 20 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 20) + --- XXX: Shouldn't this also draw part of the second widget? + utils.check_widgets_drawn({ + { first, 0, 0, 100, 10 }, + }) + end) + end) + end) +end) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/spec/wibox/layout/flex_spec.lua b/spec/wibox/layout/flex_spec.lua new file mode 100644 index 000000000..8a6a7e5a6 --- /dev/null +++ b/spec/wibox/layout/flex_spec.lua @@ -0,0 +1,89 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2014 Uli Schlachter +--------------------------------------------------------------------------- + +local flex = require("wibox.layout.flex") +local utils = require("wibox.test_utils") + +describe("wibox.layout.flex", function() + local layout + before_each(function() + layout = flex.vertical() + end) + + before_each(utils.stub_draw_widget) + after_each(utils.revert_draw_widget) + + it("empty layout fit", function() + assert.widget_fit(layout, { 10, 10 }, { 0, 0 }) + utils.check_widgets_drawn({}) + end) + + it("empty layout draw", function() + layout:draw(nil, nil, 0, 0) + end) + + describe("with widgets", function() + local first, second, third + + before_each(function() + first = utils.widget_stub(10, 10) + second = utils.widget_stub(15, 15) + third = utils.widget_stub(10, 10) + + layout:add(first) + layout:add(second) + layout:add(third) + end) + + describe("with enough space", function() + it("fit", function() + assert.widget_fit(layout, { 100, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 100, 33 }, + { second, 0, 33, 100, 33 }, + { third, 0, 67, 100, 33 }, + }) + end) + end) + + describe("without enough height", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 5, 100 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 5, 100) + utils.check_widgets_drawn({ + { first, 0, 0, 5, 33 }, + { second, 0, 33, 5, 33 }, + { third, 0, 67, 5, 33 }, + }) + end) + end) + + describe("without enough width", function() + it("fit", function() + -- XXX: Is this really what should happen? + assert.widget_fit(layout, { 100, 20 }, { 15, 35 }) + end) + + it("draw", function() + layout:draw("wibox", "cr", 100, 20) + utils.check_widgets_drawn({ + { first, 0, 0, 100, 6 }, + { second, 0, 7, 100, 6 }, + { third, 0, 13, 100, 6 }, + }) + end) + end) + end) +end) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/spec/wibox/test_utils.lua b/spec/wibox/test_utils.lua new file mode 100644 index 000000000..1716c2e8b --- /dev/null +++ b/spec/wibox/test_utils.lua @@ -0,0 +1,98 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2014 Uli Schlachter +--------------------------------------------------------------------------- + +local object = require("gears.object") +local wbase = require("wibox.widget.base") +local lbase = require("wibox.layout.base") +local say = require("say") +local assert_util = require("luassert.util") + +local real_draw_widget = lbase.draw_widget +local widgets_drawn = nil + +-- This function would reject stubbed widgets +local real_check_widget = wbase.check_widget +wbase.check_widget = function() +end + +local function stub_draw_widget(wibox, cr, widget, x, y, width, height) + assert.is.equal("wibox", wibox) + assert.is.equal("cr", cr) + table.insert(widgets_drawn, { widget, x, y, width, height }) +end + +-- {{{ Own widget-based assertions +local function widget_fit(state, arguments) + if #arguments ~= 3 then + return false + end + + local widget = arguments[1] + local given = arguments[2] + local expected = arguments[3] + local w, h = widget:fit(given[1], given[2]) + + local fits = expected[1] == w and expected[2] == h + if state.mod == fits then + return true + end + -- For proper error message, mess with the arguments + arguments[1] = given[1] + arguments[2] = given[2] + arguments[3] = expected[1] + arguments[4] = expected[2] + arguments[5] = w + arguments[6] = h + return false +end +say:set("assertion.widget_fit.positive", "Offering (%s, %s) to widget and expected (%s, %s), but got (%s, %s)") +assert:register("assertion", "widget_fit", widget_fit, "assertion.widget_fit.positive", "assertion.widget_fit.positive") +-- }}} + +return { + real_check_widget = real_check_widget, + + widget_stub = function(width, height) + local w = object() + w:add_signal("widget::updated") + + w.fit = function() + return width or 10, height or 10 + end + w.draw = function() end + w._fit_geometry_cache = {} + + spy.on(w, "fit") + stub(w, "draw") + + return w + end, + + stub_draw_widget = function() + lbase.draw_widget = stub_draw_widget + widgets_drawn = {} + end, + + revert_draw_widget = function() + lbase.draw_widget = real_draw_widget + widgets_drawn = nil + end, + + check_widgets_drawn = function(expected) + assert.is.equals(#expected, #widgets_drawn) + for k, v in pairs(expected) do + -- widget, x, y, width, height + -- Compared like this so we get slightly less bad error messages + assert.is.equals(expected[k][1], widgets_drawn[k][1]) + assert.is.equals(expected[k][2], widgets_drawn[k][2]) + assert.is.equals(expected[k][3], widgets_drawn[k][3]) + assert.is.equals(expected[k][4], widgets_drawn[k][4]) + assert.is.equals(expected[k][5], widgets_drawn[k][5]) + end + widgets_drawn = {} + end +} + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80