test(zap): only test if the output has generated instead of compare with local snapshot

- because will fail if zap changes the output even a little
This commit is contained in:
ernisto 2025-04-25 15:07:27 -03:00
parent 70f77385f3
commit eff55f9a6d
3 changed files with 2 additions and 452 deletions

View file

@ -8,5 +8,5 @@ local success, err = pcall(require, "bins/zap/init.luau")
assert(success, `failed to execute zap: {err}`)
assert(fs.readFile("tests/output/client.luau") == fs.readFile("tests/snapshots/client.luau"), `invalid output`)
assert(fs.readFile("tests/output/server.luau") == fs.readFile("tests/snapshots/server.luau"), `invalid output`)
assert(fs.isFile("tests/output/client.luau"), `invalid output`)
assert(fs.isFile("tests/output/server.luau"), `invalid output`)

View file

@ -1,216 +0,0 @@
--!native
--!optimize 2
--!nocheck
--!nolint
--#selene: allow(unused_variable, global_usage)
-- Client generated by Zap v0.6.20 (https://github.com/red-blox/zap)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local outgoing_buff: buffer
local outgoing_used: number
local outgoing_size: number
local outgoing_inst: { Instance }
local outgoing_apos: number
local outgoing_ids: { number }
local incoming_buff: buffer
local incoming_read: number
local incoming_inst: { Instance }
local incoming_ipos: number
local incoming_ids: { number }
-- thanks to https://dom.rojo.space/binary.html#cframe
local CFrameSpecialCases = {
CFrame.Angles(0, 0, 0),
CFrame.Angles(math.rad(90), 0, 0),
CFrame.Angles(0, math.rad(180), math.rad(180)),
CFrame.Angles(math.rad(-90), 0, 0),
CFrame.Angles(0, math.rad(180), math.rad(90)),
CFrame.Angles(0, math.rad(90), math.rad(90)),
CFrame.Angles(0, 0, math.rad(90)),
CFrame.Angles(0, math.rad(-90), math.rad(90)),
CFrame.Angles(math.rad(-90), math.rad(-90), 0),
CFrame.Angles(0, math.rad(-90), 0),
CFrame.Angles(math.rad(90), math.rad(-90), 0),
CFrame.Angles(0, math.rad(90), math.rad(180)),
CFrame.Angles(0, math.rad(-90), math.rad(180)),
CFrame.Angles(0, math.rad(180), math.rad(0)),
CFrame.Angles(math.rad(-90), math.rad(-180), math.rad(0)),
CFrame.Angles(0, math.rad(0), math.rad(180)),
CFrame.Angles(math.rad(90), math.rad(180), math.rad(0)),
CFrame.Angles(0, math.rad(0), math.rad(-90)),
CFrame.Angles(0, math.rad(-90), math.rad(-90)),
CFrame.Angles(0, math.rad(-180), math.rad(-90)),
CFrame.Angles(0, math.rad(90), math.rad(-90)),
CFrame.Angles(math.rad(90), math.rad(90), 0),
CFrame.Angles(0, math.rad(90), 0),
CFrame.Angles(math.rad(-90), math.rad(90), 0),
}
local function alloc(len: number)
if outgoing_used + len > outgoing_size then
while outgoing_used + len > outgoing_size do
outgoing_size = outgoing_size * 2
end
local new_buff = buffer.create(outgoing_size)
buffer.copy(new_buff, 0, outgoing_buff, 0, outgoing_used)
outgoing_buff = new_buff
end
outgoing_apos = outgoing_used
outgoing_used = outgoing_used + len
return outgoing_apos
end
local function read(len: number)
local pos = incoming_read
incoming_read = incoming_read + len
return pos
end
local function save()
return {
buff = outgoing_buff,
used = outgoing_used,
size = outgoing_size,
inst = outgoing_inst,
outgoing_ids = outgoing_ids,
incoming_ids = incoming_ids,
}
end
local function load(data: {
buff: buffer,
used: number,
size: number,
inst: { Instance },
outgoing_ids: { number },
incoming_ids: { number },
})
outgoing_buff = data.buff
outgoing_used = data.used
outgoing_size = data.size
outgoing_inst = data.inst
outgoing_ids = data.outgoing_ids
incoming_ids = data.incoming_ids
end
local function load_empty()
outgoing_buff = buffer.create(64)
outgoing_used = 0
outgoing_size = 64
outgoing_inst = {}
outgoing_ids = {}
incoming_ids = {}
end
load_empty()
local types = {}
local polling_queues_reliable = {}
local polling_queues_unreliable = {}
if not RunService:IsRunning() then
local noop = function() end
return table.freeze({
SendEvents = noop,
Test = table.freeze({
Call = noop,
}),
}) :: Events
end
if RunService:IsServer() then
error("Cannot use the client module on the server!")
end
local remotes = ReplicatedStorage:WaitForChild("ZAP")
local reliable = remotes:WaitForChild("ZAP_RELIABLE")
assert(reliable:IsA("RemoteEvent"), "Expected ZAP_RELIABLE to be a RemoteEvent")
local function SendEvents()
if outgoing_used ~= 0 then
local buff = buffer.create(outgoing_used)
buffer.copy(buff, 0, outgoing_buff, 0, outgoing_used)
reliable:FireServer(buff, outgoing_inst)
outgoing_buff = buffer.create(64)
outgoing_used = 0
outgoing_size = 64
table.clear(outgoing_inst)
end
end
RunService.Heartbeat:Connect(SendEvents)
local reliable_events = table.create(1)
local reliable_event_queue: { [number]: { any } } = table.create(1)
local function_call_id = 0
reliable_event_queue[0] = table.create(255)
reliable.OnClientEvent:Connect(function(buff, inst)
incoming_buff = buff
incoming_inst = inst
incoming_read = 0
incoming_ipos = 0
local len = buffer.len(buff)
while incoming_read < len do
local id = buffer.readu8(buff, read(1))
if id == 0 then
local call_id = buffer.readu8(incoming_buff, read(1))
local value
value = {}
local enum_value_1 = buffer.readu8(incoming_buff, read(1))
if enum_value_1 == 0 then
value = "Success"
elseif enum_value_1 == 1 then
value = "Fail"
else
error("Invalid enumerator")
end
local thread = reliable_event_queue[0][call_id]
-- When using actors it's possible for multiple Zap clients to exist, but only one called the Zap remote function.
if thread then
task.spawn(thread, value)
end
reliable_event_queue[0][call_id] = nil
else
error("Unknown event id")
end
end
end)
table.freeze(polling_queues_reliable)
table.freeze(polling_queues_unreliable)
local returns = {
SendEvents = SendEvents,
Test = {
Call = function(Foo: number, Bar: string): "Success" | "Fail"
alloc(1)
buffer.writeu8(outgoing_buff, outgoing_apos, 0)
function_call_id += 1
function_call_id %= 256
if reliable_event_queue[0][function_call_id] then
function_call_id -= 1
error("Zap has more than 256 calls awaiting a response, and therefore this packet has been dropped")
end
alloc(1)
buffer.writeu8(outgoing_buff, outgoing_apos, function_call_id)
alloc(1)
buffer.writeu8(outgoing_buff, outgoing_apos, Foo)
local len_1 = #Bar
alloc(2)
buffer.writeu16(outgoing_buff, outgoing_apos, len_1)
alloc(len_1)
buffer.writestring(outgoing_buff, outgoing_apos, Bar, len_1)
reliable_event_queue[0][function_call_id] = coroutine.running()
return coroutine.yield()
end,
},
}
type Events = typeof(returns)
return returns

View file

@ -1,234 +0,0 @@
--!native
--!optimize 2
--!nocheck
--!nolint
--#selene: allow(unused_variable, global_usage)
-- Server generated by Zap v0.6.20 (https://github.com/red-blox/zap)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local outgoing_buff: buffer
local outgoing_used: number
local outgoing_size: number
local outgoing_inst: { Instance }
local outgoing_apos: number
local outgoing_ids: { number }
local incoming_buff: buffer
local incoming_read: number
local incoming_inst: { Instance }
local incoming_ipos: number
local incoming_ids: { number }
-- thanks to https://dom.rojo.space/binary.html#cframe
local CFrameSpecialCases = {
CFrame.Angles(0, 0, 0),
CFrame.Angles(math.rad(90), 0, 0),
CFrame.Angles(0, math.rad(180), math.rad(180)),
CFrame.Angles(math.rad(-90), 0, 0),
CFrame.Angles(0, math.rad(180), math.rad(90)),
CFrame.Angles(0, math.rad(90), math.rad(90)),
CFrame.Angles(0, 0, math.rad(90)),
CFrame.Angles(0, math.rad(-90), math.rad(90)),
CFrame.Angles(math.rad(-90), math.rad(-90), 0),
CFrame.Angles(0, math.rad(-90), 0),
CFrame.Angles(math.rad(90), math.rad(-90), 0),
CFrame.Angles(0, math.rad(90), math.rad(180)),
CFrame.Angles(0, math.rad(-90), math.rad(180)),
CFrame.Angles(0, math.rad(180), math.rad(0)),
CFrame.Angles(math.rad(-90), math.rad(-180), math.rad(0)),
CFrame.Angles(0, math.rad(0), math.rad(180)),
CFrame.Angles(math.rad(90), math.rad(180), math.rad(0)),
CFrame.Angles(0, math.rad(0), math.rad(-90)),
CFrame.Angles(0, math.rad(-90), math.rad(-90)),
CFrame.Angles(0, math.rad(-180), math.rad(-90)),
CFrame.Angles(0, math.rad(90), math.rad(-90)),
CFrame.Angles(math.rad(90), math.rad(90), 0),
CFrame.Angles(0, math.rad(90), 0),
CFrame.Angles(math.rad(-90), math.rad(90), 0),
}
local function alloc(len: number)
if outgoing_used + len > outgoing_size then
while outgoing_used + len > outgoing_size do
outgoing_size = outgoing_size * 2
end
local new_buff = buffer.create(outgoing_size)
buffer.copy(new_buff, 0, outgoing_buff, 0, outgoing_used)
outgoing_buff = new_buff
end
outgoing_apos = outgoing_used
outgoing_used = outgoing_used + len
return outgoing_apos
end
local function read(len: number)
local pos = incoming_read
incoming_read = incoming_read + len
return pos
end
local function save()
return {
buff = outgoing_buff,
used = outgoing_used,
size = outgoing_size,
inst = outgoing_inst,
outgoing_ids = outgoing_ids,
incoming_ids = incoming_ids,
}
end
local function load(data: {
buff: buffer,
used: number,
size: number,
inst: { Instance },
outgoing_ids: { number },
incoming_ids: { number },
})
outgoing_buff = data.buff
outgoing_used = data.used
outgoing_size = data.size
outgoing_inst = data.inst
outgoing_ids = data.outgoing_ids
incoming_ids = data.incoming_ids
end
local function load_empty()
outgoing_buff = buffer.create(64)
outgoing_used = 0
outgoing_size = 64
outgoing_inst = {}
outgoing_ids = {}
incoming_ids = {}
end
load_empty()
local types = {}
local polling_queues_reliable = {}
local polling_queues_unreliable = {}
if not RunService:IsRunning() then
local noop = function() end
return table.freeze({
SendEvents = noop,
Test = table.freeze({
SetCallback = noop,
}),
}) :: Events
end
local Players = game:GetService("Players")
if RunService:IsClient() then
error("Cannot use the server module on the client!")
end
local remotes = ReplicatedStorage:FindFirstChild("ZAP")
if remotes == nil then
remotes = Instance.new("Folder")
remotes.Name = "ZAP"
remotes.Parent = ReplicatedStorage
end
local reliable = remotes:FindFirstChild("ZAP_RELIABLE")
if reliable == nil then
reliable = Instance.new("RemoteEvent")
reliable.Name = "ZAP_RELIABLE"
reliable.Parent = remotes
end
local player_map = {}
local function load_player(player: Player)
if player_map[player] then
load(player_map[player])
else
load_empty()
end
end
Players.PlayerRemoving:Connect(function(player)
player_map[player] = nil
end)
local function SendEvents()
for player, outgoing in player_map do
if outgoing.used > 0 then
local buff = buffer.create(outgoing.used)
buffer.copy(buff, 0, outgoing.buff, 0, outgoing.used)
reliable:FireClient(player, buff, outgoing.inst)
outgoing.buff = buffer.create(64)
outgoing.used = 0
outgoing.size = 64
table.clear(outgoing.inst)
end
end
end
RunService.Heartbeat:Connect(SendEvents)
local reliable_events = table.create(1)
reliable.OnServerEvent:Connect(function(player, buff, inst)
incoming_buff = buff
incoming_inst = inst
incoming_read = 0
incoming_ipos = 0
local len = buffer.len(buff)
while incoming_read < len do
local id = buffer.readu8(buff, read(1))
if id == 0 then
local call_id = buffer.readu8(buff, read(1))
local value, value2
value = buffer.readu8(incoming_buff, read(1))
local len_1 = buffer.readu16(incoming_buff, read(2))
value2 = buffer.readstring(incoming_buff, read(len_1), len_1)
if reliable_events[0] then
task.spawn(function(player_2, call_id_2, value_1, value_2)
local ret_1 = reliable_events[0](player_2, value_1, value_2)
load_player(player_2)
alloc(1)
buffer.writeu8(outgoing_buff, outgoing_apos, 0)
alloc(1)
buffer.writeu8(outgoing_buff, outgoing_apos, call_id_2)
if ret_1 == "Success" then
alloc(1)
buffer.writeu8(outgoing_buff, outgoing_apos, 0)
elseif ret_1 == "Fail" then
alloc(1)
buffer.writeu8(outgoing_buff, outgoing_apos, 1)
else
error("Invalid enumerator")
end
player_map[player_2] = save()
end, player, call_id, value, value2)
end
else
error("Unknown event id")
end
end
end)
table.freeze(polling_queues_reliable)
table.freeze(polling_queues_unreliable)
local returns = {
SendEvents = SendEvents,
Test = {
SetCallback = function(Callback: (Player: Player, Foo: number, Bar: string) -> "Success" | "Fail"): () -> ()
reliable_events[0] = Callback
return function()
reliable_events[0] = nil
end
end,
},
}
type Events = typeof(returns)
return returns