From 1856953e530eab2cb8793c42c7e9c1e6b1dc2709 Mon Sep 17 00:00:00 2001 From: Bulat Gaifullin Date: Tue, 18 Apr 2017 09:50:17 +0300 Subject: [PATCH] Added method Route.GetPathRegexp --- mux_test.go | 21 +++++++++++++++++++++ route.go | 14 ++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/mux_test.go b/mux_test.go index 1dec7ab..1ccc920 100644 --- a/mux_test.go +++ b/mux_test.go @@ -35,6 +35,7 @@ type routeTest struct { path string // the expected path of the match pathTemplate string // the expected path template to match hostTemplate string // the expected host template to match + pathRegexp string // the expected path regexp shouldMatch bool // whether the request is expected to match the route at all shouldRedirect bool // whether the request should result in a redirect } @@ -270,6 +271,7 @@ func TestPath(t *testing.T) { host: "", path: "/111", pathTemplate: `/111/`, + pathRegexp: `^/111/$`, shouldMatch: false, }, { @@ -290,6 +292,7 @@ func TestPath(t *testing.T) { host: "", path: "/", pathTemplate: `/`, + pathRegexp: `^/$`, shouldMatch: true, }, { @@ -333,6 +336,7 @@ func TestPath(t *testing.T) { host: "", path: "/111/222/333", pathTemplate: `/111/{v1:[0-9]{3}}/333`, + pathRegexp: `^/111/(?P[0-9]{3})/333$`, shouldMatch: false, }, { @@ -343,6 +347,7 @@ func TestPath(t *testing.T) { host: "", path: "/111/222/333", pathTemplate: `/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}`, + pathRegexp: `^/(?P[0-9]{3})/(?P[0-9]{3})/(?P[0-9]{3})$`, shouldMatch: true, }, { @@ -353,6 +358,7 @@ func TestPath(t *testing.T) { host: "", path: "/111/222/333", pathTemplate: `/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}`, + pathRegexp: `^/(?P[0-9]{3})/(?P[0-9]{3})/(?P[0-9]{3})$`, shouldMatch: false, }, { @@ -363,6 +369,7 @@ func TestPath(t *testing.T) { host: "", path: "/a/product_name/1", pathTemplate: `/{category:a|(?:b/c)}/{product}/{id:[0-9]+}`, + pathRegexp: `^/(?Pa|(?:b/c))/(?P[^/]+)/(?P[0-9]+)$`, shouldMatch: true, }, { @@ -373,6 +380,7 @@ func TestPath(t *testing.T) { host: "", path: "/111/222/333", pathTemplate: `/111/{v-1:[0-9]{3}}/333`, + pathRegexp: `^/111/(?P[0-9]{3})/333$`, shouldMatch: true, }, { @@ -383,6 +391,7 @@ func TestPath(t *testing.T) { host: "", path: "/111/222/333", pathTemplate: `/{v-1:[0-9]{3}}/{v-2:[0-9]{3}}/{v-3:[0-9]{3}}`, + pathRegexp: `^/(?P[0-9]{3})/(?P[0-9]{3})/(?P[0-9]{3})$`, shouldMatch: true, }, { @@ -393,6 +402,7 @@ func TestPath(t *testing.T) { host: "", path: "/a/product_name/1", pathTemplate: `/{product-category:a|(?:b/c)}/{product-name}/{product-id:[0-9]+}`, + pathRegexp: `^/(?Pa|(?:b/c))/(?P[^/]+)/(?P[0-9]+)$`, shouldMatch: true, }, { @@ -403,6 +413,7 @@ func TestPath(t *testing.T) { host: "", path: "/daily-2016-01-01", pathTemplate: `/{type:(?i:daily|mini|variety)}-{date:\d{4,4}-\d{2,2}-\d{2,2}}`, + pathRegexp: `^/(?P(?i:daily|mini|variety))-(?P\d{4,4}-\d{2,2}-\d{2,2})$`, shouldMatch: true, }, { @@ -413,6 +424,7 @@ func TestPath(t *testing.T) { host: "", path: "/111/222", pathTemplate: `/{v1:[0-9]*}{v2:[a-z]*}/{v3:[0-9]*}`, + pathRegexp: `^/(?P[0-9]*)(?P[a-z]*)/(?P[0-9]*)$`, shouldMatch: true, }, } @@ -421,6 +433,7 @@ func TestPath(t *testing.T) { testRoute(t, test) testTemplate(t, test) testUseEscapedRoute(t, test) + testRegexp(t, test) } } @@ -1499,6 +1512,14 @@ func testTemplate(t *testing.T, test routeTest) { } } +func testRegexp(t *testing.T, test routeTest) { + route := test.route + routePathRegexp, regexpErr := route.GetPathRegexp() + if test.pathRegexp != "" && regexpErr == nil && routePathRegexp != test.pathRegexp { + t.Errorf("(%v) GetPathRegexp not equal: expected %v, got %v", test.title, test.pathRegexp, routePathRegexp) + } +} + type TestA301ResponseWriter struct { hh http.Header status int diff --git a/route.go b/route.go index 5544c1f..d3ba6cd 100644 --- a/route.go +++ b/route.go @@ -558,6 +558,20 @@ func (r *Route) GetPathTemplate() (string, error) { return r.regexp.path.template, nil } +// GetPathRegexp returns the expanded regular expression used to match route path. +// This is useful for building simple REST API documentation and for instrumentation +// against third-party services. +// An error will be returned if the route does not define a path. +func (r *Route) GetPathRegexp() (string, error) { + if r.err != nil { + return "", r.err + } + if r.regexp == nil || r.regexp.path == nil { + return "", errors.New("mux: route does not have a path") + } + return r.regexp.path.regexp.String(), nil +} + // GetHostTemplate returns the template used to build the // route match. // This is useful for building simple REST API documentation and for instrumentation