123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- local u = require 'luaunit'
- local mp = require "mp"
- local eq = u.assertEquals
- local fail = u.assertErrorMsgContains
- local function check_eq(t, t2)
- local bytes = mp.encode(t)
- local ok, r = pcall(mp.decode, bytes)
- if not ok then
- print(mp.tohex(bytes))
- error(r)
- end
- eq(mp.decode(bytes), t2 or t)
- end
- function _G.test_basic()
- local a = "\0\1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16"
- eq(mp.fromhex(mp.tohex(a)), a)
- eq({mp.decode "\1\2"}, {1,2})
- check_eq {
- foo = 1,
- bar = 2,
- array = {1,2,3,4}
- }
- check_eq {
- foo = 1,
- bar = 2,
- array = mp.array {1,2,3,4}
- }
- check_eq {
- foo = 1,
- bar = 2,
- array = mp.array {1,2,3,4}
- }
- check_eq {
- foo = 1,
- bar = 2,
- array = mp.map {1,2,3,4}
- }
- check_eq {
- f1 = 1,
- f2 = 2,
- fs1 = "foo",
- fs2 = "bar",
- fm = {
- ft1 = 1,
- ft2 = "foo",
- ft3 = {1,2,3},
- ft4 = { ft5 = { ft6 = { ft7 = { ft8 = { ft9 = mp.array { } } } } } }
- },
- fa_long = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17},
- fm_long = {
- f1 = 1, f2 = 2, f3 = 3, f4 = 4, f5 = 5, f6 = 6, f7 = 7, f8 = 8,
- f9 = 9, f10 = 10, f11 = 11, f12 = 12, f13 = 13, f14 = 14, f15 = 15, f16 = 16,
- f17 = 17, f18 = 18, f19 = 19, f20 = 20,
- }
- }
- end
- function _G.test_boolean()
- check_eq(true)
- check_eq(false)
- end
- function _G.test_number()
- check_eq(0)
- check_eq(127)
- check_eq(128)
- check_eq(0x100 + 100)
- check_eq(0x10000 + 100)
- check_eq(0x100000000 + 100)
- check_eq(-1)
- check_eq(-32)
- check_eq(-33)
- check_eq(-100)
- check_eq(-0x100 - 100)
- check_eq(-0x10000 - 100)
- check_eq(-0x100000000 - 100)
- check_eq("a")
- check_eq("aaa")
- check_eq(("a"):rep(31))
- check_eq(("a"):rep(32))
- check_eq(("a"):rep(0x100+100))
- check_eq(("a"):rep(0x10000+100))
- check_eq(1.123)
- check_eq(function() return "u",100 end, 100)
- check_eq(function() return "u",200 end, 200)
- check_eq(function() return "u",0x100 + 100 end, 0x100 + 100)
- check_eq(function() return "u",0x10000 + 100 end, 0x10000 + 100)
- check_eq(function() return "u",0x100000000 + 100 end, 0x100000000 + 100)
- check_eq(function() return "i",100 end, 100)
- check_eq(function() return "i",0x100 + 100 end, 0x100 + 100)
- check_eq(function() return "i",0x10000 + 100 end, 0x10000 + 100)
- check_eq(function() return "i",0x100000000 + 100 end, 0x100000000 + 100)
- check_eq(function() return "f",1.5 end, 1.5)
- check_eq(function() return "d",1.5 end, 1.5)
- check_eq(mp.meta("int", { value = 1 }), 1)
- check_eq(mp.meta("value", { value = 1 }), 1)
- end
- function _G.test_list()
- do
- local a = {}
- for i = 1, 1000 do
- a[#a+1] = i
- end
- check_eq(a)
- for i = 1, 65535 do
- a[#a+1] = i
- end
- check_eq(a)
- end
- do
- local a = {}
- for i = 1, 1000 do
- a["foo"..i] = i
- end
- check_eq(a)
- for i = 1, 65536 do
- a["foo"..(i+1000)] = i
- end
- check_eq(a)
- end
- end
- function _G.test_nil()
- check_eq(nil)
- eq(mp.decode(mp.encode(mp.null)), nil)
- eq(mp.decode(mp.newencoder()(mp.null)), nil)
- eq(tostring(mp.null), "null")
- end
- function _G.test_ext()
- local e = { type = 1, value = "foo" }
- local function check_ext(t, v)
- check_eq(function() return "e", t, v end, { type = t, value = v })
- end
- check_ext(1, "a")
- check_ext(1, ("a"):rep(2))
- check_ext(1, ("a"):rep(4))
- check_ext(1, ("a"):rep(8))
- check_ext(1, ("a"):rep(16))
- check_ext(1, ("a"):rep(50))
- check_ext(1, ("a"):rep(30000))
- check_ext(1, ("a"):rep(65537))
- check_ext(1, ("a"):rep(3))
- eq(mp.decode(mp.encode(function() return "e", 1, "foo" end),
- nil, nil, function(t, v)
- eq(t, 1)
- eq(v, "foo")
- return v
- end), "foo")
- eq(mp.decode(mp.encode(function() return "e", 1, "foo" end),
- nil, nil, function() end), e)
- check_eq(mp.meta("extension", e), e)
- --check_eq(mp.meta("t", mp.meta("ext", { value = e })), e)
- local e1 = mp.meta("extension", "foo")
- e1.type = 1
- check_eq(e1, e)
- local e2 = mp.meta("extension", setmetatable({type = 1, value = "foo"}, {}))
- check_eq(e2, e)
- end
- function _G.test_handler()
- check_eq(function() return "T" end, true)
- eq(mp.decode(mp.encode(function() return "F" end)), false)
- check_eq(function() return "s", "foo" end, "foo")
- check_eq(function() return "b", "foo" end, "foo")
- local co = coroutine.create(function()end)
- local c = 0
- local v = mp.newencoder(function(v, k, t)
- assert(k == nil)
- assert(t == nil)
- if v == co then
- c = c + 1
- return "int", 1
- end
- return "nil"
- end)(co, co, co)
- eq(c, 3); eq(v, "\1\1\1")
- c = 0; v = mp.newencoder(function(v, k, t)
- assert(k >= 1 and k <= 3)
- assert(type(t) == "table")
- if v == co then
- c = c + 1
- return "int", 1
- end
- return "nil"
- end)({co, co, co})
- eq(c, 3); eq(v, "\x93\1\1\1")
- c = 0; v = mp.newencoder(function(v, k, t)
- assert(k == "foo")
- assert(type(t) == "table")
- if v == co then
- c = c + 1
- return "int", 1
- end
- return "nil"
- end)({foo = co})
- eq(c, 1); eq(v, "\x81\xA3foo\1")
- c = 0; v = mp.newencoder(function(v, k, t)
- assert(k == nil)
- assert(type(t) == "table")
- if v == co then
- c = c + 1
- return "int", 1
- end
- return "nil"
- end)({[co] = "bar"})
- eq(c, 1); eq(v, "\x81\1\xA3bar")
- end
- function _G.test_error()
- fail("number expected, got nil",
- function() mp.encode(function() return "u", nil end) end)
- fail("integer expected, got number",
- function() mp.encode(function() return "u", 1.2 end) end)
- fail("attempt to index a msgpack.null value",
- function() return mp.null.abc end)
- fail("attempt to index a msgpack.null value",
- function() mp.null.abc = 10 end)
- local a = {} a[1] = a
- fail("array level too deep", function() mp.encode(a) end)
- a = {} a.foo = a
- fail("map level too deep", function() mp.encode(a) end)
- fail("invalid key in map", function()
- mp.encode { [function() end] = 1 }
- end)
- fail("integer expected for extension type, got boolean", function()
- mp.encode(function() return "e", true end)
- end)
- fail("invalid extension type: 10000", function()
- mp.encode(function() return "e", 10000 end)
- end)
- fail("string expected for extension value, got boolean", function()
- mp.encode(function() return "e", 1, true end)
- end)
- fail("'pack' field expected in handler object", function()
- mp.encode(mp.meta("handler", {}))
- end)
- fail("'value' field expected in wrapper object", function()
- mp.encode(mp.meta("int", {}))
- end)
- fail("invalid type 'thread'", function()
- mp.encode(coroutine.create(function() end))
- end)
- fail("invalid string at offset 2: 1 bytes expected, got 0 bytes",
- function() mp.decode("\161") end)
- fail("invalid string at offset 2: 1 bytes expected, got 0 bytes",
- function() mp.decode("\161") end)
- fail("unexpected end of message at offset 2: map key expected",
- function() mp.decode("\129") end)
- fail("unexpected end of message at offset 3: map value expected",
- function() mp.decode("\129\1") end)
- fail("unexpected end of message at offset 2: array element expected",
- function() mp.decode("\145") end)
- fail("invalid char '193' at offset 2",
- function() mp.decode("\193") end)
- end
- if _VERSION == "Lua 5.1" and not _G.jit then
- u.LuaUnit.run()
- else
- os.exit(u.LuaUnit.run(), true)
- end
- -- unixcc: run='rm -f *.gcda; time lua test.lua; gcov mp.c'
- -- win32cc: run='del /s/q *.gcda & lua test.lua & gcov mp.c'
|