aboutsummaryrefslogtreecommitdiffstats
path: root/test/lua/busted/context.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/lua/busted/context.lua')
-rw-r--r--test/lua/busted/context.lua91
1 files changed, 91 insertions, 0 deletions
diff --git a/test/lua/busted/context.lua b/test/lua/busted/context.lua
new file mode 100644
index 000000000..4cf0f3b53
--- /dev/null
+++ b/test/lua/busted/context.lua
@@ -0,0 +1,91 @@
+local tablex = require 'pl.tablex'
+
+local function save()
+ local g = {}
+ for k,_ in next, _G, nil do
+ g[k] = rawget(_G, k)
+ end
+ return {
+ gmt = getmetatable(_G),
+ g = g,
+ loaded = tablex.copy(package.loaded)
+ }
+end
+
+local function restore(state)
+ setmetatable(_G, state.gmt)
+ for k,_ in next, _G, nil do
+ rawset(_G, k, state.g[k])
+ end
+ for k,_ in pairs(package.loaded) do
+ package.loaded[k] = state.loaded[k]
+ end
+end
+
+return function()
+ local context = {}
+
+ local data = {}
+ local parents = {}
+ local children = {}
+ local stack = {}
+
+ function context.ref()
+ local ref = {}
+ local ctx = data
+
+ function ref.get(key)
+ if not key then return ctx end
+ return ctx[key]
+ end
+
+ function ref.set(key, value)
+ ctx[key] = value
+ end
+
+ function ref.clear()
+ data = {}
+ parents = {}
+ children = {}
+ stack = {}
+ ctx = data
+ end
+
+ function ref.attach(child)
+ if not children[ctx] then children[ctx] = {} end
+ parents[child] = ctx
+ table.insert(children[ctx], child)
+ end
+
+ function ref.children(parent)
+ return children[parent] or {}
+ end
+
+ function ref.parent(child)
+ return parents[child]
+ end
+
+ function ref.push(current)
+ if not parents[current] then error('Detached child. Cannot push.') end
+ if ctx ~= current and current.descriptor == 'file' then
+ current.state = save()
+ end
+ table.insert(stack, ctx)
+ ctx = current
+ end
+
+ function ref.pop()
+ local current = ctx
+ ctx = table.remove(stack)
+ if ctx ~= current and current.state then
+ restore(current.state)
+ current.state = nil
+ end
+ if not ctx then error('Context stack empty. Cannot pop.') end
+ end
+
+ return ref
+ end
+
+ return context
+end