summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--context_test.go64
-rw-r--r--engine.go (renamed from api.go)0
-rw-r--r--engine_test.go114
-rw-r--r--router_test.go79
-rw-r--r--test/main.go79
5 files changed, 257 insertions, 79 deletions
diff --git a/context_test.go b/context_test.go
new file mode 100644
index 0000000..560d9f5
--- /dev/null
+++ b/context_test.go
@@ -0,0 +1,64 @@
+package growel
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+)
+
+func TestContextPlain(t *testing.T) {
+ w := httptest.NewRecorder()
+ c := &Context{W: w}
+
+ c.Plain(201, "ok")
+
+ if w.Code != 201 {
+ t.Fatalf("expected 201, got %d", w.Code)
+ }
+ if ct := w.Header().Get("Content-Type"); !strings.Contains(ct, "text/plain") {
+ t.Fatalf("wrong content-type: %s", ct)
+ }
+ if w.Body.String() != "ok" {
+ t.Fatalf("wrong body: %s", w.Body.String())
+ }
+}
+
+func TestContextJSON(t *testing.T) {
+ w := httptest.NewRecorder()
+ c := &Context{W: w}
+
+ c.JSON(200, map[string]string{"x": "y"})
+
+ if w.Code != 200 {
+ t.Fatalf("expected 200, got %d", w.Code)
+ }
+ if ct := w.Header().Get("Content-Type"); !strings.Contains(ct, "application/json") {
+ t.Fatalf("unexpected content-type: %s", ct)
+ }
+ if !strings.Contains(w.Body.String(), `"x":"y"`) {
+ t.Fatalf("wrong json: %s", w.Body.String())
+ }
+}
+
+func TestContextError(t *testing.T) {
+ w := httptest.NewRecorder()
+ c := &Context{W: w}
+
+ c.Error(http.StatusBadRequest, "bad input")
+
+ if w.Code != 400 {
+ t.Fatalf("expected 400, got %d", w.Code)
+ }
+
+ body := w.Body.String()
+ if !strings.Contains(body, `"error":"Bad Request"`) {
+ t.Fatalf("missing human readable status: %s", body)
+ }
+ if !strings.Contains(body, `"message":"bad input"`) {
+ t.Fatalf("missing message: %s", body)
+ }
+ if !strings.Contains(body, `"status":"400"`) {
+ t.Fatalf("missing status field: %s", body)
+ }
+}
diff --git a/api.go b/engine.go
index e3c8ca8..e3c8ca8 100644
--- a/api.go
+++ b/engine.go
diff --git a/engine_test.go b/engine_test.go
new file mode 100644
index 0000000..12ec2c6
--- /dev/null
+++ b/engine_test.go
@@ -0,0 +1,114 @@
+package growel
+
+import (
+ "net/http/httptest"
+ "strings"
+ "testing"
+)
+
+func setupEngine() *Engine {
+ e := New()
+
+ e.GET("/", func(c *Context) {
+ c.Plain(200, "home")
+ })
+
+ e.GET("/hello", func(c *Context) {
+ c.JSON(200, map[string]string{"msg": "hi"})
+ })
+
+ e.GET("/user/:id", func(c *Context) {
+ c.JSON(200, map[string]string{"id": c.Params["id"]})
+ })
+
+ e.GET("/error", func(c *Context) {
+ c.BadRequest("bad")
+ })
+
+ return e
+}
+
+func TestEngineStaticRoute(t *testing.T) {
+ e := setupEngine()
+
+ req := httptest.NewRequest("GET", "/", nil)
+ w := httptest.NewRecorder()
+ e.ServeHTTP(w, req)
+
+ if w.Code != 200 {
+ t.Fatalf("expected 200, got %d", w.Code)
+ }
+
+ if w.Body.String() != "home" {
+ t.Fatalf("expected body 'home', got %q", w.Body.String())
+ }
+}
+
+func TestEngineJSONRoute(t *testing.T) {
+ e := setupEngine()
+
+ req := httptest.NewRequest("GET", "/hello", nil)
+ w := httptest.NewRecorder()
+ e.ServeHTTP(w, req)
+
+ if w.Code != 200 {
+ t.Fatalf("expected 200, got %d", w.Code)
+ }
+
+ if !strings.Contains(w.Body.String(), `"msg":"hi"`) {
+ t.Fatalf("unexpected json: %s", w.Body.String())
+ }
+}
+
+func TestEngineParamRoute(t *testing.T) {
+ e := setupEngine()
+
+ req := httptest.NewRequest("GET", "/user/99", nil)
+ w := httptest.NewRecorder()
+ e.ServeHTTP(w, req)
+
+ if w.Code != 200 {
+ t.Fatalf("expected 200, got %d", w.Code)
+ }
+
+ if !strings.Contains(w.Body.String(), `"id":"99"`) {
+ t.Fatalf("unexpected json: %s", w.Body.String())
+ }
+}
+
+func TestEngineNotFound(t *testing.T) {
+ e := setupEngine()
+
+ req := httptest.NewRequest("GET", "/doesnotexist", nil)
+ w := httptest.NewRecorder()
+ e.ServeHTTP(w, req)
+
+ if w.Code != 404 {
+ t.Fatalf("expected 404, got %d", w.Code)
+ }
+}
+
+func TestEngineErrorResponse(t *testing.T) {
+ e := setupEngine()
+
+ req := httptest.NewRequest("GET", "/error", nil)
+ w := httptest.NewRecorder()
+ e.ServeHTTP(w, req)
+
+ if w.Code != 400 {
+ t.Fatalf("expected 400, got %d", w.Code)
+ }
+
+ body := w.Body.String()
+ if !strings.Contains(body, `"error":"Bad Request"`) {
+ t.Fatalf("missing error text: %s", body)
+ }
+
+ if !strings.Contains(body, `"message":"bad"`) {
+ t.Fatalf("missing message: %s", body)
+ }
+
+ if !strings.Contains(body, `"status":"400"`) {
+ t.Fatalf("missing status code: %s", body)
+ }
+}
diff --git a/router_test.go b/router_test.go
new file mode 100644
index 0000000..24a2faa
--- /dev/null
+++ b/router_test.go
@@ -0,0 +1,79 @@
+package growel
+
+import (
+ "testing"
+)
+
+func dummy(c *Context) {}
+
+func TestRouterStaticMatch(t *testing.T) {
+ r := NewRouter()
+ r.Add("GET", "/hello", dummy)
+
+ h, params := r.Find("GET", "/hello")
+ if h == nil {
+ t.Fatal("expected handler, got nil")
+ }
+ if len(params) != 0 {
+ t.Fatalf("expected no params, got %v", params)
+ }
+}
+
+func TestRouterStaticNoMatch(t *testing.T) {
+ r := NewRouter()
+ r.Add("GET", "/hello", dummy)
+
+ h, _ := r.Find("GET", "/nothello")
+ if h != nil {
+ t.Fatal("expected nil handler, got non-nil")
+ }
+}
+
+func TestRouterParamMatch(t *testing.T) {
+ r := NewRouter()
+ r.Add("GET", "/user/:id", dummy)
+
+ h, params := r.Find("GET", "/user/42")
+ if h == nil {
+ t.Fatal("expected handler, got nil")
+ }
+ if params["id"] != "42" {
+ t.Fatalf("expected id=42, got %v", params)
+ }
+}
+
+func TestRouterParamMismatch(t *testing.T) {
+ r := NewRouter()
+ r.Add("GET", "/user/:id", dummy)
+
+ h, _ := r.Find("GET", "/user")
+ if h != nil {
+ t.Fatal("expected nil handler, got non-nil")
+ }
+}
+
+func TestRouterSplitPath(t *testing.T) {
+ r := NewRouter()
+
+ tests := []struct {
+ input string
+ want []string
+ }{
+ {"/", []string{""}},
+ {"/hello", []string{"hello"}},
+ {"/hello/world", []string{"hello", "world"}},
+ {"//hello//world//", []string{"hello", "", "world"}},
+ }
+
+ for _, tt := range tests {
+ got := r.splitPath(tt.input)
+ if len(got) != len(tt.want) {
+ t.Fatalf("splitPath(%q) length mismatch: got %v want %v", tt.input, got, tt.want)
+ }
+ for i := range got {
+ if got[i] != tt.want[i] {
+ t.Fatalf("splitPath(%q) mismatch: got %v want %v", tt.input, got, tt.want)
+ }
+ }
+ }
+}
diff --git a/test/main.go b/test/main.go
deleted file mode 100644
index 1f6c36b..0000000
--- a/test/main.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package main
-
-import (
- "github.com/bigcoke233/growel/v2"
- "strconv"
-)
-
-type User struct {
- ID int `json:"id"`
- Name string `json:"name"`
- Group string `json:"group"`
-}
-
-var Users = []User{
- {ID: 1, Name: "Alice Chen", Group: "admin"},
- {ID: 2, Name: "Bob Wu", Group: "admin"},
-
- {ID: 3, Name: "Cynthia Lin", Group: "staff"},
- {ID: 4, Name: "Daniel Zhao", Group: "staff"},
- {ID: 5, Name: "Emma Huang", Group: "staff"},
-
- {ID: 6, Name: "Felix Sun", Group: "editor"},
- {ID: 7, Name: "Grace Liu", Group: "editor"},
-
- {ID: 8, Name: "Henry Qiu", Group: "guest"},
- {ID: 9, Name: "Ivy Xu", Group: "guest"},
- {ID: 10, Name: "Jack Ma", Group: "guest"},
-
- {ID: 11, Name: "Karen He", Group: "beta"},
- {ID: 12, Name: "Leo Fang", Group: "beta"},
-
- {ID: 13, Name: "Mia Tang", Group: "test"},
- {ID: 14, Name: "Noah Jin", Group: "test"},
- {ID: 15, Name: "Olivia Ding", Group: "test"},
-
- {ID: 16, Name: "Peter Yan", Group: "ops"},
- {ID: 17, Name: "Queena Zhou", Group: "ops"},
- {ID: 18, Name: "Ryan Li", Group: "ops"},
-
- {ID: 19, Name: "Sophia Wang", Group: "support"},
- {ID: 20, Name: "Tony Du", Group: "support"},
-}
-
-func main() {
- api := growel.New()
-
- api.GET("/", func(c *growel.Context) {
- c.Plain(200, "This is home.")
- })
-
- api.GET("/hello", func(c *growel.Context) {
- c.JSON(200, map[string]string{
- "message": "Hello Growel!",
- })
- })
-
- api.GET("/user/", func(c *growel.Context) {
- c.JSON(200, Users)
- })
-
- api.GET("/user/:uid", func(c *growel.Context) {
- uid, err := strconv.Atoi(c.Params["uid"])
- if err != nil {
- c.BadRequest("Invalid user ID")
- return
- }
-
- for _, user := range Users {
- if user.ID == uid {
- c.JSON(200, user)
- return
- }
- }
-
- c.NotFound("User not found")
- })
-
- api.Start(":8080")
-}