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) {}