summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-05-15 16:22:23 +0100
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-05-15 16:22:23 +0100
commitc6a0bb10528a05db9153f6987f3d73f791e782bd (patch)
tree8b8f52eadf7df12f9856ba310e4d96d5114acc7e
parent0067c7400143bae967407c4ac4f5960da7561788 (diff)
downloadlace-c6a0bb10528a05db9153f6987f3d73f791e782bd.tar.gz
Add anyof/allof combinators and tests for the builtin.
-rw-r--r--lib/lace/builtin.lua39
-rw-r--r--test/test-lace.builtin.lua120
2 files changed, 156 insertions, 3 deletions
diff --git a/lib/lace/builtin.lua b/lib/lace/builtin.lua
index 5978bd0..71d5010 100644
--- a/lib/lace/builtin.lua
+++ b/lib/lace/builtin.lua
@@ -15,7 +15,8 @@ local function compiler()
return require "lace.compiler"
end
-local function run_conditions(exec_context, cond)
+local function run_conditions(exec_context, cond, anyof)
+ local anymet = false
for i = 1, #cond do
local name = cond[i]
local invert = false
@@ -32,10 +33,17 @@ local function run_conditions(exec_context, cond)
end
if not res then
-- condition failed
- return false
+ if not anyof then
+ return false
+ end
+ else
+ anymet = true
end
end
-- conditions passed
+ if anyof then
+ return anymet
+ end
return true
end
@@ -121,11 +129,36 @@ function builtin.default(compcontext, def, result, reason, unwanted)
}
end
+--[ Control types ]--------------------------------------------------
+
+local function _compile_any_all_of(compcontext, mtype, first, second, ...)
+ if type(first) ~= "string" then
+ return compiler().error("Expected at least two names, got none")
+ end
+ if type(second) ~= "string" then
+ return compiler().error("Expected at least two names, only got one")
+ end
+
+ return {
+ fn = run_conditions,
+ args = { { first, second, ...}, mtype == "anyof" }
+ }
+end
+
+local builtin_control_fn = {
+ anyof = _compile_any_all_of,
+ allof = _compile_any_all_of
+}
+
--[ Definitions ]----------------------------------------------------
local function _controlfn(ctx, name)
local ctt = ctx[".lace"].controltype or {}
- return ctt[name]
+ local cfn = ctt[name]
+ if cfn == nil then
+ cfn = builtin_control_fn[name]
+ end
+ return cfn
end
function builtin.define(compcontext, define, name, controltype, ...)
diff --git a/test/test-lace.builtin.lua b/test/test-lace.builtin.lua
index 8df9af8..4ee79c2 100644
--- a/test/test-lace.builtin.lua
+++ b/test/test-lace.builtin.lua
@@ -12,6 +12,7 @@
local luacov = require 'luacov'
local builtin = require 'lace.builtin'
+local engine = require 'lace.engine'
local testnames = {}
@@ -487,6 +488,125 @@ function suite.run_cond_include_present_passing()
assert(msg == "because", "Should propagate reason")
end
+function suite.compile_anyof_no_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "foo", "anyof")
+ assert(cmdtab == false, "Internal errors should return false")
+ assert(type(msg) == "table", "Internal errors should be tables")
+ assert(msg.msg:match(", got none"), "Error should mention that there were no args")
+end
+
+function suite.compile_allof_no_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "foo", "allof")
+ assert(cmdtab == false, "Internal errors should return false")
+ assert(type(msg) == "table", "Internal errors should be tables")
+ assert(msg.msg:match(", got none"), "Error should mention that there were no args")
+end
+
+function suite.compile_anyof_one_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "foo", "anyof", "foo")
+ assert(cmdtab == false, "Internal errors should return false")
+ assert(type(msg) == "table", "Internal errors should be tables")
+ assert(msg.msg:match(", only got one"), "Error should mention that there was only one arg")
+end
+
+function suite.compile_allof_one_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "foo", "allof", "foo")
+ assert(cmdtab == false, "Internal errors should return false")
+ assert(type(msg) == "table", "Internal errors should be tables")
+ assert(msg.msg:match(", only got one"), "Error should mention that there was only one arg")
+end
+
+
+function suite.compile_anyof_two_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "foo", "anyof", "foo", "bar")
+ assert(type(cmdtab) == "table", "Successful compilations should return tables")
+ assert(type(cmdtab.fn) == "function", "With functions")
+ assert(type(cmdtab.args) == "table", "And arguments")
+ assert(#cmdtab.args == 2, "There should be two args")
+ assert(type(cmdtab.args[1]) == "string", "The first should be a table")
+ assert(type(cmdtab.args[2]) == "table", "The second should be a bool")
+ local ctrltab = cmdtab.args[2]
+ assert(type(ctrltab) == "table", "Successfully compiled control functions should return tables")
+ assert(type(ctrltab.fn) == "function", "With functions")
+ assert(type(ctrltab.args) == "table", "And arguments")
+ assert(#ctrltab.args == 2, "There should be two args")
+ assert(type(ctrltab.args[1]) == "table", "The first should be a table")
+ assert(type(ctrltab.args[2]) == "boolean", "The second should be a bool")
+ assert(ctrltab.args[2] == true, "The anyof indicator should be true")
+end
+
+function suite.compile_allof_two_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "foo", "allof", "foo", "bar")
+ assert(type(cmdtab) == "table", "Successful compilations should return tables")
+ assert(type(cmdtab.fn) == "function", "With functions")
+ assert(type(cmdtab.args) == "table", "And arguments")
+ assert(#cmdtab.args == 2, "There should be two args")
+ assert(type(cmdtab.args[1]) == "string", "The first should be a table")
+ assert(type(cmdtab.args[2]) == "table", "The second should be a bool")
+ local ctrltab = cmdtab.args[2]
+ assert(type(ctrltab) == "table", "Successfully compiled control functions should return tables")
+ assert(type(ctrltab.fn) == "function", "With functions")
+ assert(type(ctrltab.args) == "table", "And arguments")
+ assert(#ctrltab.args == 2, "There should be two args")
+ assert(type(ctrltab.args[1]) == "table", "The first should be a table")
+ assert(type(ctrltab.args[2]) == "boolean", "The second should be a bool")
+ assert(ctrltab.args[2] == false, "The anyof indicator should be false")
+end
+
+function suite.run_anyof_two_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "jeff", "anyof", "foo", "bar")
+ assert(type(cmdtab) == "table", "Successful compilations should return tables")
+ local ectx = {
+ [".lace"] = {
+ defs = {
+ foo = {
+ fn = function() return true end,
+ args = {}
+ },
+ bar = {
+ fn = function() return false end,
+ args = {}
+ }
+ }
+ }
+ }
+ local ok, msg = cmdtab.fn(ectx, unpack(cmdtab.args))
+ assert(ok, "Running a define should work")
+ assert(ectx[".lace"].defs.foo.fn, "definition should have passed through")
+ assert(engine.test(ectx, "jeff"), "Any of true,false should be true")
+end
+
+function suite.run_anyof_two_args()
+ local compctx = {[".lace"] = {}}
+ local cmdtab, msg = builtin.commands.define(compctx, "define", "jeff", "allof", "foo", "bar")
+ assert(type(cmdtab) == "table", "Successful compilations should return tables")
+ local ectx = {
+ [".lace"] = {
+ defs = {
+ foo = {
+ fn = function() return true end,
+ args = {}
+ },
+ bar = {
+ fn = function() return false end,
+ args = {}
+ }
+ }
+ }
+ }
+ local ok, msg = cmdtab.fn(ectx, unpack(cmdtab.args))
+ assert(ok, "Running a define should work")
+ assert(ectx[".lace"].defs.foo.fn, "definition should have passed through")
+ assert(engine.test(ectx, "jeff") == false, "All of true,false should be false")
+end
+
local count_ok = 0
for _, testname in ipairs(testnames) do
-- print("Run: " .. testname)