@ -10,17 +10,19 @@ import (
"testing"
"testing"
)
)
// helper function to create a new request with a method and url
type routeTest struct {
func newRequest ( method , url string ) * http . Request {
title string // title of the test
req , err := http . NewRequest ( method , url , nil )
route * Route // the route being tested
if err != nil {
request * http . Request // a request to test the route
panic ( err )
vars map [ string ] string // the expected vars of the match
}
host string // the expected host of the match
return req
path string // the expected path of the match
shouldMatch bool // whether the request is expected to match the route at all
}
}
// helper function to create a new request with a method, url, and host header
func TestHost ( t * testing . T ) {
func newRequestHost ( method , url , host string ) * http . Request {
// newRequestHost a new request with a method, url, and host header
newRequestHost := func ( method , url , host string ) * http . Request {
req , err := http . NewRequest ( method , url , nil )
req , err := http . NewRequest ( method , url , nil )
if err != nil {
if err != nil {
panic ( err )
panic ( err )
@ -29,39 +31,7 @@ func newRequestHost(method, url, host string) *http.Request {
return req
return req
}
}
// helper function to create a new request with a method, url, and headers
tests := [ ] routeTest {
func newRequestHeaders ( method , url string , headers map [ string ] string ) * http . Request {
req , err := http . NewRequest ( method , url , nil )
if err != nil {
panic ( err )
}
for k , v := range headers {
req . Header . Add ( k , v )
}
return req
}
// Tests for Route
func TestRoute ( t * testing . T ) {
// match function for Custom tests
m := func ( r * http . Request , m * RouteMatch ) bool {
if r . URL . Host == "aaa.bbb.ccc" {
return true
}
return false
}
// the tests
tests := [ ] struct {
title string // title of the test
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
match bool // whether the request is expected to match the route at all
} {
// Host
{
{
title : "Host route match" ,
title : "Host route match" ,
route : new ( Route ) . Host ( "aaa.bbb.ccc" ) ,
route : new ( Route ) . Host ( "aaa.bbb.ccc" ) ,
@ -69,7 +39,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host route, wrong host in request URL" ,
title : "Host route, wrong host in request URL" ,
@ -78,7 +48,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Host route with port, match" ,
title : "Host route with port, match" ,
@ -87,7 +57,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "aaa.bbb.ccc:1234" ,
host : "aaa.bbb.ccc:1234" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host route with port, wrong port in request URL" ,
title : "Host route with port, wrong port in request URL" ,
@ -96,7 +66,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "aaa.bbb.ccc:1234" ,
host : "aaa.bbb.ccc:1234" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Host route, match with host in request header" ,
title : "Host route, match with host in request header" ,
@ -105,7 +75,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host route, wrong host in request header" ,
title : "Host route, wrong host in request header" ,
@ -114,7 +84,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
// BUG {new(Route).Host("aaa.bbb.ccc:1234"), newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:1234"), map[string]string{}, "aaa.bbb.ccc:1234", "", true},
// BUG {new(Route).Host("aaa.bbb.ccc:1234"), newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:1234"), map[string]string{}, "aaa.bbb.ccc:1234", "", true},
{
{
@ -124,7 +94,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "aaa.bbb.ccc:1234" ,
host : "aaa.bbb.ccc:1234" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Host route with pattern, match" ,
title : "Host route with pattern, match" ,
@ -133,7 +103,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "bbb" } ,
vars : map [ string ] string { "v1" : "bbb" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host route with pattern, wrong host in request URL" ,
title : "Host route with pattern, wrong host in request URL" ,
@ -142,7 +112,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "bbb" } ,
vars : map [ string ] string { "v1" : "bbb" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Host route with multiple patterns, match" ,
title : "Host route with multiple patterns, match" ,
@ -151,7 +121,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" } ,
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host route with multiple patterns, wrong host in request URL" ,
title : "Host route with multiple patterns, wrong host in request URL" ,
@ -160,10 +130,16 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" } ,
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
}
}
// Path
func TestPath ( t * testing . T ) {
tests := [ ] routeTest {
{
{
title : "Path route, match" ,
title : "Path route, match" ,
route : new ( Route ) . Path ( "/111/222/333" ) ,
route : new ( Route ) . Path ( "/111/222/333" ) ,
@ -171,7 +147,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Path route, wrong path in request in request URL" ,
title : "Path route, wrong path in request in request URL" ,
@ -180,7 +156,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Path route with pattern, match" ,
title : "Path route with pattern, match" ,
@ -189,7 +165,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "222" } ,
vars : map [ string ] string { "v1" : "222" } ,
host : "" ,
host : "" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Path route with pattern, URL in request does not match" ,
title : "Path route with pattern, URL in request does not match" ,
@ -198,7 +174,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "222" } ,
vars : map [ string ] string { "v1" : "222" } ,
host : "" ,
host : "" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Path route with multiple patterns, match" ,
title : "Path route with multiple patterns, match" ,
@ -207,7 +183,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "111" , "v2" : "222" , "v3" : "333" } ,
vars : map [ string ] string { "v1" : "111" , "v2" : "222" , "v3" : "333" } ,
host : "" ,
host : "" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Path route with multiple patterns, URL in request does not match" ,
title : "Path route with multiple patterns, URL in request does not match" ,
@ -216,10 +192,17 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "111" , "v2" : "222" , "v3" : "333" } ,
vars : map [ string ] string { "v1" : "111" , "v2" : "222" , "v3" : "333" } ,
host : "" ,
host : "" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
// PathPrefix
for _ , test := range tests {
testRoute ( t , test )
}
}
func TestPathPrefix ( t * testing . T ) {
tests := [ ] routeTest {
{
{
title : "PathPrefix route, match" ,
title : "PathPrefix route, match" ,
route : new ( Route ) . PathPrefix ( "/111" ) ,
route : new ( Route ) . PathPrefix ( "/111" ) ,
@ -227,7 +210,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "/111" ,
path : "/111" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "PathPrefix route, URL prefix in request does not match" ,
title : "PathPrefix route, URL prefix in request does not match" ,
@ -236,7 +219,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "/111" ,
path : "/111" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "PathPrefix route with pattern, match" ,
title : "PathPrefix route with pattern, match" ,
@ -245,7 +228,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "222" } ,
vars : map [ string ] string { "v1" : "222" } ,
host : "" ,
host : "" ,
path : "/111/222" ,
path : "/111/222" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "PathPrefix route with pattern, URL prefix in request does not match" ,
title : "PathPrefix route with pattern, URL prefix in request does not match" ,
@ -254,7 +237,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "222" } ,
vars : map [ string ] string { "v1" : "222" } ,
host : "" ,
host : "" ,
path : "/111/222" ,
path : "/111/222" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "PathPrefix route with multiple patterns, match" ,
title : "PathPrefix route with multiple patterns, match" ,
@ -263,7 +246,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "111" , "v2" : "222" } ,
vars : map [ string ] string { "v1" : "111" , "v2" : "222" } ,
host : "" ,
host : "" ,
path : "/111/222" ,
path : "/111/222" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "PathPrefix route with multiple patterns, URL prefix in request does not match" ,
title : "PathPrefix route with multiple patterns, URL prefix in request does not match" ,
@ -272,10 +255,17 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "111" , "v2" : "222" } ,
vars : map [ string ] string { "v1" : "111" , "v2" : "222" } ,
host : "" ,
host : "" ,
path : "/111/222" ,
path : "/111/222" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
}
}
// Host + Path
func TestHostPath ( t * testing . T ) {
tests := [ ] routeTest {
{
{
title : "Host and Path route, match" ,
title : "Host and Path route, match" ,
route : new ( Route ) . Host ( "aaa.bbb.ccc" ) . Path ( "/111/222/333" ) ,
route : new ( Route ) . Host ( "aaa.bbb.ccc" ) . Path ( "/111/222/333" ) ,
@ -283,7 +273,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host and Path route, wrong host in request URL" ,
title : "Host and Path route, wrong host in request URL" ,
@ -292,7 +282,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Host and Path route with pattern, match" ,
title : "Host and Path route with pattern, match" ,
@ -301,7 +291,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "bbb" , "v2" : "222" } ,
vars : map [ string ] string { "v1" : "bbb" , "v2" : "222" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host and Path route with pattern, URL in request does not match" ,
title : "Host and Path route with pattern, URL in request does not match" ,
@ -310,7 +300,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "bbb" , "v2" : "222" } ,
vars : map [ string ] string { "v1" : "bbb" , "v2" : "222" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : false ,
shouldMatch : false ,
} ,
} ,
{
{
title : "Host and Path route with multiple patterns, match" ,
title : "Host and Path route with multiple patterns, match" ,
@ -319,7 +309,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" , "v4" : "111" , "v5" : "222" , "v6" : "333" } ,
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" , "v4" : "111" , "v5" : "222" , "v6" : "333" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Host and Path route with multiple patterns, URL in request does not match" ,
title : "Host and Path route with multiple patterns, URL in request does not match" ,
@ -328,10 +318,29 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" , "v4" : "111" , "v5" : "222" , "v6" : "333" } ,
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" , "v3" : "ccc" , "v4" : "111" , "v5" : "222" , "v6" : "333" } ,
host : "aaa.bbb.ccc" ,
host : "aaa.bbb.ccc" ,
path : "/111/222/333" ,
path : "/111/222/333" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
}
}
// Headers
func TestHeaders ( t * testing . T ) {
// newRequestHeaders creates a new request with a method, url, and headers
newRequestHeaders := func ( method , url string , headers map [ string ] string ) * http . Request {
req , err := http . NewRequest ( method , url , nil )
if err != nil {
panic ( err )
}
for k , v := range headers {
req . Header . Add ( k , v )
}
return req
}
tests := [ ] routeTest {
{
{
title : "Headers route, match" ,
title : "Headers route, match" ,
route : new ( Route ) . Headers ( "foo" , "bar" , "baz" , "ding" ) ,
route : new ( Route ) . Headers ( "foo" , "bar" , "baz" , "ding" ) ,
@ -339,7 +348,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Headers route, bad header values" ,
title : "Headers route, bad header values" ,
@ -348,10 +357,18 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
}
}
// Methods
func TestMethods ( t * testing . T ) {
tests := [ ] routeTest {
{
{
title : "Methods route, match GET" ,
title : "Methods route, match GET" ,
route : new ( Route ) . Methods ( "GET" , "POST" ) ,
route : new ( Route ) . Methods ( "GET" , "POST" ) ,
@ -359,7 +376,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Methods route, match POST" ,
title : "Methods route, match POST" ,
@ -368,7 +385,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Methods route, bad method" ,
title : "Methods route, bad method" ,
@ -377,10 +394,17 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
}
}
// Queries
func TestQueries ( t * testing . T ) {
tests := [ ] routeTest {
{
{
title : "Queries route, match" ,
title : "Queries route, match" ,
route : new ( Route ) . Queries ( "foo" , "bar" , "baz" , "ding" ) ,
route : new ( Route ) . Queries ( "foo" , "bar" , "baz" , "ding" ) ,
@ -388,7 +412,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Queries route, bad query" ,
title : "Queries route, bad query" ,
@ -397,9 +421,17 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
}
}
func TestSchemes ( t * testing . T ) {
tests := [ ] routeTest {
// Schemes
// Schemes
{
{
title : "Schemes route, match https" ,
title : "Schemes route, match https" ,
@ -408,7 +440,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Schemes route, match ftp" ,
title : "Schemes route, match ftp" ,
@ -417,7 +449,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "Schemes route, bad scheme" ,
title : "Schemes route, bad scheme" ,
@ -426,10 +458,23 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
for _ , test := range tests {
testRoute ( t , test )
}
}
// Custom
func TestMatcherFunc ( t * testing . T ) {
m := func ( r * http . Request , m * RouteMatch ) bool {
if r . URL . Host == "aaa.bbb.ccc" {
return true
}
return false
}
tests := [ ] routeTest {
{
{
title : "MatchFunc route, match" ,
title : "MatchFunc route, match" ,
route : new ( Route ) . MatcherFunc ( m ) ,
route : new ( Route ) . MatcherFunc ( m ) ,
@ -437,7 +482,7 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : true ,
shouldMatch : true ,
} ,
} ,
{
{
title : "MatchFunc route, non-match" ,
title : "MatchFunc route, non-match" ,
@ -446,56 +491,57 @@ func TestRoute(t *testing.T) {
vars : map [ string ] string { } ,
vars : map [ string ] string { } ,
host : "" ,
host : "" ,
path : "" ,
path : "" ,
match : false ,
shouldMatch : false ,
} ,
} ,
}
}
for i , test := range tests {
for _ , test := range tests {
testRoute ( t , fmt . Sprintf ( "%v: %s" , i , test . title ) , test . match , test . route , test . request , test . vars , test . host , test . path , test . host + test . path )
testRoute ( t , test )
}
}
}
}
func TestSubRouter ( t * testing . T ) {
func TestSubRouter ( t * testing . T ) {
var route * Route
subrouter1 := new ( Route ) . Host ( "{v1:[a-z]+}.google.com" ) . Subrouter ( )
var request * http . Request
subrouter2 := new ( Route ) . PathPrefix ( "/foo/{v1}" ) . Subrouter ( )
var vars map [ string ] string
var host , path , url string
tests := [ ] routeTest {
{
subrouter := new ( Route ) . Host ( "{v1:[a-z]+}.google.com" ) . Subrouter ( )
route : subrouter1 . Path ( "/{v2:[a-z]+}" ) ,
request : newRequest ( "GET" , "http://aaa.google.com/bbb" ) ,
// Setup an id so we can see which test failed. :)
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" } ,
var idValue int
host : "aaa.google.com" ,
id := func ( ) int {
path : "/bbb" ,
idValue ++
shouldMatch : true ,
return idValue
} ,
}
{
route : subrouter1 . Path ( "/{v2:[a-z]+}" ) ,
// ------------------------------------------------------------------------
request : newRequest ( "GET" , "http://111.google.com/111" ) ,
vars : map [ string ] string { "v1" : "aaa" , "v2" : "bbb" } ,
route = subrouter . Path ( "/{v2:[a-z]+}" )
host : "aaa.google.com" ,
request , _ = http . NewRequest ( "GET" , "http://aaa.google.com/bbb" , nil )
path : "/bbb" ,
vars = map [ string ] string { "v1" : "aaa" , "v2" : "bbb" }
shouldMatch : false ,
host = "aaa.google.com"
} ,
path = "/bbb"
{
url = host + path
route : subrouter2 . Path ( "/baz/{v2}" ) ,
testRoute ( t , string ( id ( ) ) , true , route , request , vars , host , path , url )
request : newRequest ( "GET" , "http://localhost/foo/bar/baz/ding" ) ,
// Non-match for the same config.
vars : map [ string ] string { "v1" : "bar" , "v2" : "ding" } ,
request , _ = http . NewRequest ( "GET" , "http://111.google.com/111" , nil )
host : "" ,
testRoute ( t , string ( id ( ) ) , false , route , request , vars , host , path , url )
path : "/foo/bar/baz/ding" ,
shouldMatch : true ,
// ------------------------------------------------------------------------
} ,
{
subrouter = new ( Route ) . PathPrefix ( "/foo/{v1}" ) . Subrouter ( )
route : subrouter2 . Path ( "/baz/{v2}" ) ,
route = subrouter . Path ( "/baz/{v2}" )
request : newRequest ( "GET" , "http://localhost/foo/bar" ) ,
request , _ = http . NewRequest ( "GET" , "http://localhost/foo/bar/baz/ding" , nil )
vars : map [ string ] string { "v1" : "bar" , "v2" : "ding" } ,
vars = map [ string ] string { "v1" : "bar" , "v2" : "ding" }
host : "" ,
host = ""
path : "/foo/bar/baz/ding" ,
path = "/foo/bar/baz/ding"
shouldMatch : false ,
url = host + path
} ,
testRoute ( t , string ( id ( ) ) , true , route , request , vars , host , path , url )
}
// Non-match for the same config.
request , _ = http . NewRequest ( "GET" , "http://localhost/foo/bar" , nil )
for _ , test := range tests {
testRoute ( t , string ( id ( ) ) , false , route , request , vars , host , path , url )
testRoute ( t , test )
}
}
}
func TestNamedRoutes ( t * testing . T ) {
func TestNamedRoutes ( t * testing . T ) {
@ -521,6 +567,30 @@ func TestNamedRoutes(t *testing.T) {
}
}
}
}
func TestStrictSlash ( t * testing . T ) {
var r * Router
var req * http . Request
var route * Route
var match * RouteMatch
var matched bool
// StrictSlash should be ignored for path prefix.
// So we register a route ending in slash but it doesn't attempt to add
// the slash for a path not ending in slash.
r = NewRouter ( )
r . StrictSlash ( true )
route = r . NewRoute ( ) . PathPrefix ( "/static/" )
req , _ = http . NewRequest ( "GET" , "http://localhost/static/logo.png" , nil )
match = new ( RouteMatch )
matched = r . Match ( req , match )
if ! matched {
t . Errorf ( "Should match request %q -- %v" , req . URL . Path , getRouteTemplate ( route ) )
}
if match . Handler != nil {
t . Errorf ( "Should not redirect" )
}
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Helpers
// Helpers
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@ -538,8 +608,15 @@ func getRouteTemplate(route *Route) string {
return fmt . Sprintf ( "Host: %v, Path: %v" , host , path )
return fmt . Sprintf ( "Host: %v, Path: %v" , host , path )
}
}
func testRoute ( t * testing . T , id string , shouldMatch bool , route * Route ,
func testRoute ( t * testing . T , test routeTest ) {
request * http . Request , vars map [ string ] string , host , path , url string ) {
request := test . request
route := test . route
vars := test . vars
shouldMatch := test . shouldMatch
host := test . host
path := test . path
url := test . host + test . path
var match RouteMatch
var match RouteMatch
ok := route . Match ( request , & match )
ok := route . Match ( request , & match )
if ok != shouldMatch {
if ok != shouldMatch {
@ -547,62 +624,39 @@ func testRoute(t *testing.T, id string, shouldMatch bool, route *Route,
if ! shouldMatch {
if ! shouldMatch {
msg = "Should not match"
msg = "Should not match"
}
}
t . Errorf ( "(%v) %v:\nRoute: %#v\nRequest: %#v\nVars: %v\n" , id , msg , route , request , vars )
t . Errorf ( "(%v) %v:\nRoute: %#v\nRequest: %#v\nVars: %v\n" , test . title , msg , route , request , vars )
return
return
}
}
if shouldMatch {
if shouldMatch {
if vars != nil && ! stringMapEqual ( vars , match . Vars ) {
if test . vars != nil && ! stringMapEqual ( test . vars , match . Vars ) {
t . Errorf ( "(%v) Vars not equal: expected %v, got %v" , id , vars , match . Vars )
t . Errorf ( "(%v) Vars not equal: expected %v, got %v" , test . title , vars , match . Vars )
return
return
}
}
if host != "" {
if host != "" {
u , _ := route . URLHost ( mapToPairs ( match . Vars ) ... )
u , _ := test . route . URLHost ( mapToPairs ( match . Vars ) ... )
if host != u . Host {
if host != u . Host {
t . Errorf ( "(%v) URLHost not equal: expected %v, got %v -- %v" , id , host , u . Host , getRouteTemplate ( route ) )
t . Errorf ( "(%v) URLHost not equal: expected %v, got %v -- %v" , test . title , host , u . Host , getRouteTemplate ( route ) )
return
return
}
}
}
}
if path != "" {
if path != "" {
u , _ := route . URLPath ( mapToPairs ( match . Vars ) ... )
u , _ := route . URLPath ( mapToPairs ( match . Vars ) ... )
if path != u . Path {
if path != u . Path {
t . Errorf ( "(%v) URLPath not equal: expected %v, got %v -- %v" , id , path , u . Path , getRouteTemplate ( route ) )
t . Errorf ( "(%v) URLPath not equal: expected %v, got %v -- %v" , test . title , path , u . Path , getRouteTemplate ( route ) )
return
return
}
}
}
}
if url != "" {
if url != "" {
u , _ := route . URL ( mapToPairs ( match . Vars ) ... )
u , _ := route . URL ( mapToPairs ( match . Vars ) ... )
if url != u . Host + u . Path {
if url != u . Host + u . Path {
t . Errorf ( "(%v) URL not equal: expected %v, got %v -- %v" , id , url , u . Host + u . Path , getRouteTemplate ( route ) )
t . Errorf ( "(%v) URL not equal: expected %v, got %v -- %v" , test . title , url , u . Host + u . Path , getRouteTemplate ( route ) )
return
return
}
}
}
}
}
}
}
}
func TestStrictSlash ( t * testing . T ) {
// mapToPairs converts a string map to a slice of string pairs
var r * Router
var req * http . Request
var route * Route
var match * RouteMatch
var matched bool
// StrictSlash should be ignored for path prefix.
// So we register a route ending in slash but it doesn't attempt to add
// the slash for a path not ending in slash.
r = NewRouter ( )
r . StrictSlash ( true )
route = r . NewRoute ( ) . PathPrefix ( "/static/" )
req , _ = http . NewRequest ( "GET" , "http://localhost/static/logo.png" , nil )
match = new ( RouteMatch )
matched = r . Match ( req , match )
if ! matched {
t . Errorf ( "Should match request %q -- %v" , req . URL . Path , getRouteTemplate ( route ) )
}
if match . Handler != nil {
t . Errorf ( "Should not redirect" )
}
}
func mapToPairs ( m map [ string ] string ) [ ] string {
func mapToPairs ( m map [ string ] string ) [ ] string {
var i int
var i int
p := make ( [ ] string , len ( m ) * 2 )
p := make ( [ ] string , len ( m ) * 2 )
@ -614,6 +668,7 @@ func mapToPairs(m map[string]string) []string {
return p
return p
}
}
// stringMapEqual checks the equality of two string maps
func stringMapEqual ( m1 , m2 map [ string ] string ) bool {
func stringMapEqual ( m1 , m2 map [ string ] string ) bool {
nil1 := m1 == nil
nil1 := m1 == nil
nil2 := m2 == nil
nil2 := m2 == nil
@ -627,3 +682,12 @@ func stringMapEqual(m1, m2 map[string]string) bool {
}
}
return true
return true
}
}
// newRequest is a helper function to create a new request with a method and url
func newRequest ( method , url string ) * http . Request {
req , err := http . NewRequest ( method , url , nil )
if err != nil {
panic ( err )
}
return req
}