Created
November 2, 2022 02:40
-
-
Save azdle/7e8362250b1d97a18877e009f22a8d15 to your computer and use it in GitHub Desktop.
Testing Packing and Unpacking in Lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | |
-- Note: run with `busted packunpackit.lua` | |
-- | |
local havecosock, cosock = pcall(require, "cosock") | |
local socket = require "socket" | |
local pack = table and table.pack or pack | |
local unpack = table and table.unpack or unpack | |
local function mvpack(...) | |
return {...} | |
end | |
local function manpack(...) | |
local args = {...} | |
local t = {} | |
for i = 1,10 do | |
t[i] = args[i] | |
end | |
return t | |
end | |
local function unpacker(t) | |
return unpack(t) | |
end | |
local function passthrough(f, ...) | |
local ret = {f(...)} | |
return unpack(ret) | |
end | |
function reter(foo, err) | |
if err then | |
return nil,2,3,4,5 | |
else | |
return true | |
end | |
end | |
function unit(...) | |
return ... | |
end | |
local transform = { | |
output = function(a, b, c, d, e) | |
return nil, b, c, d, e | |
end | |
} | |
local function wrappedtransform(...) | |
local input = {...} | |
local ret = {unit(unpack(input))} | |
return unpack(ret) | |
end | |
test("packing", function() | |
local t = table.pack(1,2,3,4,5) | |
assert.same(#t, 5) | |
assert.same(#table.pack(reter(nil, true)), 5) | |
assert.same(#{reter(nil, true)}, 5) | |
end) | |
test("unpacking nonnil", function() | |
local t = {1,2,3,4,5} | |
local t2 = {unpacker(t)} | |
assert.same(t, t2) | |
end) | |
test("unpacking nilprefix", function() | |
local t = {nil,2,3,4,5} | |
local t2 = {passthrough(unpacker, t)} | |
assert.same(t, t2) | |
end) | |
test("unpacking midnil", function() | |
local t = {1,2,nil,4,5} | |
local t2 = {passthrough(unpacker, t)} | |
assert.same(t, t2) | |
end) | |
test("mvunpacking nonnil", function() | |
local t = mvpack(1,2,3,4,5) | |
local t2 = {passthrough(unpacker, t)} | |
assert.same(t, t2) | |
end) | |
test("mvunpacking nilprefix", function() | |
local t = mvpack(nil,2,3,4,5) | |
local t2 = {passthrough(unpacker, t)} | |
assert.same(t, t2) | |
end) | |
test("mvunpacking midnil", function() | |
local t = mvpack(1,2,nil,4,5) | |
local t2 = {passthrough(unpacker, t)} | |
assert.same(t, t2) | |
end) | |
test("fn unpacking", function() | |
local t = mvpack(nil,2,3,4,5) | |
local t2 = {passthrough(reter, nil, true)} | |
assert.same(t, t2) | |
end) | |
test("manpacked unpacking", function() | |
local t = manpack(nil,2,3,4,5) | |
local t2 = {passthrough(reter, nil, true)} | |
assert.same(t, t2) | |
end) | |
test("output unpacking", function() | |
local a, b, c, d, e = transform.output(1,2,3,4,5) | |
assert.same({a,b,c,d,e}, {nil, 2,3,4,5}) | |
end) | |
test("wrapped transform unpacking", function() | |
local a, b, c, d, e = wrappedtransform(1,2,3,4,5) | |
assert.same({a,b,c,d,e}, {1, 2,3,4,5}) | |
local a, b, c, d, e = wrappedtransform(nil,2,3,4,5) | |
assert.same({a,b,c,d,e}, {nil,2,3,4,5}) | |
end) | |
--[[ | |
test("raw pack", function() | |
local t = {} | |
t[1] = nil | |
t[2] = "foo" | |
assert.same({nil, "foo"}, {unpack(t)}) | |
end) | |
]] | |
test("unmessed", function() | |
local t = {nil, true, true} | |
assert.same({nil, true, true}, {unpack(t)}) | |
end) | |
test("just looking", function() | |
local t = {nil, true, true} | |
local status = t[1] | |
local err = t[2] | |
local ret2 = {transform.output(unpack(t))} | |
local status2, err2 = unit(unpack(ret2)) | |
assert(status == nil) | |
assert(err == true) | |
if err then | |
assert.same({nil, true, true}, {unpack(t)}) | |
else | |
error("wrong way") | |
end | |
end) | |
--[[ | |
test("manual messing", function() | |
local t = {nil, true} | |
t[3] = true | |
assert.same({nil, true, true}, {unpack(t)}) | |
end) | |
]]-- | |
test("manual re-messing", function() | |
local t = {nil, true, true} | |
t[3] = true | |
assert.same({nil, true, true}, {unpack(t)}) | |
end) | |
--[[ | |
test("packed manual messing", function() | |
local t = table.pack(nil, true) | |
t[3] = true | |
assert.same({nil, true, true}, {unpack(t)}) | |
end) | |
]] | |
test("packed manual re-messing", function() | |
local t = table.pack(nil, true, true) | |
t[3] = true | |
assert.same({nil, true, true}, {unpack(t)}) | |
end) | |
if havecosock then | |
test("cosock", function() | |
cosock.reset() | |
cosock.spawn(function() | |
local ret = {cosock.socket.select(nil, nil, 0)} -- force a yield | |
assert.same({nil, nil, "timeout"}, ret) | |
assert(#{nil, nil, "timeout"}, #ret) | |
assert.same({nil, nil, "timeout"}, {unpack(ret)}) | |
assert(#{nil, nil, "timeout"} == #{unpack(ret)}) | |
end) | |
cosock.run() | |
end) | |
end | |
test("luasocket", function() | |
local ret = {socket.select(nil, nil, 0)} | |
assert.same({{}, {}, "timeout"}, ret) | |
assert(#{{}, {}, "timeout"}, #ret) | |
assert.same({{}, {}, "timeout"}, {unpack(ret)}) | |
assert(#{{}, {}, "timeout"} == #{unpack(ret)}) | |
end) | |
test("actual socket", function() | |
function thing() | |
local sock = socket.udp() | |
assert(sock:setsockname("localhost", 0)) | |
assert(sock:settimeout(0)) | |
local ret = {sock["receivefrom"](sock, unpack({}))} | |
local status = ret[1] | |
local err = ret[2] | |
if not status and err then | |
assert(2 == #ret) | |
assert.same({nil, "timeout"}, ret) | |
assert(2 == #{unpack(ret)}) | |
assert.same({nil, "timeout"}, {unpack(ret)}) | |
return unpack(ret) | |
end | |
end | |
local status, err = thing() | |
assert(status == nil) | |
assert(err == "timeout") | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment