github.com/jxskiss/gopkg@v0.17.3/easy/log_test.go (about) 1 package easy 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "log" 8 "math/rand" 9 "regexp" 10 "strings" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 15 "github.com/jxskiss/gopkg/ptr" 16 ) 17 18 type simple struct { 19 A string 20 } 21 22 type comptyp struct { 23 I32 int32 24 I32_p *int32 25 26 I64 int64 27 I64_p *int64 28 29 Str string 30 Str_p *string 31 32 Simple simple 33 Simple_p *simple 34 } 35 36 func TestCaller(t *testing.T) { 37 name, file, line := Caller(0) 38 assert.Equal(t, "easy.TestCaller", name) 39 assert.Equal(t, "easy/log_test.go", file) 40 assert.Equal(t, 37, line) 41 } 42 43 func TestJSON(t *testing.T) { 44 tests := []map[string]interface{}{ 45 { 46 "value": 123, 47 "want": "123", 48 }, 49 { 50 "value": "456", 51 "want": `"456"`, 52 }, 53 { 54 "value": simple{"ABC"}, 55 "want": `{"A":"ABC"}`, 56 }, 57 { 58 "value": "<html></html>", 59 "want": `"<html></html>"`, 60 }, 61 } 62 for _, test := range tests { 63 x := JSON(test["value"]) 64 assert.Equal(t, test["want"], x) 65 } 66 } 67 68 func TestLogfmt(t *testing.T) { 69 tests := []map[string]interface{}{ 70 { 71 "value": 123, 72 "want": "123", 73 }, 74 { 75 "value": (*string)(nil), 76 "want": "null", 77 }, 78 { 79 "value": comptyp{ 80 I32: 32, 81 I32_p: ptr.Int32(32), 82 I64: 64, 83 I64_p: nil, 84 Str: "str", 85 Str_p: ptr.String("str with space"), 86 Simple: simple{A: "simple.A"}, 87 Simple_p: nil, 88 }, 89 "want": `i32=32 i32_p=32 i64=64 str=str str_p="str with space"`, 90 }, 91 { 92 "value": map[string]interface{}{ 93 "a": 1234, 94 "b": "bcde", 95 "c": 123.456, 96 "d": simple{A: "simple.A"}, 97 "e": nil, 98 "f": []byte("I'm bytes"), 99 }, 100 "want": `a=1234 b=bcde c=123.456 f="I'm bytes"`, 101 }, 102 } 103 for _, test := range tests { 104 got := Logfmt(test["value"]) 105 assert.Equal(t, test["want"], got) 106 } 107 } 108 109 var prettyTestWant = strings.TrimSpace(` 110 { 111 "1": 123, 112 "b": "<html>" 113 }`) 114 115 func TestPretty(t *testing.T) { 116 test := map[string]interface{}{ 117 "1": 123, 118 "b": "<html>", 119 } 120 jsonString := JSON(test) 121 assert.Equal(t, `{"1":123,"b":"<html>"}`, jsonString) 122 123 got1 := Pretty(test) 124 assert.Equal(t, prettyTestWant, got1) 125 126 got2 := Pretty(jsonString) 127 assert.Equal(t, prettyTestWant, got2) 128 129 test3 := []byte("<fff> not a json object") 130 got3 := Pretty(test3) 131 assert.Equal(t, string(test3), got3) 132 133 test4 := make([]byte, 16) 134 rand.Read(test4) 135 got4 := Pretty(test4) 136 assert.Equal(t, "<pretty: non-printable bytes>", got4) 137 } 138 139 func TestCopyStdout(t *testing.T) { 140 msg := "test CopyStdout" 141 got, _ := CopyStdout(func() { 142 fmt.Println(msg) 143 }) 144 assert.Contains(t, string(got), msg) 145 } 146 147 func TestCopyStdLog(t *testing.T) { 148 msg := "test CopyStdLog" 149 got := CopyStdLog(func() { 150 log.Println(msg) 151 }) 152 assert.Contains(t, string(got), msg) 153 } 154 155 func TestDEBUG_bare_func(t *testing.T) { 156 // test func() 157 configTestLog(true, nil, nil) 158 msg := "test DEBUG_bare_func" 159 got := CopyStdLog(func() { 160 DEBUG(func() { 161 log.Println(msg, 1, 2, 3) 162 }) 163 }) 164 assert.Contains(t, string(got), msg) 165 assert.Contains(t, string(got), "1 2 3") 166 } 167 168 func TestDEBUG_logger_interface(t *testing.T) { 169 logbuf := bytes.NewBuffer(nil) 170 logger := &bufLogger{buf: logbuf} 171 172 // test logger interface 173 configTestLog(true, nil, nil) 174 msg := "test DEBUG_logger_interface" 175 DEBUG(logger, msg, 1, 2, 3) 176 got := logbuf.String() 177 assert.Contains(t, got, msg) 178 assert.Contains(t, got, "1 2 3") 179 } 180 181 func TestDEBUG_logger_func(t *testing.T) { 182 // test logger function 183 configTestLog(true, nil, nil) 184 logger := func() stdLogger { 185 return stdLogger{} 186 } 187 msg := "test DEBUG_logger_func" 188 got := CopyStdLog(func() { 189 DEBUG(logger, msg, 1, 2, 3) 190 }) 191 assert.Contains(t, string(got), msg) 192 assert.Contains(t, string(got), "1 2 3") 193 } 194 195 func TestDEBUG_print_func(t *testing.T) { 196 // test print function 197 configTestLog(true, nil, nil) 198 msg := "test DEBUG_print_func" 199 prefix := "PREFIX: " 200 logger := func(format string, args ...interface{}) { 201 format = prefix + format 202 log.Printf(format, args...) 203 } 204 got := CopyStdLog(func() { 205 DEBUG(logger, msg, 1, 2, 3) 206 }) 207 assert.Contains(t, string(got), prefix) 208 assert.Contains(t, string(got), msg) 209 assert.Contains(t, string(got), "1 2 3") 210 } 211 212 func TestDEBUG_ctx_logger(t *testing.T) { 213 logbuf := bytes.NewBuffer(nil) 214 ctx := context.WithValue(context.Background(), "TEST_LOGGER", &bufLogger{buf: logbuf}) 215 getCtxLogger := func(ctx context.Context) ErrDebugLogger { 216 return ctx.Value("TEST_LOGGER").(*bufLogger) 217 } 218 219 // test ctx logger 220 configTestLog(true, nil, getCtxLogger) 221 msg := "test DEBUG_ctx_logger" 222 DEBUG(ctx, msg, 1, 2, 3) 223 got := logbuf.String() 224 assert.Contains(t, got, msg) 225 assert.Contains(t, got, "1 2 3") 226 } 227 228 func TestDEBUG_simple(t *testing.T) { 229 configTestLog(true, nil, nil) 230 231 // test format 232 got1 := CopyStdLog(func() { 233 DEBUG("test DEBUG_simple a=%v b=%v c=%v", 1, 2, 3) 234 }) 235 want1 := "test DEBUG_simple a=1 b=2 c=3" 236 assert.Contains(t, string(got1), want1) 237 238 // raw params 239 got2 := CopyStdLog(func() { 240 DEBUG("test DEBUG_simple a=", 1, "b=", 2, "c=", 3) 241 }) 242 want2 := "test DEBUG_simple a= 1 b= 2 c= 3" 243 assert.Contains(t, string(got2), want2) 244 } 245 246 func TestDEBUG_empty(t *testing.T) { 247 configTestLog(true, nil, nil) 248 got := CopyStdLog(func() { DEBUG() }) 249 want := regexp.MustCompile(`easy/log_test.go#L\d+ - easy.TestDEBUG_empty`) 250 assert.Regexp(t, want, string(got)) 251 } 252 253 func TestDEBUGSkip(t *testing.T) { 254 configTestLog(true, nil, nil) 255 256 got := CopyStdLog(func() { DEBUGWrap() }) 257 want := regexp.MustCompile(`easy/log_test.go#L\d+ - easy.TestDEBUGSkip`) 258 assert.Regexp(t, want, string(got)) 259 260 got = CopyStdLog(func() { DEBUGWrapSkip2() }) 261 want = regexp.MustCompile(`easy/log_test.go#L\d+ - easy.TestDEBUGSkip`) 262 assert.Regexp(t, want, string(got)) 263 } 264 265 func TestConfigLog(t *testing.T) { 266 defaultLogger := &bufLogger{} 267 getCtxLogger := func(ctx context.Context) ErrDebugLogger { 268 return ctx.Value("TEST_LOGGER").(*bufLogger) 269 } 270 configTestLog(true, defaultLogger, getCtxLogger) 271 } 272 273 type bufLogger struct { 274 buf *bytes.Buffer 275 } 276 277 func (p *bufLogger) Debugf(format string, args ...interface{}) { 278 if p.buf == nil { 279 p.buf = bytes.NewBuffer(nil) 280 } 281 fmt.Fprintf(p.buf, format, args...) 282 } 283 284 func (p *bufLogger) Errorf(format string, args ...interface{}) { 285 if p.buf == nil { 286 p.buf = bytes.NewBuffer(nil) 287 } 288 fmt.Fprintf(p.buf, format, args...) 289 } 290 291 func DEBUGWrap(args ...interface{}) { 292 DEBUGSkip(1, args...) 293 } 294 295 func DEBUGWrapSkip2(args ...interface{}) { 296 skip2 := func(args ...interface{}) { 297 DEBUGSkip(2, args...) 298 } 299 skip2(args...) 300 } 301 302 func configTestLog( 303 enableDebug bool, 304 defaultLogger ErrDebugLogger, 305 ctxFunc func(ctx context.Context) ErrDebugLogger, 306 ) { 307 ConfigLog(LogCfg{ 308 EnableDebug: func() bool { return enableDebug }, 309 Logger: func() ErrDebugLogger { return defaultLogger }, 310 CtxLogger: ctxFunc, 311 }) 312 }