mux: Add more tests
This commit is contained in:
parent
fb0d4d24bd
commit
b5c47a5ef0
220
mux_test.go
220
mux_test.go
@ -2,6 +2,7 @@ package gemini
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
@ -10,6 +11,221 @@ type nopHandler struct{}
|
||||
|
||||
func (*nopHandler) ServeGemini(context.Context, ResponseWriter, *Request) {}
|
||||
|
||||
type nopResponseWriter struct {
|
||||
Status Status
|
||||
Meta string
|
||||
}
|
||||
|
||||
func (w *nopResponseWriter) WriteHeader(status Status, meta string) {
|
||||
w.Status = status
|
||||
w.Meta = meta
|
||||
}
|
||||
|
||||
func (nopResponseWriter) SetMediaType(mediatype string) {}
|
||||
func (nopResponseWriter) Write(b []byte) (int, error) { return 0, io.EOF }
|
||||
func (nopResponseWriter) Flush() error { return nil }
|
||||
|
||||
func TestMux(t *testing.T) {
|
||||
type Test struct {
|
||||
URL string
|
||||
Pattern string
|
||||
Redirect string
|
||||
NotFound bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
Patterns []string
|
||||
Tests []Test
|
||||
}{
|
||||
{
|
||||
Patterns: []string{"/a", "/b/", "/b/c/d", "/b/c/d/"},
|
||||
Tests: []Test{
|
||||
{
|
||||
URL: "gemini://example.com",
|
||||
Redirect: "gemini://example.com/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/",
|
||||
NotFound: true,
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/c",
|
||||
NotFound: true,
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/a",
|
||||
Pattern: "/a",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/a/",
|
||||
NotFound: true,
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/b",
|
||||
Redirect: "gemini://example.com/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/b/",
|
||||
Pattern: "/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/b/c",
|
||||
Pattern: "/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/b/c/d",
|
||||
Pattern: "/b/c/d",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/b/c/d/e/",
|
||||
Pattern: "/b/c/d/",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Patterns: []string{
|
||||
"/", "/a", "/b/",
|
||||
"example.com", "example.com/a", "example.com/b/",
|
||||
"*.example.com", "*.example.com/a", "*.example.com/b/",
|
||||
},
|
||||
Tests: []Test{
|
||||
{
|
||||
URL: "gemini://example.net/",
|
||||
Pattern: "/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.net/a",
|
||||
Pattern: "/a",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.net/b",
|
||||
Redirect: "gemini://example.net/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.net/b/",
|
||||
Pattern: "/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/",
|
||||
Pattern: "example.com",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/b",
|
||||
Redirect: "gemini://example.com/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/b/",
|
||||
Pattern: "example.com/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://a.example.com/",
|
||||
Pattern: "*.example.com",
|
||||
},
|
||||
{
|
||||
URL: "gemini://b.example.com/a",
|
||||
Pattern: "*.example.com/a",
|
||||
},
|
||||
{
|
||||
URL: "gemini://c.example.com/b",
|
||||
Redirect: "gemini://c.example.com/b/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://d.example.com/b/",
|
||||
Pattern: "*.example.com/b/",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Patterns: []string{"example.net", "*.example.org"},
|
||||
Tests: []Test{
|
||||
{
|
||||
// The following redirect occurs as a result of cleaning
|
||||
// the path provided to the Mux. This happens even if there
|
||||
// are no matching handlers.
|
||||
URL: "gemini://example.com",
|
||||
Redirect: "gemini://example.com/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.com/",
|
||||
NotFound: true,
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.net",
|
||||
Redirect: "gemini://example.net/",
|
||||
},
|
||||
{
|
||||
URL: "gemini://example.org/",
|
||||
NotFound: true,
|
||||
},
|
||||
{
|
||||
URL: "gemini://gemini.example.org",
|
||||
Redirect: "gemini://gemini.example.org/",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
type handler struct {
|
||||
nopHandler
|
||||
Pattern string
|
||||
}
|
||||
|
||||
mux := &Mux{}
|
||||
for _, pattern := range test.Patterns {
|
||||
mux.Handle(pattern, &handler{
|
||||
Pattern: pattern,
|
||||
})
|
||||
}
|
||||
|
||||
for _, test := range test.Tests {
|
||||
u, err := url.Parse(test.URL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req := &Request{URL: u}
|
||||
|
||||
h := mux.Handler(req)
|
||||
|
||||
if h, ok := h.(*handler); ok {
|
||||
if h.Pattern != test.Pattern {
|
||||
t.Errorf("wrong pattern for %q: expected %q, got %q", test.URL, test.Pattern, h.Pattern)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Check redirects and NotFounds
|
||||
w := &nopResponseWriter{}
|
||||
h.ServeGemini(context.Background(), w, req)
|
||||
|
||||
switch w.Status {
|
||||
case StatusNotFound:
|
||||
if !test.NotFound {
|
||||
t.Errorf("expected pattern for %q, got NotFound", test.URL)
|
||||
}
|
||||
|
||||
case StatusPermanentRedirect:
|
||||
if test.Redirect == "" {
|
||||
t.Errorf("expected pattern for %q, got redirect to %q", test.URL, w.Meta)
|
||||
break
|
||||
}
|
||||
|
||||
res, err := url.Parse(test.Redirect)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if w.Meta != res.String() {
|
||||
t.Errorf("bad redirect for %q: expected %q, got %q", test.URL, res.String(), w.Meta)
|
||||
}
|
||||
|
||||
default:
|
||||
t.Errorf("unexpected response for %q: %d %s", test.URL, w.Status, w.Meta)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMuxMatch(t *testing.T) {
|
||||
type Match struct {
|
||||
URL string
|
||||
@ -115,12 +331,12 @@ func TestMuxMatch(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
for _, test := range tests {
|
||||
h := &nopHandler{}
|
||||
var mux Mux
|
||||
mux.Handle(test.Pattern, h)
|
||||
|
||||
for _, match := range tests[i].Matches {
|
||||
for _, match := range test.Matches {
|
||||
u, err := url.Parse(match.URL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
Loading…
Reference in New Issue
Block a user