From ece955bb9ed9239a85ec124beeacf624799a4f3f Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Sun, 15 Dec 2019 16:12:21 -0600 Subject: [PATCH] assert: add ErrorContains and move name arg to first parameter --- internal/assert/assert.go | 41 ++++------------- internal/entryhuman/entry_test.go | 4 +- internal/syncwriter/syncwriter_test.go | 12 ++--- map_test.go | 6 +-- s_test.go | 6 +-- slog_test.go | 38 ++++++++-------- sloggers/sloghuman/sloghuman_test.go | 6 +-- sloggers/slogjson/slogjson_test.go | 2 +- .../slogstackdriver/slogstackdriver_test.go | 12 ++--- sloggers/slogtest/assert/assert.go | 37 +++++++++++++--- sloggers/slogtest/assert/assert_test.go | 44 ++++++++++++------- sloggers/slogtest/t_test.go | 8 ++-- 12 files changed, 116 insertions(+), 100 deletions(-) diff --git a/internal/assert/assert.go b/internal/assert/assert.go index 3f920c8..69a92b3 100644 --- a/internal/assert/assert.go +++ b/internal/assert/assert.go @@ -3,28 +3,19 @@ package assert import ( "reflect" - "strings" "testing" ) // Equal asserts exp == act. -func Equal(t testing.TB, exp, act interface{}, name string) { +func Equal(t testing.TB, name string, exp, act interface{}) { t.Helper() if !reflect.DeepEqual(exp, act) { t.Fatalf("unexpected %v: exp: %q but got %q", name, exp, act) } } -// NotEqual asserts exp != act. -func NotEqual(t testing.TB, exp, act interface{}, name string) { - t.Helper() - if reflect.DeepEqual(exp, act) { - t.Fatalf("expected different %v: %q", name, act) - } -} - // Success asserts err == nil. -func Success(t testing.TB, err error, name string) { +func Success(t testing.TB, name string, err error) { t.Helper() if err != nil { t.Fatalf("unexpected error for %v: %+v", name, err) @@ -32,46 +23,30 @@ func Success(t testing.TB, err error, name string) { } // Error asserts exp != nil. -func Error(t testing.TB, err error, name string) { +func Error(t testing.TB, name string, err error) { t.Helper() if err == nil { t.Fatalf("expected error from %v", name) } } -// ErrorContains asserts the error string from err contains sub. -func ErrorContains(t testing.TB, err error, sub, name string) { - t.Helper() - Error(t, err, name) - errs := err.Error() - if !strings.Contains(errs, sub) { - t.Fatalf("error string %q from %v does not contain %q", errs, name, sub) - } -} - // True asserts true == act. -func True(t testing.TB, act bool, name string) { +func True(t testing.TB, name string, act bool) { t.Helper() - Equal(t, true, act, name) + Equal(t, name, true, act) } // False asserts false == act. -func False(t testing.TB, act bool, name string) { +func False(t testing.TB, name string, act bool) { t.Helper() - Equal(t, false, act, name) + Equal(t, name, false, act) } // Len asserts n == len(a). -func Len(t testing.TB, n int, a interface{}, name string) { +func Len(t testing.TB, name string, n int, a interface{}) { t.Helper() act := reflect.ValueOf(a).Len() if n != act { t.Fatalf("expected len(%v) == %v but got %v", name, n, act) } } - -// Nil asserts v == nil. -func Nil(t testing.TB, v interface{}, name string) { - t.Helper() - Equal(t, nil, v, name) -} diff --git a/internal/entryhuman/entry_test.go b/internal/entryhuman/entry_test.go index b476870..c668500 100644 --- a/internal/entryhuman/entry_test.go +++ b/internal/entryhuman/entry_test.go @@ -19,7 +19,7 @@ func TestEntry(t *testing.T) { test := func(t *testing.T, in slog.SinkEntry, exp string) { act := entryhuman.Fmt(ioutil.Discard, in) - assert.Equal(t, exp, act, "entry") + assert.Equal(t, "entry", exp, act) } t.Run("basic", func(t *testing.T) { @@ -89,6 +89,6 @@ line2`) slog.F("hey", "hi"), ), }) - assert.Equal(t, "0001-01-01 00:00:00.000 \x1b[91m[CRITICAL]\x1b[0m\t\x1b[36m<.:0>\x1b[0m\t\"\"\t{\x1b[34m\"hey\"\x1b[0m: \x1b[32m\"hi\"\x1b[0m}", act, "entry") + assert.Equal(t, "entry", "0001-01-01 00:00:00.000 \x1b[91m[CRITICAL]\x1b[0m\t\x1b[36m<.:0>\x1b[0m\t\"\"\t{\x1b[34m\"hey\"\x1b[0m: \x1b[32m\"hi\"\x1b[0m}", act) }) } diff --git a/internal/syncwriter/syncwriter_test.go b/internal/syncwriter/syncwriter_test.go index d6eb5e6..e001320 100644 --- a/internal/syncwriter/syncwriter_test.go +++ b/internal/syncwriter/syncwriter_test.go @@ -31,7 +31,7 @@ func TestWriter_Sync(t *testing.T) { tw := newWriter(nil) tw.w.Sync("test") - assert.Equal(t, 0, tw.errors, "errors") + assert.Equal(t, "errors", 0, tw.errors) }) t.Run("syncWriter", func(t *testing.T) { @@ -46,9 +46,9 @@ func TestWriter_Sync(t *testing.T) { }, }) tw.w.Write("hello", nil) - assert.Equal(t, 1, tw.errors, "errors") + assert.Equal(t, "errors", 1, tw.errors) tw.w.Sync("test") - assert.Equal(t, 2, tw.errors, "errors") + assert.Equal(t, "errors", 2, tw.errors) }) t.Run("stdout", func(t *testing.T) { @@ -56,7 +56,7 @@ func TestWriter_Sync(t *testing.T) { tw := newWriter(os.Stdout) tw.w.Sync("test") - assert.Equal(t, 0, tw.errors, "errors") + assert.Equal(t, "errors", 0, tw.errors) }) t.Run("errorf", func(t *testing.T) { @@ -77,8 +77,8 @@ func TestWriter_Sync(t *testing.T) { func Test_errorsIsAny(t *testing.T) { t.Parallel() - assert.True(t, errorsIsAny(io.EOF, io.ErrUnexpectedEOF, io.EOF), "err") - assert.False(t, errorsIsAny(io.EOF, io.ErrUnexpectedEOF, io.ErrClosedPipe), "err") + assert.True(t, "err", errorsIsAny(io.EOF, io.ErrUnexpectedEOF, io.EOF)) + assert.False(t, "err", errorsIsAny(io.EOF, io.ErrUnexpectedEOF, io.ErrClosedPipe)) } type syncWriter struct { diff --git a/map_test.go b/map_test.go index b02793e..3b98d7a 100644 --- a/map_test.go +++ b/map_test.go @@ -24,7 +24,7 @@ func TestMap(t *testing.T) { t.Helper() exp = indentJSON(t, exp) act := marshalJSON(t, m) - assert.Equal(t, exp, act, "JSON") + assert.Equal(t, "JSON", exp, act) } t.Run("JSON", func(t *testing.T) { @@ -253,13 +253,13 @@ func (m meow) SlogValue() interface{} { func indentJSON(t *testing.T, j string) string { b := &bytes.Buffer{} err := json.Indent(b, []byte(j), "", strings.Repeat(" ", 4)) - assert.Success(t, err, "indent JSON") + assert.Success(t, "indent JSON", err) return b.String() } func marshalJSON(t *testing.T, m slog.Map) string { actb, err := json.Marshal(m) - assert.Success(t, err, "marshal map to JSON") + assert.Success(t, "marshal map to JSON", err) return indentJSON(t, string(actb)) } diff --git a/s_test.go b/s_test.go index 2cdf78f..a589460 100644 --- a/s_test.go +++ b/s_test.go @@ -21,7 +21,7 @@ func TestStdlib(t *testing.T) { stdlibLog.Println("stdlib") et, rest, err := entryhuman.StripTimestamp(b.String()) - assert.Success(t, err, "strip timestamp") - assert.False(t, et.IsZero(), "timestamp") - assert.Equal(t, " [INFO]\t(stdlib)\t\tstdlib\t{\"hi\": \"we\"}\n", rest, "entry") + assert.Success(t, "strip timestamp", err) + assert.False(t, "timestamp", et.IsZero()) + assert.Equal(t, "entry", " [INFO]\t(stdlib)\t\tstdlib\t{\"hi\": \"we\"}\n", rest) } diff --git a/slog_test.go b/slog_test.go index 741bddb..a55def2 100644 --- a/slog_test.go +++ b/slog_test.go @@ -44,10 +44,10 @@ func TestLogger(t *testing.T) { l.Info(bg, "wow", slog.Error(io.EOF)) l.Error(bg, "meow", slog.Error(io.ErrUnexpectedEOF)) - assert.Equal(t, 1, s1.syncs, "syncs") - assert.Len(t, 1, s1.entries, "entries") + assert.Equal(t, "syncs", 1, s1.syncs) + assert.Len(t, "entries", 1, s1.entries) - assert.Equal(t, s1, s2, "sinks") + assert.Equal(t, "sinks", s1, s2) }) t.Run("helper", func(t *testing.T) { @@ -65,8 +65,8 @@ func TestLogger(t *testing.T) { ) h(ctx) - assert.Len(t, 1, s.entries, "entries") - assert.Equal(t, slog.SinkEntry{ + assert.Len(t, "entries", 1, s.entries) + assert.Equal(t, "entry", slog.SinkEntry{ Time: s.entries[0].Time, Level: slog.LevelInfo, @@ -79,7 +79,7 @@ func TestLogger(t *testing.T) { Fields: slog.M( slog.F("ctx", 1024), ), - }, s.entries[0], "entry") + }, s.entries[0]) }) t.Run("entry", func(t *testing.T) { @@ -96,8 +96,8 @@ func TestLogger(t *testing.T) { l.Info(ctx, "meow", slog.F("hi", "xd")) - assert.Len(t, 1, s.entries, "entries") - assert.Equal(t, slog.SinkEntry{ + assert.Len(t, "entries", 1, s.entries) + assert.Equal(t, "entry", slog.SinkEntry{ Time: s.entries[0].Time, Level: slog.LevelInfo, @@ -116,7 +116,7 @@ func TestLogger(t *testing.T) { slog.F("ctx", io.EOF), slog.F("hi", "xd"), ), - }, s.entries[0], "entry") + }, s.entries[0]) }) t.Run("levels", func(t *testing.T) { @@ -138,20 +138,20 @@ func TestLogger(t *testing.T) { l.Critical(bg, "") l.Fatal(bg, "") - assert.Len(t, 6, s.entries, "entries") - assert.Equal(t, 3, s.syncs, "syncs") - assert.Equal(t, slog.LevelDebug, s.entries[0].Level, "level") - assert.Equal(t, slog.LevelInfo, s.entries[1].Level, "level") - assert.Equal(t, slog.LevelWarn, s.entries[2].Level, "level") - assert.Equal(t, slog.LevelError, s.entries[3].Level, "level") - assert.Equal(t, slog.LevelCritical, s.entries[4].Level, "level") - assert.Equal(t, slog.LevelFatal, s.entries[5].Level, "level") - assert.Equal(t, 1, exits, "exits") + assert.Len(t, "entries", 6, s.entries) + assert.Equal(t, "syncs", 3, s.syncs) + assert.Equal(t, "level", slog.LevelDebug, s.entries[0].Level) + assert.Equal(t, "level", slog.LevelInfo, s.entries[1].Level) + assert.Equal(t, "level", slog.LevelWarn, s.entries[2].Level) + assert.Equal(t, "level", slog.LevelError, s.entries[3].Level) + assert.Equal(t, "level", slog.LevelCritical, s.entries[4].Level) + assert.Equal(t, "level", slog.LevelFatal, s.entries[5].Level) + assert.Equal(t, "exits", 1, exits) }) } func TestLevel_String(t *testing.T) { t.Parallel() - assert.Equal(t, "slog.Level(12)", slog.Level(12).String(), "level string") + assert.Equal(t, "level string", "slog.Level(12)", slog.Level(12).String()) } diff --git a/sloggers/sloghuman/sloghuman_test.go b/sloggers/sloghuman/sloghuman_test.go index 71b88ca..5c62637 100644 --- a/sloggers/sloghuman/sloghuman_test.go +++ b/sloggers/sloghuman/sloghuman_test.go @@ -22,7 +22,7 @@ func TestMake(t *testing.T) { l.Sync() et, rest, err := entryhuman.StripTimestamp(b.String()) - assert.Success(t, err, "strip timestamp") - assert.False(t, et.IsZero(), "timestamp") - assert.Equal(t, " [INFO]\t\t...\t{\"wowow\": \"me\\nyou\"}\n \"msg\": line1\n\n line2\n", rest, "entry") + assert.Success(t, "strip timestamp", err) + assert.False(t, "timestamp", et.IsZero()) + assert.Equal(t, "entry", " [INFO]\t\t...\t{\"wowow\": \"me\\nyou\"}\n \"msg\": line1\n\n line2\n", rest) } diff --git a/sloggers/slogjson/slogjson_test.go b/sloggers/slogjson/slogjson_test.go index e34307d..77ee4e4 100644 --- a/sloggers/slogjson/slogjson_test.go +++ b/sloggers/slogjson/slogjson_test.go @@ -31,5 +31,5 @@ func TestMake(t *testing.T) { j := entryjson.Filter(b.String(), "ts") exp := fmt.Sprintf(`{"level":"ERROR","msg":"line1\n\nline2","caller":"%v:29","func":"cdr.dev/slog/sloggers/slogjson_test.TestMake","logger_names":["named"],"trace":"%v","span":"%v","fields":{"wowow":"me\nyou"}} `, slogjsonTestFile, s.SpanContext().TraceID, s.SpanContext().SpanID) - assert.Equal(t, exp, j, "entry") + assert.Equal(t, "entry", exp, j) } diff --git a/sloggers/slogstackdriver/slogstackdriver_test.go b/sloggers/slogstackdriver/slogstackdriver_test.go index 5e2beda..3a4a295 100644 --- a/sloggers/slogstackdriver/slogstackdriver_test.go +++ b/sloggers/slogstackdriver/slogstackdriver_test.go @@ -31,15 +31,15 @@ func TestStackdriver(t *testing.T) { j := entryjson.Filter(b.String(), "timestamp") exp := fmt.Sprintf(`{"severity":"ERROR","message":"line1\n\nline2","logging.googleapis.com/sourceLocation":{"file":"%v","line":29,"function":"cdr.dev/slog/sloggers/slogstackdriver_test.TestStackdriver"},"logging.googleapis.com/operation":{"producer":"meow"},"logging.googleapis.com/trace":"projects//traces/%v","logging.googleapis.com/spanId":"%v","logging.googleapis.com/trace_sampled":false,"wowow":"me\nyou"} `, slogstackdriverTestFile, s.SpanContext().TraceID, s.SpanContext().SpanID) - assert.Equal(t, exp, j, "entry") + assert.Equal(t, "entry", exp, j) } func TestSevMapping(t *testing.T) { t.Parallel() - assert.Equal(t, logpbtype.LogSeverity_DEBUG, slogstackdriver.Sev(slog.LevelDebug), "level") - assert.Equal(t, logpbtype.LogSeverity_INFO, slogstackdriver.Sev(slog.LevelInfo), "level") - assert.Equal(t, logpbtype.LogSeverity_WARNING, slogstackdriver.Sev(slog.LevelWarn), "level") - assert.Equal(t, logpbtype.LogSeverity_ERROR, slogstackdriver.Sev(slog.LevelError), "level") - assert.Equal(t, logpbtype.LogSeverity_CRITICAL, slogstackdriver.Sev(slog.LevelCritical), "level") + assert.Equal(t, "level", logpbtype.LogSeverity_DEBUG, slogstackdriver.Sev(slog.LevelDebug)) + assert.Equal(t, "level", logpbtype.LogSeverity_INFO, slogstackdriver.Sev(slog.LevelInfo)) + assert.Equal(t, "level", logpbtype.LogSeverity_WARNING, slogstackdriver.Sev(slog.LevelWarn)) + assert.Equal(t, "level", logpbtype.LogSeverity_ERROR, slogstackdriver.Sev(slog.LevelError)) + assert.Equal(t, "level", logpbtype.LogSeverity_CRITICAL, slogstackdriver.Sev(slog.LevelCritical)) } diff --git a/sloggers/slogtest/assert/assert.go b/sloggers/slogtest/assert/assert.go index b1ac367..1584f54 100644 --- a/sloggers/slogtest/assert/assert.go +++ b/sloggers/slogtest/assert/assert.go @@ -8,6 +8,7 @@ package assert // import "cdr.dev/slog/sloggers/slogtest/assert" import ( "errors" "reflect" + "strings" "testing" "cdr.dev/slog" @@ -20,7 +21,7 @@ import ( // two objects. // // If act or exp is an error it will be unwrapped. -func Equal(t testing.TB, exp, act interface{}, name string) { +func Equal(t testing.TB, name string, exp, act interface{}) { slog.Helper() exp = unwrapErr(exp) @@ -36,7 +37,7 @@ func Equal(t testing.TB, exp, act interface{}, name string) { } // Success asserts err == nil. -func Success(t testing.TB, err error, name string) { +func Success(t testing.TB, name string, err error) { slog.Helper() if err != nil { slogtest.Fatal(t, "unexpected error", @@ -47,13 +48,13 @@ func Success(t testing.TB, err error, name string) { } // True asserts act == true. -func True(t testing.TB, act bool, name string) { +func True(t testing.TB, name string, act bool) { slog.Helper() - Equal(t, true, act, name) + Equal(t, name, true, act) } // Error asserts err != nil. -func Error(t testing.TB, err error, name string) { +func Error(t testing.TB, name string, err error) { slog.Helper() if err == nil { slogtest.Fatal(t, "expected error", @@ -74,3 +75,29 @@ func unwrapErr(v interface{}) interface{} { } return err } + +// ErrorContains asserts err != nil and err.Error() contains sub. +// +// The match will be case insensitive. +func ErrorContains(t testing.TB, name string, err error, sub string) { + slog.Helper() + + Error(t, name, err) + + errs := err.Error() + if !stringContainsFold(errs, sub) { + slogtest.Fatal(t, "unexpected error string", + slog.F("name", name), + slog.F("error_string", errs), + slog.F("expected_contains", sub), + ) + } +} + +func stringContainsFold(errs, sub string) bool { + errs = strings.ToLower(errs) + sub = strings.ToLower(sub) + + return strings.Contains(errs, sub) + +} diff --git a/sloggers/slogtest/assert/assert_test.go b/sloggers/slogtest/assert/assert_test.go index 6008294..82d9a5d 100644 --- a/sloggers/slogtest/assert/assert_test.go +++ b/sloggers/slogtest/assert/assert_test.go @@ -13,65 +13,79 @@ func TestEqual(t *testing.T) { t.Parallel() tb := &fakeTB{} - assert.Equal(tb, 3, 3, "meow") + assert.Equal(tb, "meow", 3, 3) defer func() { recover() - simpleassert.Equal(t, 1, tb.fatals, "fatals") + simpleassert.Equal(t, "fatals", 1, tb.fatals) }() - assert.Equal(tb, 3, 4, "meow") + assert.Equal(tb, "meow", 3, 4) } func TestEqual_error(t *testing.T) { t.Parallel() tb := &fakeTB{} - assert.Equal(tb, io.EOF, fmt.Errorf("failed: %w", io.EOF), "meow") + assert.Equal(tb, "meow", io.EOF, fmt.Errorf("failed: %w", io.EOF)) defer func() { recover() - simpleassert.Equal(t, 1, tb.fatals, "fatals") + simpleassert.Equal(t, "fatals", 1, tb.fatals) }() - assert.Equal(tb, io.ErrClosedPipe, fmt.Errorf("failed: %w", io.EOF), "meow") + assert.Equal(tb, "meow", io.ErrClosedPipe, fmt.Errorf("failed: %w", io.EOF)) } +func TestErrorContains(t *testing.T) { + t.Parallel() + + tb := &fakeTB{} + assert.ErrorContains(tb, "meow", io.EOF, "eof") + + defer func() { + recover() + simpleassert.Equal(t, "fatals", 1, tb.fatals) + + }() + assert.ErrorContains(tb, "meow", io.ErrClosedPipe, "eof") + +} func TestSuccess(t *testing.T) { t.Parallel() tb := &fakeTB{} - assert.Success(tb, nil, "meow") + assert.Success(tb, "meow", nil) defer func() { recover() - simpleassert.Equal(t, 1, tb.fatals, "fatals") + simpleassert.Equal(t, "fatals", 1, tb.fatals) }() - assert.Success(tb, io.EOF, "meow") + assert.Success(tb, "meow", io.EOF) } func TestTrue(t *testing.T) { t.Parallel() tb := &fakeTB{} - assert.True(tb, true, "meow") + assert.True(tb, "meow", true) defer func() { recover() - simpleassert.Equal(t, 1, tb.fatals, "fatals") + simpleassert.Equal(t, "fatals", 1, tb.fatals) }() - assert.True(tb, false, "meow") + assert.True(tb, "meow", false) } func TestError(t *testing.T) { t.Parallel() tb := &fakeTB{} - assert.Error(tb, io.EOF, "meow") + assert.Error(tb, "meow", io.EOF) defer func() { recover() - simpleassert.Equal(t, 1, tb.fatals, "fatals") + simpleassert.Equal(t, "fatals", 1, tb.fatals) }() - assert.Error(tb, nil, "meow") + assert.Error(tb, "meow", nil) } type fakeTB struct { diff --git a/sloggers/slogtest/t_test.go b/sloggers/slogtest/t_test.go index bd6c586..9169cbe 100644 --- a/sloggers/slogtest/t_test.go +++ b/sloggers/slogtest/t_test.go @@ -17,11 +17,11 @@ func TestStateless(t *testing.T) { slogtest.Info(tb, "hello") slogtest.Error(tb, "hello") - assert.Equal(t, 1, tb.errors, "errors") + assert.Equal(t, "errors", 1, tb.errors) defer func() { recover() - assert.Equal(t, 1, tb.fatals, "fatals") + assert.Equal(t, "fatals", 1, tb.fatals) }() slogtest.Fatal(tb, "hello") @@ -36,11 +36,11 @@ func TestIgnoreErrors(t *testing.T) { })) l.Error(bg, "hello") - assert.Equal(t, 0, tb.errors, "errors") + assert.Equal(t, "errors", 0, tb.errors) defer func() { recover() - assert.Equal(t, 0, tb.fatals, "fatals") + assert.Equal(t, "fatals", 0, tb.fatals) }() l.Fatal(bg, "hello")