composed events acceptance test passes. I have to make it more complicated

This commit is contained in:
Enrique García 2011-10-29 02:45:39 +02:00
parent 2aa41a28c5
commit 9dcf8055cf
2 changed files with 71 additions and 16 deletions

View File

@ -9,22 +9,51 @@
local beholder = {} local beholder = {}
local function copy(t)
local c={}
for i=1,#t do c[i]=t[i] end
return c
end
local function findNode(self, event) local function extractEventAndActionFromParams(...)
return self._nodes[event] local params = {...}
local action = table.remove(params, #params)
return params, action
end end
local function findNodeById(self, id) local function findNodeById(self, id)
return self._nodesById[id] return self._nodesById[id]
end end
local function createNode(self, event) local function findOrCreateNode(self, event)
self._nodes[event] = {actions={}} local current = self._root
return self._nodes[event] local key
for i=1, #event do
key = event[i]
current.children[key] = current.children[key] or {actions={},children={}}
current = current.children[key]
end
return current
end end
local function findOrCreateNode(self, event) local function executeNodeActions(self, event)
return findNode(self,event) or createNode(self,event) local current = self._root
local counter = 0
local params = copy(event)
local key
for i=1,#event do
key = event[i]
current = current.children[key]
if not current then break end
table.remove(params, 1)
for _,action in pairs(current.actions) do
action(unpack(params))
counter = counter + 1
end
end
return counter > 0 and counter
end end
local function addActionToNode(self, node, action) local function addActionToNode(self, node, action)
@ -40,16 +69,13 @@ local function removeActionFromNode(node, id)
return true return true
end end
local function executeNodeActions(node, ...)
for _,action in pairs(node.actions) do action(...) end
end
function beholder:reset() function beholder:reset()
self._nodes = {} self._root = { actions={}, children={} }
self._nodesById = setmetatable({}, {__mode="k"}) self._nodesById = setmetatable({}, {__mode="k"})
end end
function beholder:observe(event, action) function beholder:observe(...)
local event, action = extractEventAndActionFromParams(...)
return addActionToNode(self, findOrCreateNode(self, event), action) return addActionToNode(self, findOrCreateNode(self, event), action)
end end
@ -57,9 +83,9 @@ function beholder:stopObserving(id)
return removeActionFromNode(findNodeById(self, id), id) return removeActionFromNode(findNodeById(self, id), id)
end end
function beholder:trigger(event, ...) function beholder:trigger(...)
local node = findNode(self, event) local event = {...}
if node then executeNodeActions(node, ...) end return executeNodeActions(self, event)
end end
beholder:reset() beholder:reset()

View File

@ -22,6 +22,13 @@ describe("Unit", function()
assert_equal(counter1, 1) assert_equal(counter1, 1)
assert_equal(counter2, 1) assert_equal(counter2, 1)
end) end)
it("allows observing composed events", function()
local counter = 0
beholder:observe("KEYPRESS", "start", function() counter = counter + 1 end)
beholder:trigger("KEYPRESS", "start")
assert_equal(counter, 1)
end)
end) end)
describe(":stopObserving", function() describe(":stopObserving", function()
@ -77,6 +84,28 @@ describe("Unit", function()
end) end)
describe(":trigger", function()
it("does not error on random stuff", function()
assert_not_error(function() beholder:trigger("FOO") end)
end)
it("returns false on events with no actions", function()
assert_equal(false, beholder:trigger("FOO"))
end)
it("returns false if there was a node with no actions", function()
beholder:observe("ONE","TWO", function() end)
assert_equal(false, beholder:trigger("ONE"))
end)
it("returns the number of actions executed", function()
beholder:observe("X", function() end)
beholder:observe("X", function() end)
assert_equal(2, beholder:trigger("X"))
end)
end)
describe(":reset", function() describe(":reset", function()