github.com/tcncloud/wollemi@v0.8.1/adapters/logrus/logger_suite_test.go (about) 1 package logrus_test 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "math" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 15 "github.com/tcncloud/wollemi/adapters/logrus" 16 "github.com/tcncloud/wollemi/ports/logging" 17 ) 18 19 func NewLoggerSuite(t *testing.T) *LoggerSuite { 20 return &LoggerSuite{T: t} 21 } 22 23 type LoggerSuite struct { 24 *testing.T 25 stdout *bytes.Buffer 26 log *logrus.Logger 27 } 28 29 func (suite *LoggerSuite) It(name string, yield func(*LoggerSuite)) { 30 suite.Helper() 31 suite.Run(name, yield) 32 } 33 34 func (suite *LoggerSuite) Run(name string, yield func(*LoggerSuite)) { 35 suite.Helper() 36 suite.T.Run(name, func(t *testing.T) { 37 suite := NewLoggerSuite(t) 38 suite.Helper() 39 40 suite.stdout = bytes.NewBuffer(nil) 41 42 suite.log = logrus.NewLogger(suite.stdout) 43 suite.log.SetFormatter(&logging.JsonFormatter{}) 44 45 yield(suite) 46 }) 47 } 48 49 type Entry struct { 50 Level logging.Level 51 Msg string 52 Time time.Time 53 } 54 55 func (e *Entry) UnmarshalJSON(buf []byte) error { 56 var m map[string]string 57 58 err := json.Unmarshal(buf, &m) 59 if err != nil { 60 return err 61 } 62 63 if s, ok := m["level"]; ok { 64 e.Level, err = logging.ParseLevel(s) 65 if err != nil { 66 return fmt.Errorf("could not parse level: %v", err) 67 } 68 } 69 70 if s, ok := m["msg"]; ok { 71 e.Msg = s 72 } 73 74 if s, ok := m["time"]; ok { 75 e.Time, err = time.Parse(time.RFC3339, s) 76 if err != nil { 77 return fmt.Errorf("could not parse time: %v", err) 78 } 79 } 80 81 return nil 82 } 83 84 func (t *LoggerSuite) Decode(r io.Reader, entries ...interface{}) { 85 decoder := json.NewDecoder(r) 86 87 for _, entry := range entries { 88 require.NoError(t, decoder.Decode(entry)) 89 } 90 } 91 92 func (t *LoggerSuite) NowUnix() time.Time { 93 return time.Unix(time.Now().Unix(), 0) 94 } 95 96 func (t *LoggerSuite) BehavesLikeLogsMessage(run func(logging.Logger), lvl logging.Level, msg string) { 97 type T = LoggerSuite 98 99 t.Run(fmt.Sprintf("logs message with time at %s level", lvl), func(t *T) { 100 t.log.SetLevel(lvl) 101 102 min := t.NowUnix() 103 run(t.log) 104 max := t.NowUnix() 105 106 delta := time.Duration(math.Ceil(float64(max.Sub(min)) / 2.0)) 107 108 entry := &Entry{} 109 110 t.Decode(t.stdout, entry) 111 assert.Equal(t, lvl, entry.Level) 112 assert.Equal(t, msg, entry.Msg) 113 assert.WithinDuration(t, min.Add(delta), entry.Time, delta) 114 }) 115 116 t.Run(fmt.Sprintf("is not logged when log level less than %s", lvl), func(t *T) { 117 t.log.SetLevel(lvl - 1) 118 run(t.log) 119 assert.Empty(t, t.stdout.String()) 120 }) 121 }