package router_test import ( "testing" "git.akyoto.dev/go/assert" "git.akyoto.dev/go/router" ) func TestStatic(t *testing.T) { r := router.New[string]() r.Add("GET", "/hello", "Hello") r.Add("GET", "/world", "World") data, params := r.Lookup("GET", "/hello") assert.Equal(t, len(params), 0) assert.Equal(t, data, "Hello") data, params = r.Lookup("GET", "/world") assert.Equal(t, len(params), 0) assert.Equal(t, data, "World") notFound := []string{ "", "?", "/404", "/hell", "/hall", "/helloo", } for _, path := range notFound { data, params = r.Lookup("GET", path) assert.Equal(t, len(params), 0) assert.Equal(t, data, "") } } func TestParameter(t *testing.T) { r := router.New[string]() r.Add("GET", "/blog/:post", "Blog post") r.Add("GET", "/blog/:post/comments/:id", "Comment") data, params := r.Lookup("GET", "/blog/hello-world") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "post") assert.Equal(t, params[0].Value, "hello-world") assert.Equal(t, data, "Blog post") data, params = r.Lookup("GET", "/blog/hello-world/comments/123") assert.Equal(t, len(params), 2) assert.Equal(t, params[0].Key, "post") assert.Equal(t, params[0].Value, "hello-world") assert.Equal(t, params[1].Key, "id") assert.Equal(t, params[1].Value, "123") assert.Equal(t, data, "Comment") } func TestWildcard(t *testing.T) { r := router.New[string]() r.Add("GET", "/", "Front page") r.Add("GET", "/:post", "Blog post") r.Add("GET", "/users/:id", "Parameter") r.Add("GET", "/images/static", "Static") r.Add("GET", "/images/*path", "Wildcard") data, params := r.Lookup("GET", "/") assert.Equal(t, len(params), 0) assert.Equal(t, data, "Front page") data, params = r.Lookup("GET", "/blog-post") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "post") assert.Equal(t, params[0].Value, "blog-post") assert.Equal(t, data, "Blog post") data, params = r.Lookup("GET", "/users/42") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "id") assert.Equal(t, params[0].Value, "42") assert.Equal(t, data, "Parameter") data, params = r.Lookup("GET", "/images/static") assert.Equal(t, len(params), 0) assert.Equal(t, data, "Static") data, params = r.Lookup("GET", "/images/ste") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "path") assert.Equal(t, params[0].Value, "ste") assert.Equal(t, data, "Wildcard") data, params = r.Lookup("GET", "/images/sta") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "path") assert.Equal(t, params[0].Value, "sta") assert.Equal(t, data, "Wildcard") data, params = r.Lookup("GET", "/images/favicon/256.png") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "path") assert.Equal(t, params[0].Value, "favicon/256.png") assert.Equal(t, data, "Wildcard") } func TestMethods(t *testing.T) { methods := []string{ "GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "CONNECT", "TRACE", "OPTIONS", } r := router.New[string]() for _, method := range methods { r.Add(method, "/", method) } for _, method := range methods { data, _ := r.Lookup(method, "/") assert.Equal(t, data, method) } } func TestGitHub(t *testing.T) { routes := loadRoutes("testdata/github.txt") r := router.New[string]() for _, route := range routes { r.Add(route.method, route.path, "octocat") } for _, route := range routes { data, _ := r.Lookup(route.method, route.path) assert.Equal(t, data, "octocat") data = r.LookupNoAlloc(route.method, route.path, func(string, string) {}) assert.Equal(t, data, "octocat") } } func TestOverwrite(t *testing.T) { r := router.New[string]() r.Add("GET", "/", "1") r.Add("GET", "/", "2") r.Add("GET", "/", "3") r.Add("GET", "/", "4") r.Add("GET", "/", "5") data, params := r.Lookup("GET", "/") assert.Equal(t, len(params), 0) assert.Equal(t, data, "5") } func TestMemoryUsage(t *testing.T) { escape := func(a any) {} result := testing.Benchmark(func(b *testing.B) { r := router.New[string]() escape(r) }) t.Logf("%d bytes", result.MemBytes) }