diff --git a/src/http/middleware.zig b/src/http/middleware.zig index ca805fd..541ca97 100644 --- a/src/http/middleware.zig +++ b/src/http/middleware.zig @@ -163,27 +163,12 @@ test "InjectContextValue" { .handle(.{}, .{}, .{ .efgh = @as(usize, 10) }, ExpectContext(.{ .abcd = 5, .efgh = 10 }){}); } -fn expectDeepEquals(expected: anytype, actual: anytype) !void { - const E = @TypeOf(expected); - const A = @TypeOf(actual); - if (E == void) return std.testing.expect(A == void); - try std.testing.expect(std.meta.fields(E).len == std.meta.fields(A).len); - inline for (std.meta.fields(E)) |f| { - const e = @field(expected, f.name); - const a = @field(actual, f.name); - if (comptime std.meta.trait.isZigString(f.field_type)) { - try std.testing.expectEqualStrings(a, e); - } else { - try std.testing.expectEqual(a, e); - } - } -} - // Helper for testing purposes fn ExpectContext(comptime val: anytype) type { return struct { pub fn handle(_: @This(), _: anytype, _: anytype, ctx: anytype, _: void) !void { - try expectDeepEquals(val, ctx); + if (@TypeOf(val) == void) return error.TestUnexpectedResult; + try util.testing.expectDeepEqual(@as(@TypeOf(ctx), val), ctx); } }; } @@ -485,7 +470,15 @@ pub fn mount(comptime route: []const u8) Mount(route) { test "mount" { const testCase = struct { fn func(comptime base: []const u8, request: []const u8, comptime expected: ?[]const u8) !void { - const result = mount(base).handle(.{}, .{}, addField(.{}, "path", request), expectContext(.{ .path = expected orelse "" })); + const result = mount(base).handle( + .{}, + .{}, + addField(.{}, "path", request), + expectContext(.{ + .path = expected orelse "", + .mounted_at = std.mem.trim(u8, base, "/"), + }), + ); try if (expected != null) result else std.testing.expectError(error.RouteMismatch, result); } }.func; @@ -590,7 +583,8 @@ test "ParsePathArgs" { expected: @TypeOf(expected), path: []const u8, fn handle(self: @This(), _: anytype, _: anytype, ctx: anytype, _: void) !void { - try expectDeepEquals(self.expected, ctx.args); + if (@TypeOf(expected) == @TypeOf(null)) return error.TestUnexpectedResult; + try util.testing.expectDeepEqual(@as(@TypeOf(ctx.args), self.expected), ctx.args); try std.testing.expectEqualStrings(self.path, ctx.path); } }{ .expected = expected, .path = path }; @@ -619,10 +613,10 @@ test "ParsePathArgs" { try testCase("/:foo*", struct { foo: []const u8 }, "/", .{ .foo = "/" }); try testCase("/:foo*", struct { foo: []const u8 }, "", .{ .foo = "" }); - try std.testing.expectError(error.RouteMismatch, testCase("/:id", struct { id: usize }, "/", .{})); - try std.testing.expectError(error.RouteMismatch, testCase("/abcd/:id", struct { id: usize }, "/123", .{})); - try std.testing.expectError(error.RouteMismatch, testCase("/:id", struct { id: usize }, "/3/id/blahblah", .{ .id = 3 })); - try std.testing.expectError(error.InvalidCharacter, testCase("/:id", struct { id: usize }, "/xyz", .{})); + try std.testing.expectError(error.RouteMismatch, testCase("/:id", struct { id: usize }, "/", null)); + try std.testing.expectError(error.RouteMismatch, testCase("/abcd/:id", struct { id: usize }, "/123", null)); + try std.testing.expectError(error.RouteMismatch, testCase("/:id", struct { id: usize }, "/3/id/blahblah", null)); + try std.testing.expectError(error.InvalidCharacter, testCase("/:id", struct { id: usize }, "/xyz", null)); } const BaseContentType = enum { diff --git a/src/http/urlencode.zig b/src/http/urlencode.zig index c841717..85cc7b9 100644 --- a/src/http/urlencode.zig +++ b/src/http/urlencode.zig @@ -327,17 +327,20 @@ test "parse" { // try testCase(false, SubUnion, .{ .sub = null }, "sub="); const SubUnion2 = struct { - sub: ?struct { - foo: usize, - val: union(enum) { + sub: ?union(enum) { + bar: struct { + foo: usize, bar: []const u8, + }, + baz: struct { + foo: usize, baz: []const u8, }, } = null, }; try testCase(false, SubUnion2, .{ .sub = null }, ""); - try testCase(false, SubUnion2, .{ .sub = .{ .foo = 1, .val = .{ .bar = "abc" } } }, "sub.foo=1&sub.bar=abc"); - try testCase(false, SubUnion2, .{ .sub = .{ .foo = 1, .val = .{ .baz = "abc" } } }, "sub.foo=1&sub.baz=abc"); + try testCase(false, SubUnion2, .{ .sub = .{ .bar = .{ .foo = 1, .bar = "abc" } } }, "sub.foo=1&sub.bar=abc"); + try testCase(false, SubUnion2, .{ .sub = .{ .baz = .{ .foo = 1, .baz = "abc" } } }, "sub.foo=1&sub.baz=abc"); } test "encodeStruct" {