Something went wrong. Try again.
websocket
Something went wrong. Try again.
3.7 kB · 124 lines
Zig
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125const std = @import("std");const t = @import("t.zig");const ws = @import("websocket.zig");
pub fn init() Testing { return Testing.init();}
pub const Testing = struct { closed: bool, conn: ws.Conn, pair: t.SocketPair, reader: ws.proto.Reader, arena: *std.heap.ArenaAllocator,
received: std.ArrayList(ws.Message), received_index: usize,
const Opts = struct { port: ?u16 = null, }; fn init(opts: Opts) Testing { const arena = t.allocator.create(std.heap.ArenaAllocator) catch unreachable; errdefer t.allocator.destroy(arena);
arena.* = std.heap.ArenaAllocator.init(t.allocator); errdefer arena.deinit();
const port = opts.port orelse 0; const pair = t.SocketPair.init(.{ .port = port }); const timeout = std.mem.toBytes(std.posix.timeval{ .sec = 0, .usec = 50_000, }); std.posix.setsockopt(pair.client.socket.handle, std.posix.SOL.SOCKET, std.posix.SO.RCVTIMEO, &timeout) catch unreachable;
const aa = arena.allocator(); const buffer_provider = aa.create(ws.buffer.Provider) catch unreachable; buffer_provider.* = ws.buffer.Provider.init(aa, .{ .size = 0, .count = 0, .max = 20_971_520, }) catch unreachable;
const reader_buf = aa.alloc(u8, 1024) catch unreachable; const reader = ws.proto.Reader.init(reader_buf, buffer_provider, null);
return .{ .closed = false, .pair = pair, .arena = arena, .conn = .{ ._closed = false, .started = 0, .stream = pair.server, .address = std.Io.net.IpAddress.parse("127.0.0.1", port) catch unreachable, }, .reader = reader, .received = .empty, .received_index = 0, }; }
pub fn deinit(self: *Testing) void { self.pair.deinit(); self.arena.deinit(); t.allocator.destroy(self.arena); }
pub fn expectMessage(self: *Testing, op: ws.Message.Type, data: []const u8) !void { try self.ensureMessage();
const message = self.received.items[self.received_index]; self.received_index += 1;
try t.expectEqual(op, message.type); if (op == .text) { try t.expectString(data, message.data); } else { try t.expectSlice(u8, data, message.data); } }
pub fn expectClose(self: *Testing) !void { if (self.closed) { return; }
self.fill() catch if (self.closed) { return; };
return error.NotClosed; }
// we have a 50ms timeout on this socket. It's all localhost. We expect // to be able to read messages in that time. pub fn ensureMessage(self: *Testing) !void { if (self.received_index < self.received.items.len) { return; } return self.fill(); }
fn fill(self: *Testing) !void { var client_reader = self.pair.clientReader(); self.reader.fill(&client_reader) catch |err| switch (err) { error.WouldBlock => return error.NoMoreData, else => { self.closed = true; return err; }, };
while (true) { const more, const message = (try self.reader.read()) orelse return error.NoMoreData; const aa = self.arena.allocator(); self.received.append(aa, message) catch unreachable; if (more == false) { return; } } }};