Skip to content

Commit

Permalink
👔 update: testutil - update some util func add more unit test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Jul 27, 2023
1 parent f551b33 commit 28271fb
Show file tree
Hide file tree
Showing 9 changed files with 461 additions and 123 deletions.
52 changes: 52 additions & 0 deletions testutil/assert/assert.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,61 @@
// inspired the package: github.com/stretchr/testify/assert
package assert

import (
"strings"

"github.com/gookit/color"
"github.com/gookit/goutil/internal/comfunc"
)

// TestingT is an interface wrapper around *testing.T
type TestingT interface {
Helper()
Name() string
Error(args ...any)
}

//
// -------------------- render error --------------------
//

var (
// ShowFullPath on show error trace
ShowFullPath = true
// EnableColor on show error trace
EnableColor = true
)

// DisableColor render
func DisableColor() {
EnableColor = false
}

// HideFullPath render
func HideFullPath() {
ShowFullPath = false
}

// fail reports a failure through
func fail(t TestingT, failMsg string, fmtAndArgs []any) bool {
t.Helper()

tName := t.Name()
if EnableColor {
tName = color.Red.Sprint(tName)
}

labeledTexts := []labeledText{
{"Test Name", tName},
{"Error Pos", strings.Join(callerInfos(), "\n")},
{"Error Msg", failMsg},
}

// user custom message
if userMsg := comfunc.FormatWithArgs(fmtAndArgs); len(userMsg) > 0 {
labeledTexts = append(labeledTexts, labeledText{"User Msg", userMsg})
}

t.Error("\n" + formatLabeledTexts(labeledTexts))
return false
}
41 changes: 38 additions & 3 deletions testutil/assert/assertions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import (
)

func TestAssertions_Chain(t *testing.T) {
// err := "error message"
err := errors.New("error message")

as := assert.New(t).
NotEmpty(err).
NotNil(err).
Err(err).
Error(err).
ErrIs(err, err).
ErrMsg(err, "error message").
ErrSubMsg(err, "message").
Eq("error message", err.Error()).
Neq("message", err.Error()).
Equal("error message", err.Error()).
Expand All @@ -29,16 +31,49 @@ func TestAssertions_Chain(t *testing.T) {
assert.False(t, as.IsFail())

iv := 23
as = assert.New(t).
ss := []string{"a", "b"}

as = assert.New(t).WithMsg("prefix").
IsType(1, iv).
NotEq(22, iv).
NotEqual(22, iv).
Len(ss, 2).
LenGt(ss, 1).
Lte(iv, 23).
Gte(iv, 23).
Empty(0).
True(true).
False(false).
Nil(nil)
NoErr(nil).
NoError(nil).
Nil(nil).
ContainsKey(map[string]int{"a": 1}, "a")

assert.True(t, as.IsOk())

// Panics
assert.New(t).
Panics(func() { panic("panic") }).
NotPanics(func() {}).
PanicsMsg(func() { panic("panic") }, "panic").
PanicsErrMsg(func() { panic(errors.New("panic")) }, "panic")
}

func TestAssertions_chain_fail(t *testing.T) {
assert.HideFullPath()
defer func() {
assert.ShowFullPath = true
}()

tc := &tCustomTesting{T: t}
ts := assert.New(tc)

ts.Fail("fail message")
str := tc.ResetGet()
assert.StrContains(t, str, "fail message")
assert.StrContains(t, str, "assertions_test.go")
assert.NotContains(t, str, "testutil/assert/assertions_test.go")

ts.FailNow("fail now message")
assert.StrContains(t, tc.ResetGet(), "fail now message")
}
122 changes: 28 additions & 94 deletions testutil/assert/asserts.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import (
"runtime/debug"
"strings"

"github.com/gookit/color"
"github.com/gookit/goutil/arrutil"
"github.com/gookit/goutil/internal/checkfn"
"github.com/gookit/goutil/internal/comfunc"
"github.com/gookit/goutil/maputil"
"github.com/gookit/goutil/mathutil"
"github.com/gookit/goutil/reflects"
Expand Down Expand Up @@ -100,10 +98,8 @@ func runPanicFunc(f PanicRunFunc) (didPanic bool, message any, stack string) {
func Panics(t TestingT, fn PanicRunFunc, fmtAndArgs ...any) bool {
if hasPanic, panicVal, _ := runPanicFunc(fn); !hasPanic {
t.Helper()

return fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", fn, panicVal), fmtAndArgs)
return fail(t, fmt.Sprintf("func '%#v' should panic\n\tPanic value:\t%#v", fn, panicVal), fmtAndArgs)
}

return true
}

Expand All @@ -115,8 +111,7 @@ func NotPanics(t TestingT, fn PanicRunFunc, fmtAndArgs ...any) bool {
return fail(t, fmt.Sprintf(
"func %#v should not panic\n\tPanic value:\t%#v\n\tPanic stack:\t%s",
fn, panicVal, stackMsg,
), fmtAndArgs,
)
), fmtAndArgs)
}

return true
Expand All @@ -135,8 +130,7 @@ func PanicsMsg(t TestingT, fn PanicRunFunc, wantVal any, fmtAndArgs ...any) bool
return fail(t, fmt.Sprintf(
"func %#v should panic.\n\tWant value:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s",
fn, wantVal, panicVal, stackMsg),
fmtAndArgs,
)
fmtAndArgs)
}

return true
Expand Down Expand Up @@ -220,14 +214,10 @@ func NotContains(t TestingT, src, elem any, fmtAndArgs ...any) bool {
func ContainsKey(t TestingT, mp, key any, fmtAndArgs ...any) bool {
if !maputil.HasKey(mp, key) {
t.Helper()
return fail(t,
fmt.Sprintf(
"Map should contains the key: %#v\nMap data:\n%v",
key,
maputil.FormatIndent(mp, " "),
),
fmtAndArgs,
)
return fail(t, fmt.Sprintf(
"Map should contains the key: %#v\nMap data:\n%v",
key, maputil.FormatIndent(mp, " "),
), fmtAndArgs)
}

return true
Expand Down Expand Up @@ -265,14 +255,10 @@ func ContainsKeys(t TestingT, mp any, keys any, fmtAndArgs ...any) bool {
ok, noKey := maputil.HasAllKeys(mp, anyKeys...)
if !ok {
t.Helper()
return fail(t,
fmt.Sprintf(
"Map should contains the key: %#v\nMap data:\n%v",
noKey,
maputil.FormatIndent(mp, " "),
),
fmtAndArgs,
)
return fail(t, fmt.Sprintf(
"Map should contains the key: %#v\nMap data:\n%v",
noKey, maputil.FormatIndent(mp, " "),
), fmtAndArgs)
}

return true
Expand All @@ -293,14 +279,9 @@ func NotContainsKeys(t TestingT, mp any, keys any, fmtAndArgs ...any) bool {
ok, hasKey := maputil.HasOneKey(mp, anyKeys...)
if ok {
t.Helper()
return fail(t,
fmt.Sprintf(
"Map should not contains the key: %#v\nMap data:\n%v",
hasKey,
maputil.FormatIndent(mp, " "),
),
fmtAndArgs,
)
return fail(t, fmt.Sprintf("Map should not contains the key: %#v\nMap data:\n%v",
hasKey, maputil.FormatIndent(mp, " "),
), fmtAndArgs)
}

return true
Expand Down Expand Up @@ -426,29 +407,29 @@ func Len(t TestingT, give any, wantLn int, fmtAndArgs ...any) bool {
gln := reflects.Len(reflect.ValueOf(give))
if gln < 0 {
t.Helper()
return fail(t, fmt.Sprintf("\"%s\" could not be calc length", give), fmtAndArgs)
return fail(t, fmt.Sprintf("type '%T' could not be calc length", give), fmtAndArgs)
}

if gln != wantLn {
t.Helper()
return fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", give, wantLn, gln), fmtAndArgs)
}
return false
return true
}

// LenGt assert given length is greater than to minLn
func LenGt(t TestingT, give any, minLn int, fmtAndArgs ...any) bool {
gln := reflects.Len(reflect.ValueOf(give))
if gln < 0 {
t.Helper()
return fail(t, fmt.Sprintf("\"%s\" could not be calc length", give), fmtAndArgs)
return fail(t, fmt.Sprintf("type '%T' could not be calc length", give), fmtAndArgs)
}

if gln < minLn {
if gln <= minLn {
t.Helper()
return fail(t, fmt.Sprintf("\"%s\" should less have %d item(s), but has %d", give, minLn, gln), fmtAndArgs)
return fail(t, fmt.Sprintf("\"%s\" should have more than %d item(s), but has %d", give, minLn, gln), fmtAndArgs)
}
return false
return true
}

//
Expand Down Expand Up @@ -506,14 +487,11 @@ func NotEq(t TestingT, want, give any, fmtAndArgs ...any) bool {
t.Helper()

if err := checkEqualArgs(want, give); err != nil {
return fail(t,
fmt.Sprintf("Cannot compare: %#v == %#v (%s)", want, give, err),
fmtAndArgs,
)
return fail(t, fmt.Sprintf("Cannot compare: %#v == %#v (%s)", want, give, err), fmtAndArgs)
}

if reflects.IsEqual(want, give) {
return fail(t, fmt.Sprintf("Given should not be: %#v\n", give), fmtAndArgs)
return fail(t, fmt.Sprintf("Given should not be: %#v, but give: %+v\n", want, give), fmtAndArgs)
}
return true
}
Expand All @@ -525,7 +503,7 @@ func Lt(t TestingT, give, max any, fmtAndArgs ...any) bool {
}

t.Helper()
return fail(t, fmt.Sprintf("Given %v should later than %v", give, max), fmtAndArgs)
return fail(t, fmt.Sprintf("Given %v should less than %v", give, max), fmtAndArgs)
}

// Lte asserts that the give(intX,uintX,floatX) should not be less than or equals to max
Expand All @@ -535,7 +513,7 @@ func Lte(t TestingT, give, max any, fmtAndArgs ...any) bool {
}

t.Helper()
return fail(t, fmt.Sprintf("Given %v should later than %v", give, max), fmtAndArgs)
return fail(t, fmt.Sprintf("Given %v should less than or equal %v", give, max), fmtAndArgs)
}

// Gt asserts that the give(intX,uintX,floatX) should not be greater than min
Expand All @@ -545,7 +523,7 @@ func Gt(t TestingT, give, min any, fmtAndArgs ...any) bool {
}

t.Helper()
return fail(t, fmt.Sprintf("Given %v should gater than %v", give, min), fmtAndArgs)
return fail(t, fmt.Sprintf("Given %v should greater than %v", give, min), fmtAndArgs)
}

// Gte asserts that the give(intX,uintX,floatX) should not be greater than or equals to min
Expand All @@ -555,7 +533,7 @@ func Gte(t TestingT, give, min any, fmtAndArgs ...any) bool {
}

t.Helper()
return fail(t, fmt.Sprintf("Given %v should gater than or equal %v", give, min), fmtAndArgs)
return fail(t, fmt.Sprintf("Given %v should greater than or equal %v", give, min), fmtAndArgs)
}

// IsType assert data type equals
Expand Down Expand Up @@ -605,6 +583,7 @@ func Same(t TestingT, wanted, actual any, fmtAndArgs ...any) bool {
return true
}

t.Helper()
return fail(t, fmt.Sprintf("Not same: \n"+
"wanted: %p %#v\n"+
"actual: %p %#v", wanted, wanted, actual, actual), fmtAndArgs)
Expand All @@ -622,7 +601,7 @@ func NotSame(t TestingT, want, actual any, fmtAndArgs ...any) bool {
}

t.Helper()
return fail(t, fmt.Sprintf("Expect and actual point to the same object: %p %#v", want, want), fmtAndArgs)
return fail(t, fmt.Sprintf("Expect and actual is same object: %p %#v", want, want), fmtAndArgs)
}

// samePointers compares two generic interface objects and returns whether
Expand Down Expand Up @@ -666,48 +645,3 @@ func FailNow(t TestingT, failMsg string, fmtAndArgs ...any) bool {
}
return false
}

//
// -------------------- render error --------------------
//

var (
// ShowFullPath on show error trace
ShowFullPath = true
// EnableColor on show error trace
EnableColor = true
)

// DisableColor render
func DisableColor() {
EnableColor = false
}

// HideFullPath render
func HideFullPath() {
ShowFullPath = false
}

// fail reports a failure through
func fail(t TestingT, failMsg string, fmtAndArgs []any) bool {
t.Helper()

tName := t.Name()
if EnableColor {
tName = color.Red.Sprint(tName)
}

labeledTexts := []labeledText{
{"Test Name", tName},
{"Error At", strings.Join(callerInfos(), "\n")},
{"Error Msg", failMsg},
}

// user custom message
if userMsg := comfunc.FormatWithArgs(fmtAndArgs); len(userMsg) > 0 {
labeledTexts = append(labeledTexts, labeledText{"User Msg", userMsg})
}

t.Error("\n" + formatLabeledTexts(labeledTexts))
return false
}
Loading

0 comments on commit 28271fb

Please sign in to comment.