From 22a5ebdeda924a16bf65c4f8c6fabe03e26272e4 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sat, 3 Oct 2026 11:27:44 +0200 Subject: [PATCH] test(13-06): pin that a family falls through a member whose constraint fails - TestOverlapConstraintFallsThrough: an earlier member that matches the literals but not its Where constraint must let a later member answer; the routes.php pairs cannot show this, since each member's own handler re-checks its constraints and the pairs differ in their literals (T-13-23) --- modules/surf/overlap_edges_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/modules/surf/overlap_edges_test.go b/modules/surf/overlap_edges_test.go index f12aa88..7ef953e 100644 --- a/modules/surf/overlap_edges_test.go +++ b/modules/surf/overlap_edges_test.go @@ -146,3 +146,27 @@ func TestOverlapUnsupportedShapes(t *testing.T) { }) } } + +// TestOverlapConstraintFallsThrough: when an earlier member matches the +// literals but not its constraint, the family tries the next member +// instead of answering for the first one, as Laravel's router walks its +// routes in order. +func TestOverlapConstraintFallsThrough(t *testing.T) { + h := compileOverlap(t, []overlapRoute{ + {name: "by-number", method: "GET", path: "/drawers/{id}/open", where: map[string]string{"id": "[0-9]+"}}, + {name: "by-name", method: "GET", path: "/drawers/top/{action}"}, + }) + for _, c := range []struct{ path, want string }{ + {"/drawers/top/open", "by-name action=open"}, + {"/drawers/7/open", "by-number id=7"}, + {"/drawers/top/close", "by-name action=close"}, + } { + rec := serve(h, "GET", c.path) + if rec.Code != http.StatusOK || rec.Body.String() != c.want { + t.Errorf("GET %s = %d %q, want 200 %q", c.path, rec.Code, rec.Body.String(), c.want) + } + } + if rec := serve(h, "GET", "/drawers/x/open"); rec.Code != http.StatusNotFound { + t.Errorf("GET /drawers/x/open = %d, want 404", rec.Code) + } +}