Refactor to be testable - AdamWagner/stackline GitHub Wiki
Isolate test environment
https://github.com/hoelzro/lua-procure
procure.isolated(name)
This function behaves exactly like procure(), except the module specified by
name is loaded in an isolated environment (it cannot make changes to the global
environment). This is to allow users who want to keep a clean global environment
to use modules that "misbehave" in this regard.
It's not entirely impossible for isolated modules to alter the global
environment; while naïve global assignment (assigning to a variable not declared
with local) and assigning to _G will be intercepted, assigning to keys in the
value returned by getfenv(0) (for example) will not. I feel this is a proper
balance between cleanliness and flexibility.
Libs enabling best-practices for testable code
Inversion of control https://github.com/basiliscos/lua-gear
Dependency injection https://fperrad.frama.io/lua-Coat/inject/
Lua design patterns
General overview of standard design patterns https://www.youtube.com/watch?v=_BpmfnqjgzQ&list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc&index=2
https://github.com/floydawong/lua-patterns https://github.com/woshihuo12/LuaDesignPattern http://lua-users.org/wiki/LuaTypeChecking
Reactive libs
lua-reactor
React-style ui component system for Lua
2017
The lifecycle module: https://github.com/talldan/lua-reactor/blob/master/src/reactor/reconcile.lua
luact
Build reactive user interfaces on Lua
2020
https://github.com/LXSMNSYC/luact
coutil
Syncronization of coroutines using events and promises.
https://github.com/renatomaia/coutil
Event libs
https://github.com/ejmr/Luvent
React when table values changes
Did not work https://github.com/ZichaoNickFox/ReactiveTable (2016) https://github.com/Phrogz/notifitable (2014)
Not tested https://github.com/pfzq303/dataBind-lua https://github.com/Anti-Magic/rdatabinding (looks good!)
Worked! https://github.com/ayongm2/TableMonitor (2017) https://github.com/mainlei/bindingtable/blob/master/bindingtable.lua (2020) ✅
However, this is also pretty simple to build from scratch:
local function listener(k,v)
print( "new entry added: \n\tKey = " .. k .. "\n\tValue = " .. v)
end
local protectedTable = {}
local metaTable = {
__index = function (t,k)
return protectedTable[k]
end,
__newindex = function (t,k,v)
protectedTable[k] = v -- update original table
listener(k,v)
end,
__ipairs = function(table)
return ipairs(protectedTable)
end,
__pairs = function(table)
return pairs(protectedTable)
end
}
local t = setmetatable({},metaTable)
-- test
t.text = "Hello!"
print(t.text)
State machines
https://github.com/emiruz/decide https://github.com/kyleconroy/lua-state-machine
local machine = require('statemachine')
local fsm = machine.create({
initial = 'green',
events = {
{ name = 'warn', from = 'green', to = 'yellow' },
{ name = 'panic', from = 'yellow', to = 'red' },
{ name = 'calm', from = 'red', to = 'yellow' },
{ name = 'clear', from = 'yellow', to = 'green' }
}})