Browse Source

wip more tests

develop
Harald Albrecht 5 years ago
parent
commit
181ada66d3
  1. 12
      sdcard/layouts/shift.lua
  2. 91
      sdcard/snippets/routehandlers.lua
  3. 43
      spec/keybowhandler.lua
  4. 69
      spec/keybowhandler_spec.lua
  5. 10
      spec/multibow_spec.lua
  6. 90
      spec/routehandlers_spec.lua
  7. 120
      spec/shift_spec.lua

12
sdcard/layouts/shift.lua

@ -46,6 +46,10 @@ SHIFT →LAYOUT 🔆BRIGHT
]]--
shift.KEY_SHIFT = 11
shift.KEY_LAYOUT = 8
shift.KEY_BRIGHTNESS = 5
function shift.grab(key)
mb.grab("shift-shifted")
end
@ -70,15 +74,15 @@ end
shift.keymap = {
name="shift",
permanent=true,
[11] = {c={r=1, g=1, b=1}, press=shift.grab, release=shift.release},
[shift.KEY_SHIFT] = {c={r=1, g=1, b=1}, press=shift.grab, release=shift.release},
}
shift.keymap_shifted = {
name="shift-shifted",
secondary=true,
[11] = {c={r=1, g=1, b=1}, press=shift.grab, release=shift.release},
[shift.KEY_SHIFT] = {c={r=1, g=1, b=1}, press=shift.grab, release=shift.release},
[8] = {c={r=0, g=1, b=1}, press=shift.cycle},
[5] = {c={r=0.5, g=0.5, b=0.5}, press=shift.brightness}
[shift.KEY_LAYOUT] = {c={r=0, g=1, b=1}, press=shift.cycle},
[shift.KEY_BRIGHTNESS] = {c={r=0.5, g=0.5, b=0.5}, press=shift.brightness}
}
mb.register_keymap(shift.keymap)

91
sdcard/snippets/routehandlers.lua

@ -18,60 +18,61 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
]] --
-- This all-key, central key router forwards Keybow key events to
-- their correct handlers, depending on which keyboard layout currently
-- is active.
function mb.route(keyno, pressed)
local keydef
-- Checks for a keymap grab being enforced at this time...
if mb.grab_keymap then
print("routing GRABBED key")
keydef = mb.grab_keymap[keyno]
else
-- Checks for key in permanent keymaps first...
for name, keymap in pairs(mb.keymaps) do
if keymap.permanent then
keydef = keymap[keyno]
if keydef then; break; end
end
local keydef
-- Checks for a keymap grab being enforced at this time...
if mb.grab_keymap then
keydef = mb.grab_keymap[keyno]
else
-- Checks for key in permanent keymaps first...
for name, keymap in pairs(mb.keymaps) do
if keymap.permanent then
keydef = keymap[keyno]
if keydef then
break
end
end
end
-- Checks for key in current keymap if no persistent key was found yet.
if not keydef and mb.current_keymap then
keydef = mb.current_keymap[keyno]
end
end
-- Checks for key in current keymap if no persistent key was found yet.
if not keydef and mb.current_keymap then
keydef = mb.current_keymap[keyno]
end
end
-- Bails out if no key definition to route to could be found.
if not keydef then; return; end
--
if pressed then
for led = 0, 11 do
if led ~= keyno then; mb.led(led, {r=0, g=0, b=0}); end
end
if keydef.press then
keydef.press(keyno)
-- Bails out if no key definition to route to could be found.
if not keydef then
return
end
else
if keydef.release then
keydef.release(keyno)
-- We found a route, so we need to call its associated handler and
-- also handle the LED lightshow.
if pressed then
for led = 0, 11 do
if led ~= keyno then
mb.led(led, {r = 0, g = 0, b = 0})
end
end
if keydef.press then
keydef.press(keyno)
end
else
if keydef.release then
keydef.release(keyno)
end
mb.activate_leds()
end
mb.activate_leds()
end
end
-- Routes all keybow key handling through our central key router
function handle_key_00(pressed); mb.route(0, pressed); end
function handle_key_01(pressed); mb.route(1, pressed); end
function handle_key_02(pressed); mb.route(2, pressed); end
function handle_key_03(pressed); mb.route(3, pressed); end
function handle_key_04(pressed); mb.route(4, pressed); end
function handle_key_05(pressed); mb.route(5, pressed); end
function handle_key_06(pressed); mb.route(6, pressed); end
function handle_key_07(pressed); mb.route(7, pressed); end
function handle_key_08(pressed); mb.route(8, pressed); end
function handle_key_09(pressed); mb.route(9, pressed); end
function handle_key_10(pressed); mb.route(10, pressed); end
function handle_key_11(pressed); mb.route(11, pressed); end
-- by creating the required set of global handler functions expected
-- by the Keybow firmware.
for keyno = 0, 11 do
_G[string.format("handle_key_%02d", keyno)] = function(pressed)
mb.route(keyno, pressed)
end
end

43
spec/keybowhandler.lua

@ -0,0 +1,43 @@
--[[
Copyright 2019 Harald Albrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
kbh = {} -- module
-- Convenience: returns the name of a Keybow key handler function.
function kbh.handler_name(keyno)
return string.format("handle_key_%02d", keyno)
end
-- Convenience: calls Keybow key handler by key number instead of name.
function kbh.handle_key(keyno, pressed)
_G[kbh.handler_name(keyno)](pressed)
end
-- Convenience: taps a Keybow key, triggering the corresponding key handler
-- twice.
function kbh.tap(keyno)
local h = _G[kbh.handler_name(keyno)]
h(true)
h(false)
end
return kbh -- module

69
spec/keybowhandler_spec.lua

@ -0,0 +1,69 @@
--[[
Copyright 2019 Harald Albrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
local kbh = require("spec/keybowhandler")
describe("Keybow keyhandler", function()
it("returns proper Keybow handler name", function()
assert.equals(kbh.handler_name(0), "handle_key_00")
end)
it("calls correct Keybow key handler", function()
stub(_G, "handle_key_00")
stub(_G, "handle_key_01")
kbh.handle_key(0, true)
assert.stub(handle_key_00).was.called(1)
assert.stub(handle_key_00).was.called_with(true)
assert.stub(handle_key_01).was_not.called()
handle_key_00:revert()
handle_key_01:revert()
end)
describe("wrapped Keybow key handler 00", function()
local old
local seq
before_each(function()
old = _G.handle_key_00
seq = {}
_G.handle_key_00 = function(pressed)
table.insert(seq, pressed)
end
end)
after_each(function()
_G.handle_key_00 = old
end)
it("taps Keybow key handlers", function()
kbh.tap(0)
assert.equals(#seq, 2)
assert.same(seq, {true, false})
end)
end)
end)

10
spec/multibow_spec.lua

@ -25,7 +25,7 @@ require "mocked-keybow"
describe("multibow", function()
-- ensure to get a fresh multibow module instance each time we run
-- an isolated test...
-- an isolated, nope, insulated test...
local mb
before_each(function()
@ -80,12 +80,14 @@ describe("multibow", function()
insl(function()
it("sets up multibow, activates lights", function()
local s = spy.on(_G, "setup")
_G.setup()
assert.spy(s).was.called(1)
local al = spy.on(mb, "activate_leds")
_G.setup()
assert.spy(s).was.called(1)
assert.spy(al).was.called(1)
s:revert()
al:revert()
end)
end)

90
spec/routehandlers_spec.lua

@ -21,6 +21,7 @@ SOFTWARE.
]]--
require "mocked-keybow"
local kbh = require("spec/keybowhandler")
describe("routehandlers", function()
@ -33,8 +34,15 @@ describe("routehandlers", function()
prim_key_release=function(key) end,
prim_otherkey_press=function(key) end,
prim_otherkey_release=function(key) end,
sec_key_press=function(key) end,
sec_key_release=function(key) end,
perm_key_press=function(key) end,
perm_key_release=function(key) end,
grab_key_press=function(key) end,
grab_key_release=function(key) end,
})
local primary_keymap = {
@ -42,11 +50,20 @@ describe("routehandlers", function()
[0]={press=spies.prim_key_press, release=spies.prim_key_release},
[1]={press=spies.prim_otherkey_press, release=spies.prim_otherkey_release},
}
local secondary_keymap = {
name="test-secondary",
secondary=true,
[0]={press=spies.sec_key_press, release=spies.sec_key_release},
}
local permanent_keymap = {
name="permanent",
permanent=true,
[0]={press=spies.perm_key_press, release=spies.perm_key_release}
}
local grab_keymap = {
name="grab",
[0]={press=spies.grab_key_press, release=spies.grab_key_release}
}
before_each(function()
require("keybow")
@ -58,21 +75,64 @@ describe("routehandlers", function()
end)
insl(function()
it("defines all Keybow key handlers for routing", function()
for keyno = 0, 11 do
assert.is_function(_G[string.format("handle_key_%02d", keyno)])
end
end)
it("calls routing handler with correct key number", function()
stub(mb, "route")
for keyno = 0, 11 do
mb.route:clear()
kbh.handle_key(keyno, true)
assert.stub(mb.route).was.called(1)
assert.stub(mb.route).was.called_with(keyno, true)
mb.route:clear()
kbh.handle_key(keyno, false)
assert.stub(mb.route).was.called(1)
assert.stub(mb.route).was.called_with(keyno, false)
end
mb.route:revert()
end)
end)
insl(function()
it("routes key press to primary keymap", function()
it("doesn't fail for unroutable keys", function()
kbh.handle_key(0, true)
kbh.handle_key(0, false)
end)
-- start with secondary keymap only :)
it("doesn't route a key press to a registered secondary keymap without activation", function()
assert.is_not_truthy(secondary_keymap.permanent)
assert.is_truthy(secondary_keymap.secondary)
mb.register_keymap(secondary_keymap)
assert.spy(spies.sec_key_press).was_not.called() -- just a safety guard
kbh.handle_key(0, true)
assert.spy(spies.sec_key_press).was_not.called()
end)
it("routes key press to activated secondary keymap", function()
mb.activate_keymap(secondary_keymap.name)
kbh.handle_key(0, true)
assert.spy(spies.sec_key_press).was.called(1)
assert.spy(spies.sec_key_press).was.called_with(0)
end)
-- throw in a primary keymap
it("routes key press to primary keymap, but not to secondary", function()
assert.is_not_truthy(primary_keymap.permanent or primary_keymap.secondary)
mb.register_keymap(primary_keymap)
mb.activate_keymap(primary_keymap.name)
assert.spy(spies.prim_key_press).was_not.called() -- just a safety guard
handle_key_00(true)
kbh.handle_key(0, true)
assert.spy(spies.prim_key_press).was.called(1)
assert.spy(spies.prim_key_press).was.called_with(0)
assert.spy(spies.prim_key_release).was_not.called()
@ -80,18 +140,19 @@ describe("routehandlers", function()
it("routes key release to primary keymap", function()
assert.spy(spies.prim_key_press).was_not.called() -- just a safety guard
handle_key_00(false)
kbh.handle_key(0, false)
assert.spy(spies.prim_key_press).was_not.called()
assert.spy(spies.prim_key_release).was.called(1)
assert.spy(spies.prim_key_release).was.called_with(0)
end)
-- adds a permanent keymap on top
it("routes with priority key press/release to permanent key", function()
assert.is_truthy(permanent_keymap.permanent)
assert.is_not_truthy(permanent_keymap.secondary)
mb.register_keymap(permanent_keymap)
handle_key_00(true)
kbh.handle_key(0, true)
assert.spy(spies.perm_key_press).was.called(1)
assert.spy(spies.perm_key_press).was.called_with(0)
assert.spy(spies.perm_key_release).was_not.called()
@ -101,12 +162,29 @@ describe("routehandlers", function()
it("correctly routes key press to un-overlaid primary key 2", function()
assert.spy(spies.prim_otherkey_press).was_not_called()
handle_key_01(true)
kbh.handle_key(1, true)
assert.spy(spies.prim_otherkey_press).was.called(1)
assert.spy(spies.prim_otherkey_press).was.called_with(1)
end)
end)
-- and finally adds a grab keymap, what a mess!
it("routes to grab keymap", function()
mb.register_keymap(grab_keymap)
mb.grab(grab_keymap.name)
assert.spy(spies.grab_key_press).was.called(0)
kbh.handle_key(0, true)
assert.spy(spies.grab_key_press).was.called(1)
assert.spy(spies.grab_key_press).was.called_with(0)
spies.grab_key_press:clear()
mb.ungrab()
kbh.handle_key(0, true)
assert.spy(spies.grab_key_press).was.called(0)
assert.spy(spies.perm_key_press).was.called(1)
assert.spy(spies.prim_key_press).was.called(0)
end)
end)
end)

120
spec/shift_spec.lua

@ -0,0 +1,120 @@
--[[
Copyright 2019 Harald Albrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
require "mocked-keybow"
require "snippets/multibow"
local kbh = require("spec/keybowhandler")
describe("SHIFT multibow keymap", function()
local mb = require("snippets/multibow")
insl(function()
it("installs the SHIFT keymap", function()
-- Sanity check that there are no registered keymaps yet.
assert.is.equal(#mb.registered_keymaps(), 0)
local shift = require("layouts/shift")
assert.is_not_nil(shift) -- we're going slightly over the top here...
assert.is_not_nil(shift.keymap)
-- SHIFT must register exactly two keymaps, a primary and a secondary one.
local kms = mb.registered_keymaps()
assert.is.equal(#kms, 2)
for idx, keymap in ipairs(kms) do
if keymap == "shift" then
assert.is_falsy(keymap.permanent)
assert.is_falsy(keymap.secondary)
elseif keymap == "shift-shifted" then
assert.is_falsy(keymap.permanent)
assert.is_true(keymap.secondary)
end
end
end)
end)
insl(function()
-- ensure to get a fresh SHIFT layout instance each time we run
-- an isolated, erm, insulated test.
local shift
before_each(function()
shift = require("layouts/shift")
end)
it("SHIFT grabs", function()
spy.on(mb, "grab")
spy.on(mb, "ungrab")
-- route in the SHIFT permanent keymap
kbh.handle_key(shift.KEY_SHIFT, true)
assert.spy(mb.grab).was.called(1)
assert.spy(mb.grab).was.called_with(shift.keymap_shifted.name)
-- route in the shifted(!) SHIFT keymap, so this checks
-- that we ungrab correctly
mb.grab:clear()
kbh.handle_key(shift.KEY_SHIFT, false)
assert.spy(mb.grab).was_not.called()
assert.spy(mb.ungrab).was.called(1)
mb.grab:revert()
mb.ungrab:revert()
end)
describe("while SHIFTed", function()
before_each(function()
kbh.handle_key(shift.KEY_SHIFT, true)
end)
after_each(function()
kbh.handle_key(shift.KEY_SHIFT, false)
end)
it("cycles primary keymaps", function()
stub(mb, "cycle_primary_keymaps")
kbh.tap(shift.KEY_LAYOUT)
assert.stub(mb.cycle_primary_keymaps).was.called(1)
mb.cycle_primary_keymaps:revert()
end)
it("changes brightness", function()
stub(mb, "set_brightness")
kbh.tap(shift.KEY_BRIGHTNESS)
kbh.tap(shift.KEY_BRIGHTNESS)
assert.stub(mb.set_brightness).was.called(2)
mb.set_brightness:revert()
end)
end)
end)
end)
Loading…
Cancel
Save