@ -10,6 +10,7 @@ import (
@@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"net/http"
"net/url"
"strings"
"testing"
)
@ -31,10 +32,11 @@ type routeTest struct {
@@ -31,10 +32,11 @@ type routeTest struct {
route * Route // the route being tested
request * http . Request // a request to test the route
vars map [ string ] string // the expected vars of the match
host string // the expected host of the match
path string // the expected path of the match
pathTemplate string // the expected path template to match
hostTemplate string // the expected host template to match
scheme string // the expected scheme of the built URL
host string // the expected host of the built URL
path string // the expected path of the built URL
pathTemplate string // the expected path template of the route
hostTemplate string // the expected host template of the route
methods [ ] string // the expected route methods
pathRegexp string // the expected path regexp
shouldMatch bool // whether the request is expected to match the route at all
@ -197,46 +199,6 @@ func TestHost(t *testing.T) {
@@ -197,46 +199,6 @@ func TestHost(t *testing.T) {
hostTemplate : ` { v-1:[a-z] { 3}}. { v-2:[a-z] { 3}}. { v-3:[a-z] { 3}} ` ,
shouldMatch : true ,
} ,
{
title : "Path route with single pattern with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}" ) ,
request : newRequest ( "GET" , "http://localhost/a" ) ,
vars : map [ string ] string { "category" : "a" } ,
host : "" ,
path : "/a" ,
pathTemplate : ` / { category:a|b/c} ` ,
shouldMatch : true ,
} ,
{
title : "Path route with single pattern with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}" ) ,
request : newRequest ( "GET" , "http://localhost/b/c" ) ,
vars : map [ string ] string { "category" : "b/c" } ,
host : "" ,
path : "/b/c" ,
pathTemplate : ` / { category:a|b/c} ` ,
shouldMatch : true ,
} ,
{
title : "Path route with multiple patterns with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}/{product}/{id:[0-9]+}" ) ,
request : newRequest ( "GET" , "http://localhost/a/product_name/1" ) ,
vars : map [ string ] string { "category" : "a" , "product" : "product_name" , "id" : "1" } ,
host : "" ,
path : "/a/product_name/1" ,
pathTemplate : ` / { category:a|b/c}/ { product}/ { id:[0-9]+} ` ,
shouldMatch : true ,
} ,
{
title : "Path route with multiple patterns with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}/{product}/{id:[0-9]+}" ) ,
request : newRequest ( "GET" , "http://localhost/b/c/product_name/1" ) ,
vars : map [ string ] string { "category" : "b/c" , "product" : "product_name" , "id" : "1" } ,
host : "" ,
path : "/b/c/product_name/1" ,
pathTemplate : ` / { category:a|b/c}/ { product}/ { id:[0-9]+} ` ,
shouldMatch : true ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
@ -428,6 +390,46 @@ func TestPath(t *testing.T) {
@@ -428,6 +390,46 @@ func TestPath(t *testing.T) {
pathRegexp : ` ^/(?P<v0>[0-9]*)(?P<v1>[a-z]*)/(?P<v2>[0-9]*)$ ` ,
shouldMatch : true ,
} ,
{
title : "Path route with single pattern with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}" ) ,
request : newRequest ( "GET" , "http://localhost/a" ) ,
vars : map [ string ] string { "category" : "a" } ,
host : "" ,
path : "/a" ,
pathTemplate : ` / { category:a|b/c} ` ,
shouldMatch : true ,
} ,
{
title : "Path route with single pattern with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}" ) ,
request : newRequest ( "GET" , "http://localhost/b/c" ) ,
vars : map [ string ] string { "category" : "b/c" } ,
host : "" ,
path : "/b/c" ,
pathTemplate : ` / { category:a|b/c} ` ,
shouldMatch : true ,
} ,
{
title : "Path route with multiple patterns with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}/{product}/{id:[0-9]+}" ) ,
request : newRequest ( "GET" , "http://localhost/a/product_name/1" ) ,
vars : map [ string ] string { "category" : "a" , "product" : "product_name" , "id" : "1" } ,
host : "" ,
path : "/a/product_name/1" ,
pathTemplate : ` / { category:a|b/c}/ { product}/ { id:[0-9]+} ` ,
shouldMatch : true ,
} ,
{
title : "Path route with multiple patterns with pipe, match" ,
route : new ( Route ) . Path ( "/{category:a|b/c}/{product}/{id:[0-9]+}" ) ,
request : newRequest ( "GET" , "http://localhost/b/c/product_name/1" ) ,
vars : map [ string ] string { "category" : "b/c" , "product" : "product_name" , "id" : "1" } ,
host : "" ,
path : "/b/c/product_name/1" ,
pathTemplate : ` / { category:a|b/c}/ { product}/ { id:[0-9]+} ` ,
shouldMatch : true ,
} ,
}
for _ , test := range tests {
@ -516,15 +518,28 @@ func TestPathPrefix(t *testing.T) {
@@ -516,15 +518,28 @@ func TestPathPrefix(t *testing.T) {
}
}
func TestHostPath ( t * testing . T ) {
func TestScheme HostPath ( t * testing . T ) {
tests := [ ] routeTest {
{
title : "Host and Path route, match" ,
route : new ( Route ) . Host ( "aaa.bbb.ccc" ) . Path ( "/111/222/333" ) ,
request : newRequest ( "GET" , "http://aaa.bbb.ccc/111/222/333" ) ,
vars : map [ string ] string { } ,
host : "" ,
path : "" ,
scheme : "http" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` /111/222/333 ` ,
hostTemplate : ` aaa.bbb.ccc ` ,
shouldMatch : true ,
} ,
{
title : "Scheme, Host, and Path route, match" ,
route : new ( Route ) . Schemes ( "https" ) . Host ( "aaa.bbb.ccc" ) . Path ( "/111/222/333" ) ,
request : newRequest ( "GET" , "https://aaa.bbb.ccc/111/222/333" ) ,
vars : map [ string ] string { } ,
scheme : "https" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` /111/222/333 ` ,
hostTemplate : ` aaa.bbb.ccc ` ,
shouldMatch : true ,
@ -534,8 +549,9 @@ func TestHostPath(t *testing.T) {
@@ -534,8 +549,9 @@ func TestHostPath(t *testing.T) {
route : new ( Route ) . Host ( "aaa.bbb.ccc" ) . Path ( "/111/222/333" ) ,
request : newRequest ( "GET" , "http://aaa.222.ccc/111/222/333" ) ,
vars : map [ string ] string { } ,
host : "" ,
path : "" ,
scheme : "http" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` /111/222/333 ` ,
hostTemplate : ` aaa.bbb.ccc ` ,
shouldMatch : false ,
@ -545,6 +561,19 @@ func TestHostPath(t *testing.T) {
@@ -545,6 +561,19 @@ func TestHostPath(t *testing.T) {
route : new ( Route ) . Host ( "aaa.{v1:[a-z]{3}}.ccc" ) . Path ( "/111/{v2:[0-9]{3}}/333" ) ,
request : newRequest ( "GET" , "http://aaa.bbb.ccc/111/222/333" ) ,
vars : map [ string ] string { "v1" : "bbb" , "v2" : "222" } ,
scheme : "http" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` /111/ { v2:[0-9] { 3}}/333 ` ,
hostTemplate : ` aaa. { v1:[a-z] { 3}}.ccc ` ,
shouldMatch : true ,
} ,
{
title : "Scheme, Host, and Path route with host and path patterns, match" ,
route : new ( Route ) . Schemes ( "ftp" , "ssss" ) . Host ( "aaa.{v1:[a-z]{3}}.ccc" ) . Path ( "/111/{v2:[0-9]{3}}/333" ) ,
request : newRequest ( "GET" , "ssss://aaa.bbb.ccc/111/222/333" ) ,
vars : map [ string ] string { "v1" : "bbb" , "v2" : "222" } ,
scheme : "ftp" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` /111/ { v2:[0-9] { 3}}/333 ` ,
@ -556,6 +585,7 @@ func TestHostPath(t *testing.T) {
@@ -556,6 +585,7 @@ func TestHostPath(t *testing.T) {
route : new ( Route ) . Host ( "aaa.{v1:[a-z]{3}}.ccc" ) . Path ( "/111/{v2:[0-9]{3}}/333" ) ,
request : newRequest ( "GET" , "http://aaa.222.ccc/111/222/333" ) ,
vars : map [ string ] string { "v1" : "bbb" , "v2" : "222" } ,
scheme : "http" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` /111/ { v2:[0-9] { 3}}/333 ` ,
@ -567,6 +597,7 @@ func TestHostPath(t *testing.T) {
@@ -567,6 +597,7 @@ func TestHostPath(t *testing.T) {
route : new ( Route ) . Host ( "{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}" ) . Path ( "/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}" ) ,
request : newRequest ( "GET" , "http://aaa.bbb.ccc/111/222/333" ) ,
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" , "v4" : "111" , "v5" : "222" , "v6" : "333" } ,
scheme : "http" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` / { v4:[0-9] { 3}}/ { v5:[0-9] { 3}}/ { v6:[0-9] { 3}} ` ,
@ -578,6 +609,7 @@ func TestHostPath(t *testing.T) {
@@ -578,6 +609,7 @@ func TestHostPath(t *testing.T) {
route : new ( Route ) . Host ( "{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}" ) . Path ( "/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}" ) ,
request : newRequest ( "GET" , "http://aaa.222.ccc/111/222/333" ) ,
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" , "v4" : "111" , "v5" : "222" , "v6" : "333" } ,
scheme : "http" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
pathTemplate : ` / { v4:[0-9] { 3}}/ { v5:[0-9] { 3}}/ { v6:[0-9] { 3}} ` ,
@ -649,7 +681,6 @@ func TestHeaders(t *testing.T) {
@@ -649,7 +681,6 @@ func TestHeaders(t *testing.T) {
testRoute ( t , test )
testTemplate ( t , test )
}
}
func TestMethods ( t * testing . T ) {
@ -938,30 +969,43 @@ func TestSchemes(t *testing.T) {
@@ -938,30 +969,43 @@ func TestSchemes(t *testing.T) {
tests := [ ] routeTest {
// Schemes
{
title : "Schemes route, match https" ,
route : new ( Route ) . Schemes ( "https" , "ftp" ) ,
title : "Schemes route, default scheme, match http, build http" ,
route : new ( Route ) . Host ( "localhost" ) ,
request : newRequest ( "GET" , "http://localhost" ) ,
scheme : "http" ,
host : "localhost" ,
shouldMatch : true ,
} ,
{
title : "Schemes route, match https, build https" ,
route : new ( Route ) . Schemes ( "https" , "ftp" ) . Host ( "localhost" ) ,
request : newRequest ( "GET" , "https://localhost" ) ,
vars : map [ string ] string { } ,
host : "" ,
path : "" ,
scheme : "https" ,
host : "localhost" ,
shouldMatch : true ,
} ,
{
title : "Schemes route, match ftp" ,
route : new ( Route ) . Schemes ( "https" , "ftp" ) ,
title : "Schemes route, match ftp, build https " ,
route : new ( Route ) . Schemes ( "https" , "ftp" ) . Host ( "localhost" ) ,
request : newRequest ( "GET" , "ftp://localhost" ) ,
vars : map [ string ] string { } ,
host : "" ,
path : "" ,
scheme : "https" ,
host : "localhost" ,
shouldMatch : true ,
} ,
{
title : "Schemes route, match ftp, build ftp" ,
route : new ( Route ) . Schemes ( "ftp" , "https" ) . Host ( "localhost" ) ,
request : newRequest ( "GET" , "ftp://localhost" ) ,
scheme : "ftp" ,
host : "localhost" ,
shouldMatch : true ,
} ,
{
title : "Schemes route, bad scheme" ,
route : new ( Route ) . Schemes ( "https" , "ftp" ) ,
route : new ( Route ) . Schemes ( "https" , "ftp" ) . Host ( "localhost" ) ,
request : newRequest ( "GET" , "http://localhost" ) ,
vars : map [ string ] string { } ,
host : "" ,
path : "" ,
scheme : "https" ,
host : "localhost" ,
shouldMatch : false ,
} ,
}
@ -1448,10 +1492,15 @@ func testRoute(t *testing.T, test routeTest) {
@@ -1448,10 +1492,15 @@ func testRoute(t *testing.T, test routeTest) {
route := test . route
vars := test . vars
shouldMatch := test . shouldMatch
host := test . host
path := test . path
url := test . host + test . path
shouldRedirect := test . shouldRedirect
uri := url . URL {
Scheme : test . scheme ,
Host : test . host ,
Path : test . path ,
}
if uri . Scheme == "" {
uri . Scheme = "http"
}
var match RouteMatch
ok := route . Match ( request , & match )
@ -1464,28 +1513,51 @@ func testRoute(t *testing.T, test routeTest) {
@@ -1464,28 +1513,51 @@ func testRoute(t *testing.T, test routeTest) {
return
}
if shouldMatch {
if test . vars != nil && ! stringMapEqual ( test . vars , match . Vars ) {
if vars != nil && ! stringMapEqual ( vars , match . Vars ) {
t . Errorf ( "(%v) Vars not equal: expected %v, got %v" , test . title , vars , match . Vars )
return
}
if host != "" {
u , _ := test . route . URLHost ( mapToPairs ( match . Vars ) ... )
if host != u . Host {
t . Errorf ( "(%v) URLHost not equal: expected %v, got %v -- %v" , test . title , host , u . Host , getRouteTemplate ( route ) )
if test . scheme != "" {
u , err := route . URL ( mapToPairs ( match . Vars ) ... )
if err != nil {
t . Fatalf ( "(%v) URL error: %v -- %v" , test . title , err , getRouteTemplate ( route ) )
}
if uri . Scheme != u . Scheme {
t . Errorf ( "(%v) URLScheme not equal: expected %v, got %v" , test . title , uri . Scheme , u . Scheme )
return
}
}
if path != "" {
u , _ := route . URLPath ( mapToPairs ( match . Vars ) ... )
if path != u . Path {
t . Errorf ( "(%v) URLPath not equal: expected %v, got %v -- %v" , test . title , path , u . Path , getRouteTemplate ( route ) )
if test . host != "" {
u , err := test . route . URLHost ( mapToPairs ( match . Vars ) ... )
if err != nil {
t . Fatalf ( "(%v) URLHost error: %v -- %v" , test . title , err , getRouteTemplate ( route ) )
}
if uri . Scheme != u . Scheme {
t . Errorf ( "(%v) URLHost scheme not equal: expected %v, got %v -- %v" , test . title , uri . Scheme , u . Scheme , getRouteTemplate ( route ) )
return
}
if uri . Host != u . Host {
t . Errorf ( "(%v) URLHost host not equal: expected %v, got %v -- %v" , test . title , uri . Host , u . Host , getRouteTemplate ( route ) )
return
}
}
if test . path != "" {
u , err := route . URLPath ( mapToPairs ( match . Vars ) ... )
if err != nil {
t . Fatalf ( "(%v) URLPath error: %v -- %v" , test . title , err , getRouteTemplate ( route ) )
}
if uri . Path != u . Path {
t . Errorf ( "(%v) URLPath not equal: expected %v, got %v -- %v" , test . title , uri . Path , u . Path , getRouteTemplate ( route ) )
return
}
}
if test . host != "" && test . path != "" {
u , err := route . URL ( mapToPairs ( match . Vars ) ... )
if err != nil {
t . Fatalf ( "(%v) URL error: %v -- %v" , test . title , err , getRouteTemplate ( route ) )
}
if url != "" {
u , _ := route . URL ( mapToPairs ( match . Vars ) ... )
if url != u . Host + u . Path {
t . Errorf ( "(%v) URL not equal: expected %v, got %v -- %v" , test . title , url , u . Host + u . Path , getRouteTemplate ( route ) )
if expected , got := uri . String ( ) , u . String ( ) ; expected != got {
t . Errorf ( "(%v) URL not equal: expected %v, got %v -- %v" , test . title , expected , got , getRouteTemplate ( route ) )
return
}
}