go.sdls.io/sin@v0.0.9/pkg/sin/gin_test.go (about) 1 // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 // Use of this source code is governed by a MIT style 3 // license that can be found in the LICENSE file. 4 5 package sin 6 7 import ( 8 "reflect" 9 "strconv" 10 "sync/atomic" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func TestCreateEngine(t *testing.T) { 17 router := New() 18 assert.Equal(t, "/", router.basePath) 19 assert.Equal(t, router.engine, router) 20 assert.Empty(t, router.Handlers) 21 } 22 23 func TestAddRoute(t *testing.T) { 24 router := New() 25 router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}}) 26 27 assert.Len(t, router.trees, 1) 28 assert.NotNil(t, router.trees.get("GET")) 29 assert.Nil(t, router.trees.get("POST")) 30 31 router.addRoute("POST", "/", HandlersChain{func(_ *Context) {}}) 32 33 assert.Len(t, router.trees, 2) 34 assert.NotNil(t, router.trees.get("GET")) 35 assert.NotNil(t, router.trees.get("POST")) 36 37 router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}}) 38 assert.Len(t, router.trees, 2) 39 } 40 41 func TestAddRouteFails(t *testing.T) { 42 router := New() 43 assert.Panics(t, func() { router.addRoute("", "/", HandlersChain{func(_ *Context) {}}) }) 44 assert.Panics(t, func() { router.addRoute("GET", "a", HandlersChain{func(_ *Context) {}}) }) 45 assert.Panics(t, func() { router.addRoute("GET", "/", HandlersChain{}) }) 46 47 router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}}) 48 assert.Panics(t, func() { 49 router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}}) 50 }) 51 } 52 53 func TestNoRouteWithoutGlobalHandlers(t *testing.T) { 54 var middleware0 HandlerFunc = func(c *Context) {} 55 var middleware1 HandlerFunc = func(c *Context) {} 56 57 router := New() 58 59 router.NoRoute(middleware0) 60 assert.Nil(t, router.Handlers) 61 assert.Len(t, router.noRoute, 1) 62 assert.Len(t, router.allNoRoute, 1) 63 compareFunc(t, router.noRoute[0], middleware0) 64 compareFunc(t, router.allNoRoute[0], middleware0) 65 66 router.NoRoute(middleware1, middleware0) 67 assert.Len(t, router.noRoute, 2) 68 assert.Len(t, router.allNoRoute, 2) 69 compareFunc(t, router.noRoute[0], middleware1) 70 compareFunc(t, router.allNoRoute[0], middleware1) 71 compareFunc(t, router.noRoute[1], middleware0) 72 compareFunc(t, router.allNoRoute[1], middleware0) 73 } 74 75 func TestNoRouteWithGlobalHandlers(t *testing.T) { 76 var middleware0 HandlerFunc = func(c *Context) {} 77 var middleware1 HandlerFunc = func(c *Context) {} 78 var middleware2 HandlerFunc = func(c *Context) {} 79 80 router := New() 81 router.Use(middleware2) 82 83 router.NoRoute(middleware0) 84 assert.Len(t, router.allNoRoute, 2) 85 assert.Len(t, router.Handlers, 1) 86 assert.Len(t, router.noRoute, 1) 87 88 compareFunc(t, router.Handlers[0], middleware2) 89 compareFunc(t, router.noRoute[0], middleware0) 90 compareFunc(t, router.allNoRoute[0], middleware2) 91 compareFunc(t, router.allNoRoute[1], middleware0) 92 93 router.Use(middleware1) 94 assert.Len(t, router.allNoRoute, 3) 95 assert.Len(t, router.Handlers, 2) 96 assert.Len(t, router.noRoute, 1) 97 98 compareFunc(t, router.Handlers[0], middleware2) 99 compareFunc(t, router.Handlers[1], middleware1) 100 compareFunc(t, router.noRoute[0], middleware0) 101 compareFunc(t, router.allNoRoute[0], middleware2) 102 compareFunc(t, router.allNoRoute[1], middleware1) 103 compareFunc(t, router.allNoRoute[2], middleware0) 104 } 105 106 func TestNoMethodWithoutGlobalHandlers(t *testing.T) { 107 var middleware0 HandlerFunc = func(c *Context) {} 108 var middleware1 HandlerFunc = func(c *Context) {} 109 110 router := New() 111 112 router.NoMethod(middleware0) 113 assert.Empty(t, router.Handlers) 114 assert.Len(t, router.noMethod, 1) 115 assert.Len(t, router.allNoMethod, 1) 116 compareFunc(t, router.noMethod[0], middleware0) 117 compareFunc(t, router.allNoMethod[0], middleware0) 118 119 router.NoMethod(middleware1, middleware0) 120 assert.Len(t, router.noMethod, 2) 121 assert.Len(t, router.allNoMethod, 2) 122 compareFunc(t, router.noMethod[0], middleware1) 123 compareFunc(t, router.allNoMethod[0], middleware1) 124 compareFunc(t, router.noMethod[1], middleware0) 125 compareFunc(t, router.allNoMethod[1], middleware0) 126 } 127 128 func TestRebuild404Handlers(t *testing.T) { 129 } 130 131 func TestNoMethodWithGlobalHandlers(t *testing.T) { 132 var middleware0 HandlerFunc = func(c *Context) {} 133 var middleware1 HandlerFunc = func(c *Context) {} 134 var middleware2 HandlerFunc = func(c *Context) {} 135 136 router := New() 137 router.Use(middleware2) 138 139 router.NoMethod(middleware0) 140 assert.Len(t, router.allNoMethod, 2) 141 assert.Len(t, router.Handlers, 1) 142 assert.Len(t, router.noMethod, 1) 143 144 compareFunc(t, router.Handlers[0], middleware2) 145 compareFunc(t, router.noMethod[0], middleware0) 146 compareFunc(t, router.allNoMethod[0], middleware2) 147 compareFunc(t, router.allNoMethod[1], middleware0) 148 149 router.Use(middleware1) 150 assert.Len(t, router.allNoMethod, 3) 151 assert.Len(t, router.Handlers, 2) 152 assert.Len(t, router.noMethod, 1) 153 154 compareFunc(t, router.Handlers[0], middleware2) 155 compareFunc(t, router.Handlers[1], middleware1) 156 compareFunc(t, router.noMethod[0], middleware0) 157 compareFunc(t, router.allNoMethod[0], middleware2) 158 compareFunc(t, router.allNoMethod[1], middleware1) 159 compareFunc(t, router.allNoMethod[2], middleware0) 160 } 161 162 func compareFunc(t *testing.T, a, b interface{}) { 163 sf1 := reflect.ValueOf(a) 164 sf2 := reflect.ValueOf(b) 165 if sf1.Pointer() != sf2.Pointer() { 166 t.Error("different functions") 167 } 168 } 169 170 func TestListOfRoutes(t *testing.T) { 171 router := New() 172 router.GET("/favicon.ico", handlerTest1) 173 router.GET("/", handlerTest1) 174 group := router.Group("/users") 175 { 176 group.GET("/", handlerTest2) 177 group.GET("/:id", handlerTest1) 178 group.POST("/:id", handlerTest2) 179 } 180 181 list := router.Routes() 182 183 assert.Len(t, list, 5) 184 assertRoutePresent(t, list, RouteInfo{ 185 Method: "GET", 186 Path: "/favicon.ico", 187 Handler: "^(.*/vendor/)?go.sdls.io/sin/pkg/sin.handlerTest1$", 188 }) 189 assertRoutePresent(t, list, RouteInfo{ 190 Method: "GET", 191 Path: "/", 192 Handler: "^(.*/vendor/)?go.sdls.io/sin/pkg/sin.handlerTest1$", 193 }) 194 assertRoutePresent(t, list, RouteInfo{ 195 Method: "GET", 196 Path: "/users/", 197 Handler: "^(.*/vendor/)?go.sdls.io/sin/pkg/sin.handlerTest2$", 198 }) 199 assertRoutePresent(t, list, RouteInfo{ 200 Method: "GET", 201 Path: "/users/:id", 202 Handler: "^(.*/vendor/)?go.sdls.io/sin/pkg/sin.handlerTest1$", 203 }) 204 assertRoutePresent(t, list, RouteInfo{ 205 Method: "POST", 206 Path: "/users/:id", 207 Handler: "^(.*/vendor/)?go.sdls.io/sin/pkg/sin.handlerTest2$", 208 }) 209 } 210 211 func TestEngineHandleContext(t *testing.T) { 212 r := New() 213 r.GET("/", func(c *Context) { 214 c.Request.URL.Path = "/v2" 215 r.HandleContext(c) 216 }) 217 v2 := r.Group("/v2") 218 { 219 v2.GET("/", func(c *Context) {}) 220 } 221 222 assert.NotPanics(t, func() { 223 w := performRequest(r, "GET", "/") 224 assert.Equal(t, 404, w.Code) 225 }) 226 } 227 228 func TestEngineHandleContextManyReEntries(t *testing.T) { 229 expectValue := 10000 230 231 var handlerCounter, middlewareCounter int64 232 233 r := New() 234 r.Use(func(c *Context) { 235 atomic.AddInt64(&middlewareCounter, 1) 236 }) 237 r.GET("/:count", func(c *Context) { 238 countStr := c.Param("count") 239 count, err := strconv.Atoi(countStr) 240 assert.NoError(t, err) 241 242 n, err := c.Writer.Write([]byte(".")) 243 assert.NoError(t, err) 244 assert.Equal(t, 1, n) 245 246 switch { 247 case count > 0: 248 c.Request.URL.Path = "/" + strconv.Itoa(count-1) 249 r.HandleContext(c) 250 } 251 }, func(c *Context) { 252 atomic.AddInt64(&handlerCounter, 1) 253 }) 254 255 assert.NotPanics(t, func() { 256 w := performRequest(r, "GET", "/"+strconv.Itoa(expectValue-1)) // include 0 value 257 assert.Equal(t, 200, w.Code) 258 assert.Equal(t, expectValue, w.Body.Len()) 259 }) 260 261 assert.Equal(t, int64(expectValue), handlerCounter) 262 assert.Equal(t, int64(expectValue), middlewareCounter) 263 } 264 265 func assertRoutePresent(t *testing.T, gotRoutes RoutesInfo, wantRoute RouteInfo) { 266 for _, gotRoute := range gotRoutes { 267 if gotRoute.Path == wantRoute.Path && gotRoute.Method == wantRoute.Method { 268 assert.Regexp(t, wantRoute.Handler, gotRoute.Handler) 269 return 270 } 271 } 272 t.Errorf("route not found: %v", wantRoute) 273 } 274 275 func handlerTest1(_ *Context) {} 276 func handlerTest2(_ *Context) {}