Files
lua-matrix/spec/eventable_spec.lua
2016-07-03 22:55:28 +03:00

150 lines
4.3 KiB
Lua

--
-- eventable.lua
-- Copyright (C) 2016 Adrian Perez <aperez@igalia.com>
--
-- Distributed under terms of the MIT license.
--
local eventable = require "matrix.eventable"
describe("matrix.eventable", function ()
it("can be imported", function ()
assert.is.table(eventable)
end)
it("has a matrix.eventable.functions function", function ()
assert.is_function(eventable.functions)
end)
it("has a matrix.eventable.object function", function ()
assert.is_function(eventable.object)
end)
end)
describe("matrix.eventable.functions()", function ()
it("returns three callable functions", function ()
local s = spy.new(eventable.functions)
local fire, hook, unhook = s()
assert.spy(s).returned_with(
match.is_function(),
match.is_function(),
match.is_function())
end)
it("calls hooked handlers when firing events", function ()
local flag = false
local handler = spy.new(function () flag = true end)
local fire, hook = assert(eventable.functions())
hook("foo", handler)
fire("foo")
assert.spy(handler).was_called(1)
assert.is_true(flag)
end)
it("stops at first handler that returs some value", function ()
local fire, hook = assert(eventable.functions())
local flag1, flag2, flag3 = false, false, false
hook("foo", function () flag1 = true end)
hook("foo", function () flag2 = true ; return 42 end)
hook("foo", function () flag3 = true ; return 0 end)
assert.is_equal(42, fire("foo"))
assert.is_true(flag1)
assert.is_true(flag2)
assert.is_false(flag3)
end)
it("accepts a table where to store the event map", function ()
local events = {}
local fire, hook = assert(eventable.functions(events))
hook("foo", function () end)
assert.truthy(events.foo)
end)
it("allows unhooking a handler", function ()
local fire, hook, unhook = assert(eventable.functions())
local h1 = spy.new(function () end)
local h2 = spy.new(function () end)
hook("foo", h1)
hook("foo", h2)
fire("foo")
assert.spy(h1).was_called(1)
assert.spy(h2).was_called(1)
unhook("foo", h2)
fire("foo")
assert.spy(h1).was_called(2)
assert.spy(h2).was_called(1)
end)
it("allows unhooking all handlers at once", function ()
local fire, hook, unhook = assert(eventable.functions())
local h1 = spy.new(function () end)
local h2 = spy.new(function () end)
hook("foo", h1)
hook("foo", h2)
fire("foo")
assert.spy(h1).was_called(1)
assert.spy(h2).was_called(1)
unhook("foo")
fire("foo")
assert.spy(h1).was_called(1)
assert.spy(h2).was_called(1)
end)
it("allows retrieving the list of handlers", function ()
local fire, hook = assert(eventable.functions())
local h = function () end
hook("foo", h)
assert.same({ h }, hook("foo"))
hook("foo", h)
assert.same({ h, h }, hook("foo"))
end)
it("unhooks multiple instances of the same handler", function ()
local fire, hook, unhook = assert(eventable.functions())
local h = function () end
hook("foo", h)
hook("foo", h)
assert.same({ h, h }, hook("foo"))
unhook("foo", h)
assert.same({}, hook("foo"))
end)
end)
describe("matrix.eventable.object()", function ()
it("creates a new table when no parameters are passed", function ()
assert.is_table(eventable.object())
end)
it("adds methods to an existing table", function ()
local t = {}
assert.is_equal(t, eventable.object(t))
assert.is_function(t.fire)
assert.is_function(t.hook)
assert.is_function(t.unhook)
end)
it("passes the table as first argument when firing events", function ()
local t = assert(eventable.object())
local h = spy.new(function (o)
assert.is_equal(t, o)
end)
t:hook("foo", h)
t:fire("foo")
assert.spy(h).was_called_with(t)
end)
it("allows chaining :hook() and :unhook() calls", function ()
local t = assert(eventable.object())
local h = function () end
assert.is_equal(t, t:hook("foo", h))
assert.is_equal(t, t:unhook("foo", h))
assert.is_equal(t, t:hook("foo", h):unhook("foo", h))
end)
end)