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