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 5package gin 6 7import ( 8 "bytes" 9 "errors" 10 "html/template" 11 "io" 12 "log" 13 "os" 14 "runtime" 15 "sync" 16 "testing" 17 18 "github.com/stretchr/testify/assert" 19) 20 21// TODO 22// func debugRoute(httpMethod, absolutePath string, handlers HandlersChain) { 23// func debugPrint(format string, values ...interface{}) { 24 25func TestIsDebugging(t *testing.T) { 26 SetMode(DebugMode) 27 assert.True(t, IsDebugging()) 28 SetMode(ReleaseMode) 29 assert.False(t, IsDebugging()) 30 SetMode(TestMode) 31 assert.False(t, IsDebugging()) 32} 33 34func TestDebugPrint(t *testing.T) { 35 re := captureOutput(t, func() { 36 SetMode(DebugMode) 37 SetMode(ReleaseMode) 38 debugPrint("DEBUG this!") 39 SetMode(TestMode) 40 debugPrint("DEBUG this!") 41 SetMode(DebugMode) 42 debugPrint("these are %d %s", 2, "error messages") 43 SetMode(TestMode) 44 }) 45 assert.Equal(t, "[GIN-debug] these are 2 error messages\n", re) 46} 47 48func TestDebugPrintError(t *testing.T) { 49 re := captureOutput(t, func() { 50 SetMode(DebugMode) 51 debugPrintError(nil) 52 debugPrintError(errors.New("this is an error")) 53 SetMode(TestMode) 54 }) 55 assert.Equal(t, "[GIN-debug] [ERROR] this is an error\n", re) 56} 57 58func TestDebugPrintRoutes(t *testing.T) { 59 re := captureOutput(t, func() { 60 SetMode(DebugMode) 61 debugPrintRoute("GET", "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest}) 62 SetMode(TestMode) 63 }) 64 assert.Regexp(t, `^\[GIN-debug\] GET /path/to/route/:param --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, re) 65} 66 67func TestDebugPrintLoadTemplate(t *testing.T) { 68 re := captureOutput(t, func() { 69 SetMode(DebugMode) 70 templ := template.Must(template.New("").Delims("{[{", "}]}").ParseGlob("./testdata/template/hello.tmpl")) 71 debugPrintLoadTemplate(templ) 72 SetMode(TestMode) 73 }) 74 assert.Regexp(t, `^\[GIN-debug\] Loaded HTML Templates \(2\): \n(\t- \n|\t- hello\.tmpl\n){2}\n`, re) 75} 76 77func TestDebugPrintWARNINGSetHTMLTemplate(t *testing.T) { 78 re := captureOutput(t, func() { 79 SetMode(DebugMode) 80 debugPrintWARNINGSetHTMLTemplate() 81 SetMode(TestMode) 82 }) 83 assert.Equal(t, "[GIN-debug] [WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called\nat initialization. ie. before any route is registered or the router is listening in a socket:\n\n\trouter := gin.Default()\n\trouter.SetHTMLTemplate(template) // << good place\n\n", re) 84} 85 86func TestDebugPrintWARNINGDefault(t *testing.T) { 87 re := captureOutput(t, func() { 88 SetMode(DebugMode) 89 debugPrintWARNINGDefault() 90 SetMode(TestMode) 91 }) 92 m, e := getMinVer(runtime.Version()) 93 if e == nil && m <= ginSupportMinGoVer { 94 assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.11 or later and Go 1.12 will be required soon.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re) 95 } else { 96 assert.Equal(t, "[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re) 97 } 98} 99 100func TestDebugPrintWARNINGNew(t *testing.T) { 101 re := captureOutput(t, func() { 102 SetMode(DebugMode) 103 debugPrintWARNINGNew() 104 SetMode(TestMode) 105 }) 106 assert.Equal(t, "[GIN-debug] [WARNING] Running in \"debug\" mode. Switch to \"release\" mode in production.\n - using env:\texport GIN_MODE=release\n - using code:\tgin.SetMode(gin.ReleaseMode)\n\n", re) 107} 108 109func captureOutput(t *testing.T, f func()) string { 110 reader, writer, err := os.Pipe() 111 if err != nil { 112 panic(err) 113 } 114 defaultWriter := DefaultWriter 115 defaultErrorWriter := DefaultErrorWriter 116 defer func() { 117 DefaultWriter = defaultWriter 118 DefaultErrorWriter = defaultErrorWriter 119 log.SetOutput(os.Stderr) 120 }() 121 DefaultWriter = writer 122 DefaultErrorWriter = writer 123 log.SetOutput(writer) 124 out := make(chan string) 125 wg := new(sync.WaitGroup) 126 wg.Add(1) 127 go func() { 128 var buf bytes.Buffer 129 wg.Done() 130 _, err := io.Copy(&buf, reader) 131 assert.NoError(t, err) 132 out <- buf.String() 133 }() 134 wg.Wait() 135 f() 136 writer.Close() 137 return <-out 138} 139 140func TestGetMinVer(t *testing.T) { 141 var m uint64 142 var e error 143 _, e = getMinVer("go1") 144 assert.NotNil(t, e) 145 m, e = getMinVer("go1.1") 146 assert.Equal(t, uint64(1), m) 147 assert.Nil(t, e) 148 m, e = getMinVer("go1.1.1") 149 assert.Nil(t, e) 150 assert.Equal(t, uint64(1), m) 151 _, e = getMinVer("go1.1.1.1") 152 assert.NotNil(t, e) 153} 154