mirror of
https://github.com/fluffle/goirc
synced 2025-07-12 08:11:17 +00:00
Rewrite logging package for great justice.
Allowing people to use the static functions to log things makes testing hard, so I've removed them. I've also rewritten things to allow logging different levels to separate files.
This commit is contained in:
parent
7be7e79c78
commit
c769723596
2 changed files with 210 additions and 96 deletions
|
@ -2,9 +2,22 @@ package logging
|
|||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Note: the below is deliberately PLACED AT THE TOP OF THIS FILE because
|
||||
// it is fragile. It ensures the right file:line is logged. Sorry!
|
||||
func TestLogCorrectLineNumbers(t *testing.T) {
|
||||
l, m := setUp()
|
||||
l.Log(Error, "Error!")
|
||||
if s := string(m[Error].written); s[20:] != "log_test.go:13: ERROR Error!\n" {
|
||||
t.Errorf("Error incorrectly logged (check line numbers!)")
|
||||
}
|
||||
}
|
||||
|
||||
type writerMap map[LogLevel]*mockWriter
|
||||
|
||||
type mockWriter struct {
|
||||
written []byte
|
||||
}
|
||||
|
@ -14,19 +27,79 @@ func (w *mockWriter) Write(p []byte) (n int, err os.Error) {
|
|||
return len(p), nil
|
||||
}
|
||||
|
||||
func TestDefaultLogging(t *testing.T) {
|
||||
w := &mockWriter{make([]byte, 0)}
|
||||
l := New(w, LogError, false)
|
||||
l.Log(4, "Nothing should be logged yet")
|
||||
l.Log(LogDebug, "or yet...")
|
||||
l.Log(LogWarn, "or yet!")
|
||||
if len(w.written) > 0 {
|
||||
t.Errorf("Unexpected low-level logging output.")
|
||||
func (w *mockWriter) reset() {
|
||||
w.written = w.written[:0]
|
||||
}
|
||||
|
||||
func setUp() (*logger, writerMap) {
|
||||
wMap := writerMap{
|
||||
Debug: &mockWriter{make([]byte, 0)},
|
||||
Info: &mockWriter{make([]byte, 0)},
|
||||
Warn: &mockWriter{make([]byte, 0)},
|
||||
Error: &mockWriter{make([]byte, 0)},
|
||||
Fatal: &mockWriter{make([]byte, 0)},
|
||||
}
|
||||
l.Log(LogError, "Error!")
|
||||
// Note: the below is deliberately fragile to ensure
|
||||
// the right file:line is logged on errors. Sorry!
|
||||
if s := string(w.written); s[20:] != "log_test.go:26: Error!\n" {
|
||||
t.Errorf("Error incorrectly logged (check line numbers!)")
|
||||
logMap := make(LogMap)
|
||||
for lv, w := range wMap {
|
||||
logMap[lv] = makeLogger(w)
|
||||
}
|
||||
return New(logMap, Error, false), wMap
|
||||
}
|
||||
|
||||
func (m writerMap) checkNothingWritten(t *testing.T) {
|
||||
for lv, w := range m {
|
||||
if len(w.written) > 0 {
|
||||
t.Errorf("%d bytes logged at level %s, expected none:",
|
||||
len(w.written), logString[lv])
|
||||
t.Errorf("\t%s", w.written)
|
||||
w.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m writerMap) checkWrittenAtLevel(t *testing.T, lv LogLevel, exp string) {
|
||||
var w *mockWriter
|
||||
if _, ok := m[lv]; !ok {
|
||||
w = m[Debug]
|
||||
} else {
|
||||
w = m[lv]
|
||||
}
|
||||
if len(w.written) == 0 {
|
||||
t.Errorf("No bytes logged at level %s, expected:", LogString(lv))
|
||||
t.Errorf("\t%s", exp)
|
||||
}
|
||||
// 32 bytes covers the date, time and filename up to the colon in
|
||||
// 2011/10/22 10:22:57 log_test.go:<line no>: <log message>
|
||||
s := string(w.written[32:])
|
||||
// 3 covers the : itself and the two extra spaces
|
||||
idx := strings.Index(s, ":") + len(LogString(lv)) + 3
|
||||
// s will end in "\n", so -1 to chop that off too
|
||||
s = s[idx:len(s)-1]
|
||||
if s != exp {
|
||||
t.Errorf("Log message at level %s differed.", LogString(lv))
|
||||
t.Errorf("\texp: %s\n\tgot: %s", exp, s)
|
||||
}
|
||||
w.reset()
|
||||
}
|
||||
|
||||
func TestLogging(t *testing.T) {
|
||||
l, m := setUp()
|
||||
|
||||
l.Log(4, "Nothing should be logged yet")
|
||||
m.checkNothingWritten(t)
|
||||
|
||||
l.Log(Debug, "or yet...")
|
||||
m.checkNothingWritten(t)
|
||||
|
||||
l.Log(Info, "or yet...")
|
||||
m.checkNothingWritten(t)
|
||||
|
||||
l.Log(Warn, "or yet!")
|
||||
m.checkNothingWritten(t)
|
||||
|
||||
l.Log(Error, "Error!")
|
||||
m.checkWrittenAtLevel(t, Error, "Error!")
|
||||
// Calling checkNothingWritten here both tests that w.reset() works
|
||||
// and verifies that nothing was written at any other levels than Error.
|
||||
m.checkNothingWritten(t)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue