feat: replace debug log with fmt package. (#1560)

This commit is contained in:
Bo-Yi Wu 2018-09-19 13:57:00 +08:00 committed by GitHub
parent b27b7026c7
commit 07f1bf0e63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 74 deletions

View File

@ -784,14 +784,14 @@ func TestContextRenderHTML2(t *testing.T) {
router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}}) router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
assert.Len(t, router.trees, 1) assert.Len(t, router.trees, 1)
var b bytes.Buffer
setup(&b)
defer teardown()
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`)) templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
router.SetHTMLTemplate(templ) re := captureOutput(func() {
SetMode(DebugMode)
router.SetHTMLTemplate(templ)
SetMode(TestMode)
})
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", b.String()) 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)
c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"}) c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"})

View File

@ -6,14 +6,10 @@ package gin
import ( import (
"bytes" "bytes"
"fmt"
"html/template" "html/template"
"log"
) )
func init() {
log.SetFlags(0)
}
// IsDebugging returns true if the framework is running in debug mode. // IsDebugging returns true if the framework is running in debug mode.
// Use SetMode(gin.ReleaseMode) to disable debug mode. // Use SetMode(gin.ReleaseMode) to disable debug mode.
func IsDebugging() bool { func IsDebugging() bool {
@ -48,7 +44,7 @@ func debugPrintLoadTemplate(tmpl *template.Template) {
func debugPrint(format string, values ...interface{}) { func debugPrint(format string, values ...interface{}) {
if IsDebugging() { if IsDebugging() {
log.Printf("[GIN-debug] "+format, values...) fmt.Printf("[GIN-debug] "+format, values...)
} }
} }

View File

@ -11,6 +11,7 @@ import (
"io" "io"
"log" "log"
"os" "os"
"sync"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -30,86 +31,101 @@ func TestIsDebugging(t *testing.T) {
} }
func TestDebugPrint(t *testing.T) { func TestDebugPrint(t *testing.T) {
var w bytes.Buffer re := captureOutput(func() {
setup(&w) SetMode(DebugMode)
defer teardown() SetMode(ReleaseMode)
debugPrint("DEBUG this!")
SetMode(ReleaseMode) SetMode(TestMode)
debugPrint("DEBUG this!") debugPrint("DEBUG this!")
SetMode(TestMode) SetMode(DebugMode)
debugPrint("DEBUG this!") debugPrint("these are %d %s\n", 2, "error messages")
assert.Empty(t, w.String()) SetMode(TestMode)
})
SetMode(DebugMode) assert.Equal(t, "[GIN-debug] these are 2 error messages\n", re)
debugPrint("these are %d %s\n", 2, "error messages")
assert.Equal(t, "[GIN-debug] these are 2 error messages\n", w.String())
} }
func TestDebugPrintError(t *testing.T) { func TestDebugPrintError(t *testing.T) {
var w bytes.Buffer re := captureOutput(func() {
setup(&w) SetMode(DebugMode)
defer teardown() debugPrintError(nil)
debugPrintError(errors.New("this is an error"))
SetMode(DebugMode) SetMode(TestMode)
debugPrintError(nil) })
assert.Empty(t, w.String()) assert.Equal(t, "[GIN-debug] [ERROR] this is an error\n", re)
debugPrintError(errors.New("this is an error"))
assert.Equal(t, "[GIN-debug] [ERROR] this is an error\n", w.String())
} }
func TestDebugPrintRoutes(t *testing.T) { func TestDebugPrintRoutes(t *testing.T) {
var w bytes.Buffer re := captureOutput(func() {
setup(&w) SetMode(DebugMode)
defer teardown() debugPrintRoute("GET", "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest})
SetMode(TestMode)
debugPrintRoute("GET", "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest}) })
assert.Regexp(t, `^\[GIN-debug\] GET /path/to/route/:param --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, w.String()) assert.Regexp(t, `^\[GIN-debug\] GET /path/to/route/:param --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, re)
} }
func TestDebugPrintLoadTemplate(t *testing.T) { func TestDebugPrintLoadTemplate(t *testing.T) {
var w bytes.Buffer re := captureOutput(func() {
setup(&w) SetMode(DebugMode)
defer teardown() templ := template.Must(template.New("").Delims("{[{", "}]}").ParseGlob("./testdata/template/hello.tmpl"))
debugPrintLoadTemplate(templ)
templ := template.Must(template.New("").Delims("{[{", "}]}").ParseGlob("./testdata/template/hello.tmpl")) SetMode(TestMode)
debugPrintLoadTemplate(templ) })
assert.Regexp(t, `^\[GIN-debug\] Loaded HTML Templates \(2\): \n(\t- \n|\t- hello\.tmpl\n){2}\n`, w.String()) assert.Regexp(t, `^\[GIN-debug\] Loaded HTML Templates \(2\): \n(\t- \n|\t- hello\.tmpl\n){2}\n`, re)
} }
func TestDebugPrintWARNINGSetHTMLTemplate(t *testing.T) { func TestDebugPrintWARNINGSetHTMLTemplate(t *testing.T) {
var w bytes.Buffer re := captureOutput(func() {
setup(&w) SetMode(DebugMode)
defer teardown() debugPrintWARNINGSetHTMLTemplate()
SetMode(TestMode)
debugPrintWARNINGSetHTMLTemplate() })
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", w.String()) 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)
} }
func TestDebugPrintWARNINGDefault(t *testing.T) { func TestDebugPrintWARNINGDefault(t *testing.T) {
var w bytes.Buffer re := captureOutput(func() {
setup(&w) SetMode(DebugMode)
defer teardown() debugPrintWARNINGDefault()
SetMode(TestMode)
debugPrintWARNINGDefault() })
assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", w.String()) assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re)
} }
func TestDebugPrintWARNINGNew(t *testing.T) { func TestDebugPrintWARNINGNew(t *testing.T) {
var w bytes.Buffer re := captureOutput(func() {
setup(&w) SetMode(DebugMode)
defer teardown() debugPrintWARNINGNew()
SetMode(TestMode)
debugPrintWARNINGNew() })
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", w.String()) 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)
} }
func setup(w io.Writer) { func captureOutput(f func()) string {
SetMode(DebugMode) reader, writer, err := os.Pipe()
log.SetOutput(w) if err != nil {
} panic(err)
}
func teardown() { stdout := os.Stdout
SetMode(TestMode) stderr := os.Stderr
log.SetOutput(os.Stdout) defer func() {
os.Stdout = stdout
os.Stderr = stderr
log.SetOutput(os.Stderr)
}()
os.Stdout = writer
os.Stderr = writer
log.SetOutput(writer)
out := make(chan string)
wg := new(sync.WaitGroup)
wg.Add(1)
go func() {
var buf bytes.Buffer
wg.Done()
io.Copy(&buf, reader)
out <- buf.String()
}()
wg.Wait()
f()
writer.Close()
return <-out
} }