gin_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  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. package gin
  5. import (
  6. "crypto/tls"
  7. "fmt"
  8. "html/template"
  9. "io/ioutil"
  10. "net/http"
  11. "net/http/httptest"
  12. "reflect"
  13. "testing"
  14. "time"
  15. "github.com/stretchr/testify/assert"
  16. )
  17. func formatAsDate(t time.Time) string {
  18. year, month, day := t.Date()
  19. return fmt.Sprintf("%d/%02d/%02d", year, month, day)
  20. }
  21. func setupHTMLFiles(t *testing.T, mode string, tls bool, loadMethod func(*Engine)) *httptest.Server {
  22. SetMode(mode)
  23. router := New()
  24. router.Delims("{[{", "}]}")
  25. router.SetFuncMap(template.FuncMap{
  26. "formatAsDate": formatAsDate,
  27. })
  28. loadMethod(router)
  29. router.GET("/test", func(c *Context) {
  30. c.HTML(http.StatusOK, "hello.tmpl", map[string]string{"name": "world"})
  31. })
  32. router.GET("/raw", func(c *Context) {
  33. c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
  34. "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
  35. })
  36. })
  37. var ts *httptest.Server
  38. if tls {
  39. ts = httptest.NewTLSServer(router)
  40. } else {
  41. ts = httptest.NewServer(router)
  42. }
  43. return ts
  44. }
  45. func TestLoadHTMLGlobDebugMode(t *testing.T) {
  46. ts := setupHTMLFiles(
  47. t,
  48. DebugMode,
  49. false,
  50. func(router *Engine) {
  51. router.LoadHTMLGlob("./testdata/template/*")
  52. },
  53. )
  54. defer ts.Close()
  55. res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
  56. if err != nil {
  57. fmt.Println(err)
  58. }
  59. resp, _ := ioutil.ReadAll(res.Body)
  60. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  61. }
  62. func TestLoadHTMLGlobTestMode(t *testing.T) {
  63. ts := setupHTMLFiles(
  64. t,
  65. TestMode,
  66. false,
  67. func(router *Engine) {
  68. router.LoadHTMLGlob("./testdata/template/*")
  69. },
  70. )
  71. defer ts.Close()
  72. res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
  73. if err != nil {
  74. fmt.Println(err)
  75. }
  76. resp, _ := ioutil.ReadAll(res.Body)
  77. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  78. }
  79. func TestLoadHTMLGlobReleaseMode(t *testing.T) {
  80. ts := setupHTMLFiles(
  81. t,
  82. ReleaseMode,
  83. false,
  84. func(router *Engine) {
  85. router.LoadHTMLGlob("./testdata/template/*")
  86. },
  87. )
  88. defer ts.Close()
  89. res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
  90. if err != nil {
  91. fmt.Println(err)
  92. }
  93. resp, _ := ioutil.ReadAll(res.Body)
  94. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  95. }
  96. func TestLoadHTMLGlobUsingTLS(t *testing.T) {
  97. ts := setupHTMLFiles(
  98. t,
  99. DebugMode,
  100. true,
  101. func(router *Engine) {
  102. router.LoadHTMLGlob("./testdata/template/*")
  103. },
  104. )
  105. defer ts.Close()
  106. // Use InsecureSkipVerify for avoiding `x509: certificate signed by unknown authority` error
  107. tr := &http.Transport{
  108. TLSClientConfig: &tls.Config{
  109. InsecureSkipVerify: true,
  110. },
  111. }
  112. client := &http.Client{Transport: tr}
  113. res, err := client.Get(fmt.Sprintf("%s/test", ts.URL))
  114. if err != nil {
  115. fmt.Println(err)
  116. }
  117. resp, _ := ioutil.ReadAll(res.Body)
  118. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  119. }
  120. func TestLoadHTMLGlobFromFuncMap(t *testing.T) {
  121. ts := setupHTMLFiles(
  122. t,
  123. DebugMode,
  124. false,
  125. func(router *Engine) {
  126. router.LoadHTMLGlob("./testdata/template/*")
  127. },
  128. )
  129. defer ts.Close()
  130. res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL))
  131. if err != nil {
  132. fmt.Println(err)
  133. }
  134. resp, _ := ioutil.ReadAll(res.Body)
  135. assert.Equal(t, "Date: 2017/07/01\n", string(resp))
  136. }
  137. func init() {
  138. SetMode(TestMode)
  139. }
  140. func TestCreateEngine(t *testing.T) {
  141. router := New()
  142. assert.Equal(t, "/", router.basePath)
  143. assert.Equal(t, router.engine, router)
  144. assert.Empty(t, router.Handlers)
  145. }
  146. func TestLoadHTMLFilesTestMode(t *testing.T) {
  147. ts := setupHTMLFiles(
  148. t,
  149. TestMode,
  150. false,
  151. func(router *Engine) {
  152. router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl")
  153. },
  154. )
  155. defer ts.Close()
  156. res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
  157. if err != nil {
  158. fmt.Println(err)
  159. }
  160. resp, _ := ioutil.ReadAll(res.Body)
  161. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  162. }
  163. func TestLoadHTMLFilesDebugMode(t *testing.T) {
  164. ts := setupHTMLFiles(
  165. t,
  166. DebugMode,
  167. false,
  168. func(router *Engine) {
  169. router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl")
  170. },
  171. )
  172. defer ts.Close()
  173. res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
  174. if err != nil {
  175. fmt.Println(err)
  176. }
  177. resp, _ := ioutil.ReadAll(res.Body)
  178. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  179. }
  180. func TestLoadHTMLFilesReleaseMode(t *testing.T) {
  181. ts := setupHTMLFiles(
  182. t,
  183. ReleaseMode,
  184. false,
  185. func(router *Engine) {
  186. router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl")
  187. },
  188. )
  189. defer ts.Close()
  190. res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
  191. if err != nil {
  192. fmt.Println(err)
  193. }
  194. resp, _ := ioutil.ReadAll(res.Body)
  195. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  196. }
  197. func TestLoadHTMLFilesUsingTLS(t *testing.T) {
  198. ts := setupHTMLFiles(
  199. t,
  200. TestMode,
  201. true,
  202. func(router *Engine) {
  203. router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl")
  204. },
  205. )
  206. defer ts.Close()
  207. // Use InsecureSkipVerify for avoiding `x509: certificate signed by unknown authority` error
  208. tr := &http.Transport{
  209. TLSClientConfig: &tls.Config{
  210. InsecureSkipVerify: true,
  211. },
  212. }
  213. client := &http.Client{Transport: tr}
  214. res, err := client.Get(fmt.Sprintf("%s/test", ts.URL))
  215. if err != nil {
  216. fmt.Println(err)
  217. }
  218. resp, _ := ioutil.ReadAll(res.Body)
  219. assert.Equal(t, "<h1>Hello world</h1>", string(resp))
  220. }
  221. func TestLoadHTMLFilesFuncMap(t *testing.T) {
  222. ts := setupHTMLFiles(
  223. t,
  224. TestMode,
  225. false,
  226. func(router *Engine) {
  227. router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl")
  228. },
  229. )
  230. defer ts.Close()
  231. res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL))
  232. if err != nil {
  233. fmt.Println(err)
  234. }
  235. resp, _ := ioutil.ReadAll(res.Body)
  236. assert.Equal(t, "Date: 2017/07/01\n", string(resp))
  237. }
  238. func TestAddRoute(t *testing.T) {
  239. router := New()
  240. router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
  241. assert.Len(t, router.trees, 1)
  242. assert.NotNil(t, router.trees.get("GET"))
  243. assert.Nil(t, router.trees.get("POST"))
  244. router.addRoute("POST", "/", HandlersChain{func(_ *Context) {}})
  245. assert.Len(t, router.trees, 2)
  246. assert.NotNil(t, router.trees.get("GET"))
  247. assert.NotNil(t, router.trees.get("POST"))
  248. router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
  249. assert.Len(t, router.trees, 2)
  250. }
  251. func TestAddRouteFails(t *testing.T) {
  252. router := New()
  253. assert.Panics(t, func() { router.addRoute("", "/", HandlersChain{func(_ *Context) {}}) })
  254. assert.Panics(t, func() { router.addRoute("GET", "a", HandlersChain{func(_ *Context) {}}) })
  255. assert.Panics(t, func() { router.addRoute("GET", "/", HandlersChain{}) })
  256. router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
  257. assert.Panics(t, func() {
  258. router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}})
  259. })
  260. }
  261. func TestCreateDefaultRouter(t *testing.T) {
  262. router := Default()
  263. assert.Len(t, router.Handlers, 2)
  264. }
  265. func TestNoRouteWithoutGlobalHandlers(t *testing.T) {
  266. var middleware0 HandlerFunc = func(c *Context) {}
  267. var middleware1 HandlerFunc = func(c *Context) {}
  268. router := New()
  269. router.NoRoute(middleware0)
  270. assert.Nil(t, router.Handlers)
  271. assert.Len(t, router.noRoute, 1)
  272. assert.Len(t, router.allNoRoute, 1)
  273. compareFunc(t, router.noRoute[0], middleware0)
  274. compareFunc(t, router.allNoRoute[0], middleware0)
  275. router.NoRoute(middleware1, middleware0)
  276. assert.Len(t, router.noRoute, 2)
  277. assert.Len(t, router.allNoRoute, 2)
  278. compareFunc(t, router.noRoute[0], middleware1)
  279. compareFunc(t, router.allNoRoute[0], middleware1)
  280. compareFunc(t, router.noRoute[1], middleware0)
  281. compareFunc(t, router.allNoRoute[1], middleware0)
  282. }
  283. func TestNoRouteWithGlobalHandlers(t *testing.T) {
  284. var middleware0 HandlerFunc = func(c *Context) {}
  285. var middleware1 HandlerFunc = func(c *Context) {}
  286. var middleware2 HandlerFunc = func(c *Context) {}
  287. router := New()
  288. router.Use(middleware2)
  289. router.NoRoute(middleware0)
  290. assert.Len(t, router.allNoRoute, 2)
  291. assert.Len(t, router.Handlers, 1)
  292. assert.Len(t, router.noRoute, 1)
  293. compareFunc(t, router.Handlers[0], middleware2)
  294. compareFunc(t, router.noRoute[0], middleware0)
  295. compareFunc(t, router.allNoRoute[0], middleware2)
  296. compareFunc(t, router.allNoRoute[1], middleware0)
  297. router.Use(middleware1)
  298. assert.Len(t, router.allNoRoute, 3)
  299. assert.Len(t, router.Handlers, 2)
  300. assert.Len(t, router.noRoute, 1)
  301. compareFunc(t, router.Handlers[0], middleware2)
  302. compareFunc(t, router.Handlers[1], middleware1)
  303. compareFunc(t, router.noRoute[0], middleware0)
  304. compareFunc(t, router.allNoRoute[0], middleware2)
  305. compareFunc(t, router.allNoRoute[1], middleware1)
  306. compareFunc(t, router.allNoRoute[2], middleware0)
  307. }
  308. func TestNoMethodWithoutGlobalHandlers(t *testing.T) {
  309. var middleware0 HandlerFunc = func(c *Context) {}
  310. var middleware1 HandlerFunc = func(c *Context) {}
  311. router := New()
  312. router.NoMethod(middleware0)
  313. assert.Empty(t, router.Handlers)
  314. assert.Len(t, router.noMethod, 1)
  315. assert.Len(t, router.allNoMethod, 1)
  316. compareFunc(t, router.noMethod[0], middleware0)
  317. compareFunc(t, router.allNoMethod[0], middleware0)
  318. router.NoMethod(middleware1, middleware0)
  319. assert.Len(t, router.noMethod, 2)
  320. assert.Len(t, router.allNoMethod, 2)
  321. compareFunc(t, router.noMethod[0], middleware1)
  322. compareFunc(t, router.allNoMethod[0], middleware1)
  323. compareFunc(t, router.noMethod[1], middleware0)
  324. compareFunc(t, router.allNoMethod[1], middleware0)
  325. }
  326. func TestRebuild404Handlers(t *testing.T) {
  327. }
  328. func TestNoMethodWithGlobalHandlers(t *testing.T) {
  329. var middleware0 HandlerFunc = func(c *Context) {}
  330. var middleware1 HandlerFunc = func(c *Context) {}
  331. var middleware2 HandlerFunc = func(c *Context) {}
  332. router := New()
  333. router.Use(middleware2)
  334. router.NoMethod(middleware0)
  335. assert.Len(t, router.allNoMethod, 2)
  336. assert.Len(t, router.Handlers, 1)
  337. assert.Len(t, router.noMethod, 1)
  338. compareFunc(t, router.Handlers[0], middleware2)
  339. compareFunc(t, router.noMethod[0], middleware0)
  340. compareFunc(t, router.allNoMethod[0], middleware2)
  341. compareFunc(t, router.allNoMethod[1], middleware0)
  342. router.Use(middleware1)
  343. assert.Len(t, router.allNoMethod, 3)
  344. assert.Len(t, router.Handlers, 2)
  345. assert.Len(t, router.noMethod, 1)
  346. compareFunc(t, router.Handlers[0], middleware2)
  347. compareFunc(t, router.Handlers[1], middleware1)
  348. compareFunc(t, router.noMethod[0], middleware0)
  349. compareFunc(t, router.allNoMethod[0], middleware2)
  350. compareFunc(t, router.allNoMethod[1], middleware1)
  351. compareFunc(t, router.allNoMethod[2], middleware0)
  352. }
  353. func compareFunc(t *testing.T, a, b interface{}) {
  354. sf1 := reflect.ValueOf(a)
  355. sf2 := reflect.ValueOf(b)
  356. if sf1.Pointer() != sf2.Pointer() {
  357. t.Error("different functions")
  358. }
  359. }
  360. func TestListOfRoutes(t *testing.T) {
  361. router := New()
  362. router.GET("/favicon.ico", handlerTest1)
  363. router.GET("/", handlerTest1)
  364. group := router.Group("/users")
  365. {
  366. group.GET("/", handlerTest2)
  367. group.GET("/:id", handlerTest1)
  368. group.POST("/:id", handlerTest2)
  369. }
  370. router.Static("/static", ".")
  371. list := router.Routes()
  372. assert.Len(t, list, 7)
  373. assertRoutePresent(t, list, RouteInfo{
  374. Method: "GET",
  375. Path: "/favicon.ico",
  376. Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
  377. })
  378. assertRoutePresent(t, list, RouteInfo{
  379. Method: "GET",
  380. Path: "/",
  381. Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
  382. })
  383. assertRoutePresent(t, list, RouteInfo{
  384. Method: "GET",
  385. Path: "/users/",
  386. Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$",
  387. })
  388. assertRoutePresent(t, list, RouteInfo{
  389. Method: "GET",
  390. Path: "/users/:id",
  391. Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$",
  392. })
  393. assertRoutePresent(t, list, RouteInfo{
  394. Method: "POST",
  395. Path: "/users/:id",
  396. Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$",
  397. })
  398. }
  399. func assertRoutePresent(t *testing.T, gotRoutes RoutesInfo, wantRoute RouteInfo) {
  400. for _, gotRoute := range gotRoutes {
  401. if gotRoute.Path == wantRoute.Path && gotRoute.Method == wantRoute.Method {
  402. assert.Regexp(t, wantRoute.Handler, gotRoute.Handler)
  403. return
  404. }
  405. }
  406. t.Errorf("route not found: %v", wantRoute)
  407. }
  408. func handlerTest1(c *Context) {}
  409. func handlerTest2(c *Context) {}