1
0
Fork 0
mirror of https://github.com/zigzap/zap.git synced 2025-10-20 23:24:09 +00:00
zap/src/tests/test_http_params.zig
2025-03-21 19:30:18 +01:00

200 lines
6.9 KiB
Zig

const std = @import("std");
const zap = @import("zap");
fn makeRequest(a: std.mem.Allocator, url: []const u8) !void {
var http_client: std.http.Client = .{ .allocator = a };
defer http_client.deinit();
_ = try http_client.fetch(.{
.location = .{ .url = url },
});
zap.stop();
}
fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread {
return try std.Thread.spawn(.{}, makeRequest, .{ a, url });
}
test "http parameters" {
const allocator = std.testing.allocator;
const Handler = struct {
var alloc: std.mem.Allocator = undefined;
var ran: bool = false;
var param_count: isize = 0;
var strParams: ?zap.Request.HttpParamStrKVList = null;
var params: ?zap.Request.HttpParamKVList = null;
var paramOneStr: ?[]const u8 = null;
var paramOneSlice: ?[]const u8 = null;
var paramSlices: zap.Request.ParamSliceIterator = undefined;
pub fn on_request(r: zap.Request) !void {
ran = true;
r.parseQuery();
param_count = r.getParamCount();
// true -> make copies of temp strings
strParams = r.parametersToOwnedStrList(alloc) catch unreachable;
// true -> make copies of temp strings
params = r.parametersToOwnedList(alloc) catch unreachable;
paramOneStr = r.getParamStr(alloc, "one") catch unreachable;
// we need to dupe it here because the request object r will get
// invalidated at the end of the function but we need to check
// its correctness later in the test
paramOneSlice = if (r.getParamSlice("one")) |slice| alloc.dupe(u8, slice) catch unreachable else null;
paramSlices = r.getParamSlices();
}
};
Handler.alloc = allocator;
// setup listener
var listener = zap.HttpListener.init(
.{
.port = 3001,
.on_request = Handler.on_request,
.log = false,
.max_clients = 10,
.max_body_size = 1 * 1024,
},
);
zap.enableDebugLog();
try listener.listen();
const thread = try makeRequestThread(allocator, "http://127.0.0.1:3001/?one=1&two=2&string=hello+world&float=6.28&bool=true");
defer thread.join();
zap.start(.{
.threads = 1,
.workers = 1,
});
defer {
if (Handler.strParams) |*p| {
p.deinit();
}
if (Handler.params) |*p| {
p.deinit();
}
if (Handler.paramOneStr) |p| {
allocator.free(p);
}
if (Handler.paramOneSlice) |p| {
allocator.free(p);
}
}
try std.testing.expectEqual(true, Handler.ran);
try std.testing.expectEqual(5, Handler.param_count);
try std.testing.expect(Handler.paramOneStr != null);
try std.testing.expectEqualStrings("1", Handler.paramOneStr.?);
try std.testing.expect(Handler.paramOneSlice != null);
try std.testing.expectEqualStrings("1", Handler.paramOneSlice.?);
try std.testing.expect(Handler.strParams != null);
for (Handler.strParams.?.items, 0..) |kv, i| {
switch (i) {
0 => {
try std.testing.expectEqualStrings("one", kv.key);
try std.testing.expectEqualStrings("1", kv.value);
},
1 => {
try std.testing.expectEqualStrings("two", kv.key);
try std.testing.expectEqualStrings("2", kv.value);
},
2 => {
try std.testing.expectEqualStrings("string", kv.key);
try std.testing.expectEqualStrings("hello world", kv.value);
},
3 => {
try std.testing.expectEqualStrings("float", kv.key);
try std.testing.expectEqualStrings("6.28", kv.value);
},
4 => {
try std.testing.expectEqualStrings("bool", kv.key);
try std.testing.expectEqualStrings("true", kv.value);
},
else => return error.TooManyArgs,
}
}
var pindex: usize = 0;
while (Handler.paramSlices.next()) |param| {
switch (pindex) {
0 => {
try std.testing.expectEqualStrings("one", param.name);
try std.testing.expectEqualStrings("1", param.value);
},
1 => {
try std.testing.expectEqualStrings("two", param.name);
try std.testing.expectEqualStrings("2", param.value);
},
2 => {
try std.testing.expectEqualStrings("string", param.name);
try std.testing.expectEqualStrings("hello+world", param.value);
},
3 => {
try std.testing.expectEqualStrings("float", param.name);
try std.testing.expectEqualStrings("6.28", param.value);
},
4 => {
try std.testing.expectEqualStrings("bool", param.name);
try std.testing.expectEqualStrings("true", param.value);
},
else => return error.TooManyArgs,
}
pindex += 1;
}
for (Handler.params.?.items, 0..) |kv, i| {
switch (i) {
0 => {
try std.testing.expectEqualStrings("one", kv.key);
try std.testing.expect(kv.value != null);
switch (kv.value.?) {
.Int => |n| try std.testing.expectEqual(1, n),
else => return error.InvalidHttpParamType,
}
},
1 => {
try std.testing.expectEqualStrings("two", kv.key);
try std.testing.expect(kv.value != null);
switch (kv.value.?) {
.Int => |n| try std.testing.expectEqual(2, n),
else => return error.InvalidHttpParamType,
}
},
2 => {
try std.testing.expectEqualStrings("string", kv.key);
try std.testing.expect(kv.value != null);
switch (kv.value.?) {
.String => |s| try std.testing.expectEqualStrings("hello world", s),
else => return error.InvalidHttpParamType,
}
},
3 => {
try std.testing.expectEqualStrings("float", kv.key);
try std.testing.expect(kv.value != null);
switch (kv.value.?) {
.Float => |f| try std.testing.expectEqual(6.28, f),
else => return error.InvalidHttpParamType,
}
},
4 => {
try std.testing.expectEqualStrings("bool", kv.key);
try std.testing.expect(kv.value != null);
switch (kv.value.?) {
.Bool => |b| try std.testing.expectEqual(true, b),
else => return error.InvalidHttpParamType,
}
},
else => return error.TooManyArgs,
}
}
}