package router_test import ( "bufio" "os" "strings" "testing" "git.akyoto.dev/go/assert" "git.akyoto.dev/go/router" ) type route struct { method string path string } func TestHello(t *testing.T) { router := router.New[string]() router.Add("GET", "/hello", "Hello") router.Add("GET", "/world", "World") data, params := router.Lookup("GET", "/hello") assert.Equal(t, len(params), 0) assert.Equal(t, data, "Hello") data, params = router.Lookup("GET", "/world") assert.Equal(t, len(params), 0) assert.Equal(t, data, "World") data, params = router.Lookup("GET", "/404") assert.Equal(t, len(params), 0) assert.Equal(t, data, "") } func TestParam(t *testing.T) { router := router.New[string]() router.Add("GET", "/blog/:slug", "Blog post") router.Add("GET", "/blog/:slug/comments/:id", "Comment") data, params := router.Lookup("GET", "/blog/hello-world") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "slug") assert.Equal(t, params[0].Value, "hello-world") assert.Equal(t, data, "Blog post") data, params = router.Lookup("GET", "/blog/hello-world/comments/123") assert.Equal(t, len(params), 2) assert.Equal(t, params[0].Key, "slug") 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) { router := router.New[string]() router.Add("GET", "/", "Front page") router.Add("GET", "/:slug", "Blog post") router.Add("GET", "/users/:id", "Parameter") router.Add("GET", "/images/*path", "Wildcard") data, params := router.Lookup("GET", "/") assert.Equal(t, len(params), 0) assert.Equal(t, data, "Front page") data, params = router.Lookup("GET", "/blog-post") assert.Equal(t, len(params), 1) assert.Equal(t, params[0].Key, "slug") assert.Equal(t, params[0].Value, "blog-post") assert.Equal(t, data, "Blog post") data, params = router.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 = router.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 TestGitHub(t *testing.T) { tree := router.New[string]() routes := loadRoutes("testdata/github.txt") for _, route := range routes { tree.Add(route.method, route.path, "octocat") } for _, route := range routes { data, _ := tree.Lookup(route.method, route.path) assert.Equal(t, data, "octocat") } } func loadRoutes(fileName string) []route { var routes []route for line := range linesInFile(fileName) { parts := strings.Split(line, " ") routes = append(routes, route{ method: parts[0], path: parts[1], }) } return routes } func linesInFile(fileName string) <-chan string { lines := make(chan string) go func() { defer close(lines) file, err := os.Open(fileName) if err != nil { return } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { lines <- strings.TrimSpace(scanner.Text()) } }() return lines }