summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2012-07-21 17:53:28 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2012-07-21 17:53:28 +0100
commitf3ba95101aabd9c308ef746db32c6eb7536a5a7f (patch)
treea0b325ccfadc80c827dee4fa79360cd45dc44980
parent47ef63d725d7daa2562703e0179ebe4b15a705bc (diff)
downloadsupple-f3ba95101aabd9c308ef746db32c6eb7536a5a7f.tar.gz
SUPPLE.REQUEST: Support requests, responses and deserialising, and test it all
-rw-r--r--Makefile2
-rw-r--r--lib/supple/request.lua82
-rw-r--r--test/test-supple.request.lua66
3 files changed, 149 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index a90727b..60a1d7e 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ test: build
$(LUA) test/test-$${MOD}.lua; \
test "x$$?" = "x0" || ERR=1; \
done; \
- $(LUA) extras/luacov/src/bin/luacov -X luacov. -X test. $(LMODULES); \
+ $(LUA) extras/luacov/src/bin/luacov -X luacov. -X test. $(TEST_MODULES); \
exit $$ERR
.PHONY: interactive
diff --git a/lib/supple/request.lua b/lib/supple/request.lua
index 7f01e99..ab8388a 100644
--- a/lib/supple/request.lua
+++ b/lib/supple/request.lua
@@ -10,7 +10,14 @@
-- For licence terms, see COPYING
--
+local capi = require 'supple.capi'
+local objects = require 'supple.objects'
+
local tconcat = table.concat
+local ipairs = ipairs
+local select = select
+local loadstring = loadstring
+local setfenv = setfenv
local function serialise_error(errstr, traceback)
return tconcat {
@@ -20,13 +27,88 @@ local function serialise_error(errstr, traceback)
}
end
+local function _serialise_object(obj, ret)
+ ret[#ret+1] = "{"
+ local comma = ""
+ if obj.type then
+ ret[#ret+1] = ("type=%q"):format(obj.type)
+ comma = ","
+ end
+ ret[#ret+1] = ("%stag=%q"):format(comma, obj.tag)
+ if obj.methods then
+ ret[#ret+1] = ",methods={"
+ comma = ""
+ for _, meth in ipairs(obj.methods) do
+ ret[#ret+1] = ("%s%q"):format(comma, meth)
+ comma = ","
+ end
+ ret[#ret+1] = "}"
+ end
+ ret[#ret+1] = "}"
+end
+
local function serialise_request(obj, method, ...)
+ assert(capi.rawtype(obj) == "string")
+ assert(capi.rawtype(method) == "string")
+ local args = { n = select("#", ...), ... }
+ local ret = {
+ ("object=%q,"):format(obj),
+ ("method=%q,"):format(method),
+ ("args={n=%d"):format(args.n)
+ }
+
+ for i = 1, args.n do
+ local v = objects.give(args[i])
+ if capi.rawtype(v) == "string" then
+ ret[#ret+1] = (",%q"):format(v)
+ elseif capi.rawtype(v) == "table" then
+ ret[#ret+1] = ","
+ _serialise_object(v, ret)
+ else
+ ret[#ret+1] = "," .. tostring(v)
+ end
+ end
+
+ ret[#ret+1] = "}"
+ return tconcat(ret)
end
local function serialise_response(...)
+ local args = { n = select("#", ...), ... }
+ local ret = {
+ "error=false,",
+ ("results={n=%d"):format(args.n)
+ }
+
+ for i = 1, args.n do
+ local v = objects.give(args[i])
+ if capi.rawtype(v) == "string" then
+ ret[#ret+1] = (",%q"):format(v)
+ elseif capi.rawtype(v) == "table" then
+ ret[#ret+1] = ","
+ _serialise_object(v, ret)
+ else
+ ret[#ret+1] = "," .. tostring(v)
+ end
+ end
+
+ ret[#ret+1] = "}"
+ return tconcat(ret)
end
local function deserialise_entity(entity)
+ local str = ("return {%s}"):format(entity)
+ local fn = assert(loadstring(str))
+ setfenv(fn, {})
+ local res = fn()
+ local walk = res.args or res.results
+ if walk then
+ assert(walk.n, "Elements missing 'n'")
+ for i = 1, walk.n do
+ walk[i] = objects.receive(walk[i])
+ end
+ end
+ return res
end
return {
diff --git a/test/test-supple.request.lua b/test/test-supple.request.lua
index 5413cd8..6ed5f5b 100644
--- a/test/test-supple.request.lua
+++ b/test/test-supple.request.lua
@@ -12,6 +12,7 @@
local luacov = require 'luacov'
local request = require 'supple.request'
+local objects = require 'supple.objects'
local testnames = {}
@@ -34,7 +35,72 @@ function suite.serialise_error()
local err = request.error("m","tb")
assert(err == [[error=true,message="m",traceback="tb"]],
"Error did not serialise properly")
+end
+
+function suite.serialise_request_simple()
+ local req = request.request("TAG", "METH", "arg1", true)
+ local tab = assert(loadstring("return {" .. req .. "}"))()
+ assert(tab.object == "TAG", "object tag not passed")
+ assert(tab.method == "METH", "method name not passed")
+ assert(tab.args.n == 2, "argument count not passed")
+ assert(tab.args[1] == "arg1", "arg1 not passed")
+ assert(tab.args[2] == true, "arg2 not passed")
+end
+
+function suite.serialise_request_simple_table()
+ local argtab = {}
+ local req = request.request("TAG", "METH", argtab)
+ local tab = assert(loadstring("return {" .. req .. "}"))()
+ assert(tab.object == "TAG", "object tag not passed")
+ assert(tab.method == "METH", "method name not passed")
+ assert(tab.args.n == 1, "argument count not passed")
+ -- Best check that the received arg unwraps nicely
+ assert(objects.receive(tab.args[1]) == argtab, "arg did not unwrap")
+end
+
+function suite.serialise_request_table_with_index()
+ local argtab = setmetatable({}, { __index = {} })
+ local req = request.request("TAG", "METH", argtab)
+ local tab = assert(loadstring("return {" .. req .. "}"))()
+ assert(tab.object == "TAG", "object tag not passed")
+ assert(tab.method == "METH", "method name not passed")
+ assert(tab.args.n == 1, "argument count not passed")
+ assert(tab.args[1].methods[1] == "__index", "metamethod didn't pass")
+ -- Best check that the received arg unwraps nicely
+ assert(objects.receive(tab.args[1]) == argtab, "arg did not unwrap")
+end
+
+function suite.serialise_response_simple()
+ local req = request.response("foo",12)
+ local tab = assert(loadstring("return {" .. req .. "}"))()
+ assert(tab.error == false, "error wasn't false")
+ assert(type(tab.results) == "table", "results were missing")
+ assert(tab.results.n == 2, "Result count not passed")
+ assert(tab.results[1] == "foo", "result 1 not passed")
+ assert(tab.results[2] == 12, "result 2 not passed")
+end
+
+function suite.serialise_response_table()
+ local argtab = {}
+ local req = request.response(argtab)
+ local tab = assert(loadstring("return {" .. req .. "}"))()
+ assert(tab.error == false, "error wasn't false")
+ assert(type(tab.results) == "table", "results were missing")
+ assert(tab.results.n == 1, "Result count not passed")
+ assert(type(tab.results[1]) == "table", "result 1 not passed")
+ assert(objects.receive(tab.results[1]) == argtab,
+ "arg did not unwrap")
+end
+function suite.deserialise()
+ local argtab = {}
+ local req = request.response(argtab)
+ local tab = request.deserialise(req)
+ assert(tab.error == false, "error wasn't false")
+ assert(type(tab.results) == "table", "results were missing")
+ assert(tab.results.n == 1, "Result count not passed")
+ assert(type(tab.results[1]) == "table", "result 1 not passed")
+ assert(tab.results[1] == argtab, "arg did not unwrap")
end
local count_ok = 0