Rudimentary test cases for ParseBody
This commit is contained in:
parent
8aa4f900f6
commit
b99a0095d4
1 changed files with 46 additions and 6 deletions
|
@ -591,12 +591,13 @@ const BaseContentType = enum {
|
||||||
other,
|
other,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn parseBodyFromRequest(comptime T: type, content_type: BaseContentType, reader: anytype, alloc: std.mem.Allocator) !T {
|
fn parseBodyFromRequest(comptime T: type, content_type: ?[]const u8, reader: anytype, alloc: std.mem.Allocator) !T {
|
||||||
//@compileLog(T);
|
// Use json by default for now for testing purposes
|
||||||
|
const parser_type = matchContentType(content_type) orelse .json;
|
||||||
const buf = try reader.readAllAlloc(alloc, 1 << 16);
|
const buf = try reader.readAllAlloc(alloc, 1 << 16);
|
||||||
defer alloc.free(buf);
|
defer alloc.free(buf);
|
||||||
|
|
||||||
switch (content_type) {
|
switch (parser_type) {
|
||||||
.octet_stream, .json => {
|
.octet_stream, .json => {
|
||||||
const body = try json_utils.parse(T, buf, alloc);
|
const body = try json_utils.parse(T, buf, alloc);
|
||||||
defer json_utils.parseFree(body, alloc);
|
defer json_utils.parseFree(body, alloc);
|
||||||
|
@ -640,10 +641,8 @@ pub fn ParseBody(comptime Body: type) type {
|
||||||
return next.handle(req, res, new_ctx, {});
|
return next.handle(req, res, new_ctx, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const base_content_type = matchContentType(content_type);
|
|
||||||
|
|
||||||
var stream = req.body orelse return error.NoBody;
|
var stream = req.body orelse return error.NoBody;
|
||||||
const body = try parseBodyFromRequest(Body, base_content_type orelse .json, stream.reader(), ctx.allocator);
|
const body = try parseBodyFromRequest(Body, content_type, stream.reader(), ctx.allocator);
|
||||||
defer util.deepFree(ctx.allocator, body);
|
defer util.deepFree(ctx.allocator, body);
|
||||||
|
|
||||||
return next.handle(
|
return next.handle(
|
||||||
|
@ -659,6 +658,47 @@ pub fn parseBody(comptime Body: type) ParseBody(Body) {
|
||||||
return .{};
|
return .{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "parseBodyFromRequest" {
|
||||||
|
const testCase = struct {
|
||||||
|
fn case(content_type: []const u8, body: []const u8, expected: anytype) !void {
|
||||||
|
var stream = std.io.StreamSource{ .const_buffer = std.io.fixedBufferStream(body) };
|
||||||
|
const result = try parseBodyFromRequest(@TypeOf(expected), content_type, stream.reader(), std.testing.allocator);
|
||||||
|
defer util.deepFree(std.testing.allocator, result);
|
||||||
|
|
||||||
|
try util.testing.expectDeepEqual(expected, result);
|
||||||
|
}
|
||||||
|
}.case;
|
||||||
|
|
||||||
|
const Struct = struct {
|
||||||
|
id: usize,
|
||||||
|
};
|
||||||
|
try testCase("application/json", "{\"id\": 3}", Struct{ .id = 3 });
|
||||||
|
try testCase("application/x-www-form-urlencoded", "id=3", Struct{ .id = 3 });
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parseBody" {
|
||||||
|
const Struct = struct {
|
||||||
|
foo: []const u8,
|
||||||
|
};
|
||||||
|
const body =
|
||||||
|
\\{"foo": "bar"}
|
||||||
|
;
|
||||||
|
var stream = std.io.StreamSource{ .const_buffer = std.io.fixedBufferStream(body) };
|
||||||
|
var headers = http.Fields.init(std.testing.allocator);
|
||||||
|
defer headers.deinit();
|
||||||
|
|
||||||
|
try parseBody(Struct).handle(
|
||||||
|
.{ .body = @as(?std.io.StreamSource, stream), .headers = headers },
|
||||||
|
.{},
|
||||||
|
.{ .allocator = std.testing.allocator },
|
||||||
|
struct {
|
||||||
|
fn handle(_: anytype, _: anytype, _: anytype, ctx: anytype, _: void) !void {
|
||||||
|
try util.testing.expectDeepEqual(Struct{ .foo = "bar" }, ctx.body);
|
||||||
|
}
|
||||||
|
}{},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses query parameters as defined in query.zig
|
/// Parses query parameters as defined in query.zig
|
||||||
pub fn ParseQueryParams(comptime QueryParams: type) type {
|
pub fn ParseQueryParams(comptime QueryParams: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
|
|
Loading…
Reference in a new issue