diff --git a/Race_test.go b/Race_test.go index 54c3a83..6f27815 100644 --- a/Race_test.go +++ b/Race_test.go @@ -35,7 +35,7 @@ func TestRace(t *testing.T) { it.Must.Equal(int32(4), total) it.Log(`counter:`, counter, `total:`, total) it.Must.True(counter < total, - fmt.Sprintf(`counter was expected to be less that the total block run during race`)) + assert.Message(fmt.Sprintf(`counter was expected to be less that the total block run during race`))) }) }) diff --git a/assert/AnyOf.go b/assert/AnyOf.go index 9f0465e..9192340 100644 --- a/assert/AnyOf.go +++ b/assert/AnyOf.go @@ -12,7 +12,7 @@ import ( // OneOf function checks a list of values and matches an expectation against each element of the list. // If any of the elements pass the assertion, then the assertion helper function does not fail the test. -func OneOf[V any](tb testing.TB, vs []V, blk func(it It, got V), msg ...any) { +func OneOf[V any](tb testing.TB, vs []V, blk func(it It, got V), msg ...Message) { tb.Helper() Must(tb).AnyOf(func(a *AnyOf) { a.name = "OneOf" @@ -71,7 +71,7 @@ func (ao *AnyOf) Test(blk func(t It)) { } // Finish will check if any of the assertion succeeded. -func (ao *AnyOf) Finish(msg ...interface{}) { +func (ao *AnyOf) Finish(msg ...Message) { ao.TB.Helper() if ao.OK() { return @@ -89,7 +89,7 @@ func (ao *AnyOf) Finish(msg ...interface{}) { } return "None of the .Test succeeded" }(), - Message: msg, + Message: toMsg(msg), Values: nil, }) ao.Fail() diff --git a/assert/AnyOf_test.go b/assert/AnyOf_test.go index eaccc82..298087a 100644 --- a/assert/AnyOf_test.go +++ b/assert/AnyOf_test.go @@ -71,7 +71,7 @@ func TestAnyOf(t *testing.T) { s.Then(`AnyOf yields failure on .Finish`, func(t *testcase.T) { anyOf.Get(t).Finish() - t.Must.True(true, stub.Get(t).IsFailed) + t.Must.True(stub.Get(t).IsFailed) }) s.Then("AnyOf.OK will yield false due to no passing test", func(t *testcase.T) { diff --git a/assert/Asserter.go b/assert/Asserter.go index 5879ac2..2b2f551 100644 --- a/assert/Asserter.go +++ b/assert/Asserter.go @@ -51,7 +51,7 @@ func (a Asserter) try(blk func(a Asserter)) (ok bool) { return !dtb.IsFailed } -func (a Asserter) True(v bool, msg ...any) { +func (a Asserter) True(v bool, msg ...Message) { a.TB.Helper() if v { return @@ -59,7 +59,7 @@ func (a Asserter) True(v bool, msg ...any) { a.fn(fmterror.Message{ Method: "True", Cause: `"true" was expected.`, - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "value", @@ -69,7 +69,7 @@ func (a Asserter) True(v bool, msg ...any) { }.String()) } -func (a Asserter) False(v bool, msg ...any) { +func (a Asserter) False(v bool, msg ...Message) { a.TB.Helper() if !a.try(func(a Asserter) { a.True(v) }) { return @@ -77,7 +77,7 @@ func (a Asserter) False(v bool, msg ...any) { a.fn(fmterror.Message{ Method: "False", Cause: `"false" was expected.`, - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "value", @@ -87,7 +87,7 @@ func (a Asserter) False(v bool, msg ...any) { }.String()) } -func (a Asserter) Nil(v any, msg ...any) { +func (a Asserter) Nil(v any, msg ...Message) { a.TB.Helper() if v == nil { return @@ -98,7 +98,7 @@ func (a Asserter) Nil(v any, msg ...any) { a.fn(fmterror.Message{ Method: "Nil", Cause: "Not nil value received", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "value", @@ -108,7 +108,7 @@ func (a Asserter) Nil(v any, msg ...any) { }) } -func (a Asserter) NotNil(v any, msg ...any) { +func (a Asserter) NotNil(v any, msg ...Message) { a.TB.Helper() if !reflects.IsNil(v) { return @@ -116,11 +116,11 @@ func (a Asserter) NotNil(v any, msg ...any) { a.fn(fmterror.Message{ Method: "NotNil", Cause: "Nil value received", - Message: msg, + Message: toMsg(msg), }) } -func (a Asserter) Panic(blk func(), msg ...any) any { +func (a Asserter) Panic(blk func(), msg ...Message) any { a.TB.Helper() if ro := sandbox.Run(blk); !ro.OK { return ro.PanicValue @@ -128,12 +128,12 @@ func (a Asserter) Panic(blk func(), msg ...any) any { a.fn(fmterror.Message{ Method: "Panics", Cause: "Expected to panic or die.", - Message: msg, + Message: toMsg(msg), }) return nil } -func (a Asserter) NotPanic(blk func(), msg ...any) { +func (a Asserter) NotPanic(blk func(), msg ...Message) { a.TB.Helper() out := sandbox.Run(blk) if out.OK { @@ -142,7 +142,7 @@ func (a Asserter) NotPanic(blk func(), msg ...any) { a.fn(fmterror.Message{ Method: "Panics", Cause: "Expected to panic or die.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "panic:", @@ -159,7 +159,7 @@ func (a Asserter) NotPanic(blk func(), msg ...any) { // - value.IsEqual(oth T) (bool, error) // - value.Equal(oth T) bool // - value.Equal(oth T) (bool, error) -func (a Asserter) Equal(v, oth any, msg ...any) { +func (a Asserter) Equal(v, oth any, msg ...Message) { a.TB.Helper() const method = "Equal" @@ -173,13 +173,13 @@ func (a Asserter) Equal(v, oth any, msg ...any) { a.TB.Log(fmterror.Message{ Method: method, - Message: msg, + Message: toMsg(msg), }.String()) a.TB.Logf("\n\n%s", DiffFunc(v, oth)) a.Fail() } -func (a Asserter) NotEqual(v, oth any, msg ...any) { +func (a Asserter) NotEqual(v, oth any, msg ...Message) { a.TB.Helper() const method = "NotEqual" @@ -194,7 +194,7 @@ func (a Asserter) NotEqual(v, oth any, msg ...any) { a.fn(fmterror.Message{ Method: method, Cause: "Values are equal.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "value", @@ -208,7 +208,7 @@ func (a Asserter) NotEqual(v, oth any, msg ...any) { }.String()) } -func (a Asserter) checkTypeEquality(method string, v any, oth any, msg []any) (failed bool) { +func (a Asserter) checkTypeEquality(method string, v any, oth any, msg []Message) (failed bool) { a.TB.Helper() var ( vType = reflect.TypeOf(v) @@ -229,7 +229,7 @@ func (a Asserter) checkTypeEquality(method string, v any, oth any, msg []any) (f a.TB.Log(fmterror.Message{ Method: method, Cause: "incorrect types", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "type", @@ -249,7 +249,7 @@ func (a Asserter) eq(exp, act any) bool { return eq(a.TB, exp, act) } -func (a Asserter) Contain(haystack, needle any, msg ...any) { +func (a Asserter) Contain(haystack, needle any, msg ...Message) { a.TB.Helper() rSrc := reflect.ValueOf(haystack) rHas := reflect.ValueOf(needle) @@ -306,13 +306,13 @@ func (a Asserter) Contain(haystack, needle any, msg ...any) { } } -func (a Asserter) failContains(src, sub any, msg ...any) { +func (a Asserter) failContains(src, sub any, msg ...Message) { a.TB.Helper() a.fn(fmterror.Message{ Method: "Contain", Cause: "Source doesn't contains expected value(s).", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "source", @@ -326,7 +326,7 @@ func (a Asserter) failContains(src, sub any, msg ...any) { }.String()) } -func (a Asserter) sliceContainsValue(slice, value reflect.Value, msg []any) { +func (a Asserter) sliceContainsValue(slice, value reflect.Value, msg []Message) { a.TB.Helper() var found bool for i := 0; i < slice.Len(); i++ { @@ -341,7 +341,7 @@ func (a Asserter) sliceContainsValue(slice, value reflect.Value, msg []any) { a.fn(fmterror.Message{ Method: "Contain", Cause: "Couldn't find the expected value in the source slice", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "source", @@ -355,14 +355,14 @@ func (a Asserter) sliceContainsValue(slice, value reflect.Value, msg []any) { }) } -func (a Asserter) sliceContainsSubSlice(haystack, needle reflect.Value, msg []any) { +func (a Asserter) sliceContainsSubSlice(haystack, needle reflect.Value, msg []Message) { a.TB.Helper() if haystack.Len() < needle.Len() { a.fn(fmterror.Message{ Method: "Contain", Cause: "Haystack slice is smaller than needle slice.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "haystack slice len", @@ -394,7 +394,7 @@ func (a Asserter) sliceContainsSubSlice(haystack, needle reflect.Value, msg []an a.fn(fmterror.Message{ Method: "Contain", Cause: "Haystack slice doesn't contains expected value(s) of needle slice.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "haystack slice", @@ -414,7 +414,7 @@ func (a Asserter) sliceContainsSubSlice(haystack, needle reflect.Value, msg []an } } -func (a Asserter) Sub(slice, sub any, msg ...any) { +func (a Asserter) Sub(slice, sub any, msg ...Message) { a.TB.Helper() sliceRV := reflect.ValueOf(slice) @@ -452,7 +452,7 @@ func (a Asserter) Sub(slice, sub any, msg ...any) { a.fn(fmterror.Message{ Method: "Subset", Cause: "Slice doesn't contain the expected subset.", - Message: msg, + Message: toMsg(msg), Values: values, }.String()) } @@ -461,7 +461,7 @@ func (a Asserter) Sub(slice, sub any, msg ...any) { a.fn(fmterror.Message{ Method: "Contain", Cause: "Source slice is smaller than sub slice.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "source", @@ -511,7 +511,7 @@ searching: // Match will fail for both receiving an invalid expression // or having the value not matched by the expression. // If the expression is invalid, test will fail early, regardless if Should or Must was used. -func (a Asserter) Match(v, expr string, msg ...any) { +func (a Asserter) Match(v, expr string, msg ...Message) { a.TB.Helper() if a.toRegexp(expr).MatchString(v) { return @@ -519,7 +519,7 @@ func (a Asserter) Match(v, expr string, msg ...any) { a.fn(fmterror.Message{ Method: "Match", Cause: "failed to match the expected expression", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: v}, {Label: "expression", Value: expr}, @@ -529,7 +529,7 @@ func (a Asserter) Match(v, expr string, msg ...any) { // NotMatch will check if an expression is not matching a given value. // NotMatch will fail the test early for receiving an invalid expression. -func (a Asserter) NotMatch(v, expr string, msg ...any) { +func (a Asserter) NotMatch(v, expr string, msg ...Message) { a.TB.Helper() if !a.toRegexp(expr).MatchString(v) { return @@ -537,7 +537,7 @@ func (a Asserter) NotMatch(v, expr string, msg ...any) { a.fn(fmterror.Message{ Method: "NotMatch", Cause: "value is matching the expression", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: v}, {Label: "expression", Value: expr}, @@ -562,7 +562,7 @@ func (a Asserter) toRegexp(expr string) *regexp.Regexp { return rgx } -func (a Asserter) mapContainsSubMap(src reflect.Value, has reflect.Value, msg []any) { +func (a Asserter) mapContainsSubMap(src reflect.Value, has reflect.Value, msg []Message) { a.TB.Helper() for _, key := range has.MapKeys() { srcValue := src.MapIndex(key) @@ -570,7 +570,7 @@ func (a Asserter) mapContainsSubMap(src reflect.Value, has reflect.Value, msg [] a.fn(fmterror.Message{ Method: "Contain", Cause: "Source doesn't contains the other map.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "source", @@ -588,7 +588,7 @@ func (a Asserter) mapContainsSubMap(src reflect.Value, has reflect.Value, msg [] a.fn(fmterror.Message{ Method: "Contain", Cause: "Source has the key but with different value.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "source", @@ -605,7 +605,7 @@ func (a Asserter) mapContainsSubMap(src reflect.Value, has reflect.Value, msg [] } } -func (a Asserter) stringContainsSub(src reflect.Value, has reflect.Value, msg []any) { +func (a Asserter) stringContainsSub(src reflect.Value, has reflect.Value, msg []Message) { a.TB.Helper() if strings.Contains(fmt.Sprint(src.Interface()), fmt.Sprint(has.Interface())) { return @@ -613,7 +613,7 @@ func (a Asserter) stringContainsSub(src reflect.Value, has reflect.Value, msg [] a.fn(fmterror.Message{ Method: "Contain", Cause: "String doesn't include sub string.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "string", @@ -627,7 +627,7 @@ func (a Asserter) stringContainsSub(src reflect.Value, has reflect.Value, msg [] }) } -func (a Asserter) NotContain(haystack, v any, msg ...any) { +func (a Asserter) NotContain(haystack, v any, msg ...Message) { a.TB.Helper() if !a.try(func(a Asserter) { a.Contain(haystack, v) }) { return @@ -635,7 +635,7 @@ func (a Asserter) NotContain(haystack, v any, msg ...any) { a.fn(fmterror.Message{ Method: "NotContain", Cause: "Source contains the received value", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "haystack", @@ -649,7 +649,7 @@ func (a Asserter) NotContain(haystack, v any, msg ...any) { }) } -func (a Asserter) ContainExactly(v, oth any /* slice | map */, msg ...any) { +func (a Asserter) ContainExactly(v, oth any /* slice | map */, msg ...Message) { a.TB.Helper() rv := reflect.ValueOf(v) @@ -713,7 +713,7 @@ func (a Asserter) ContainExactly(v, oth any /* slice | map */, msg ...any) { } } -func (a Asserter) containExactlyMap(exp reflect.Value, act reflect.Value, msg []any) { +func (a Asserter) containExactlyMap(exp reflect.Value, act reflect.Value, msg []Message) { a.TB.Helper() if a.eq(exp.Interface(), act.Interface()) { @@ -722,7 +722,7 @@ func (a Asserter) containExactlyMap(exp reflect.Value, act reflect.Value, msg [] a.fn(fmterror.Message{ Method: "ContainExactly", Cause: "SubMap content doesn't exactly match with expectations.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "expected", Value: exp.Interface()}, {Label: "actual", Value: act.Interface()}, @@ -730,14 +730,14 @@ func (a Asserter) containExactlyMap(exp reflect.Value, act reflect.Value, msg [] }) } -func (a Asserter) containExactlySlice(exp reflect.Value, act reflect.Value, msg []any) { +func (a Asserter) containExactlySlice(exp reflect.Value, act reflect.Value, msg []Message) { a.TB.Helper() if exp.Len() != act.Len() { a.fn(fmterror.Message{ Method: "ContainExactly", Cause: "Element count doesn't match", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "expected:", @@ -766,7 +766,7 @@ func (a Asserter) containExactlySlice(exp reflect.Value, act reflect.Value, msg a.fn(fmterror.Message{ Method: "ContainExactly", Cause: fmt.Sprintf("Element not found at index %d", i), - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "actual:", @@ -782,7 +782,7 @@ func (a Asserter) containExactlySlice(exp reflect.Value, act reflect.Value, msg } } -func (a Asserter) AnyOf(blk func(a *AnyOf), msg ...any) { +func (a Asserter) AnyOf(blk func(a *AnyOf), msg ...Message) { a.TB.Helper() anyOf := &AnyOf{TB: a.TB, Fail: a.Fail} defer anyOf.Finish(msg...) @@ -817,7 +817,7 @@ func (a Asserter) isEmpty(v any) bool { } // Empty gets whether the specified value is considered empty. -func (a Asserter) Empty(v any, msg ...any) { +func (a Asserter) Empty(v any, msg ...Message) { a.TB.Helper() if a.isEmpty(v) { return @@ -825,7 +825,7 @@ func (a Asserter) Empty(v any, msg ...any) { a.fn(fmterror.Message{ Method: "Empty", Cause: "Value was expected to be empty.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: v}, }, @@ -833,7 +833,7 @@ func (a Asserter) Empty(v any, msg ...any) { } // NotEmpty gets whether the specified value is considered empty. -func (a Asserter) NotEmpty(v any, msg ...any) { +func (a Asserter) NotEmpty(v any, msg ...Message) { a.TB.Helper() if !a.isEmpty(v) { return @@ -841,7 +841,7 @@ func (a Asserter) NotEmpty(v any, msg ...any) { a.fn(fmterror.Message{ Method: "NotEmpty", Cause: "Value was expected to be not empty.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: v}, }, @@ -851,7 +851,7 @@ func (a Asserter) NotEmpty(v any, msg ...any) { // ErrorIs allow you to assert an error value by an expectation. // ErrorIs allow asserting an error regardless if it's wrapped or not. // Suppose the implementation of the test subject later changes by wrap errors to add more context to the return error. -func (a Asserter) ErrorIs(err, oth error, msg ...any) { +func (a Asserter) ErrorIs(err, oth error, msg ...Message) { a.TB.Helper() if a.errorIs(err, oth) || a.errorIs(oth, err) { return @@ -859,7 +859,7 @@ func (a Asserter) ErrorIs(err, oth error, msg ...any) { a.fn(fmterror.Message{ Method: "ErrorIs", Cause: "error value is not what was expected", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "err", Value: err}, {Label: "oth", Value: oth}, @@ -886,7 +886,7 @@ func (a Asserter) errorIs(err, oth error) bool { return false } -func (a Asserter) Error(err error, msg ...any) { +func (a Asserter) Error(err error, msg ...Message) { a.TB.Helper() if err != nil { return @@ -894,14 +894,14 @@ func (a Asserter) Error(err error, msg ...any) { a.fn(fmterror.Message{ Method: "Error", Cause: "Expected an error, but got nil.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: err}, }, }) } -func (a Asserter) NoError(err error, msg ...any) { +func (a Asserter) NoError(err error, msg ...Message) { a.TB.Helper() if err == nil { return @@ -909,7 +909,7 @@ func (a Asserter) NoError(err error, msg ...any) { a.fn(fmterror.Message{ Method: "NoError", Cause: "Non-nil error value is received.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: err}, {Label: "error", Value: err.Error()}, @@ -917,14 +917,14 @@ func (a Asserter) NoError(err error, msg ...any) { }) } -func (a Asserter) Read(v any /* string | []byte */, r io.Reader, msg ...any) { +func (a Asserter) Read(v any /* string | []byte */, r io.Reader, msg ...Message) { const FnMethod = "Read" a.TB.Helper() if r == nil { a.fn(fmterror.Message{ Method: FnMethod, Cause: "io.Reader is nil", - Message: msg, + Message: toMsg(msg), }) return } @@ -933,7 +933,7 @@ func (a Asserter) Read(v any /* string | []byte */, r io.Reader, msg ...any) { a.fn(fmterror.Message{ Method: FnMethod, Cause: "Error occurred during io.Reader.Read", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: err}, {Label: "error", Value: err.Error()}, @@ -959,7 +959,7 @@ func (a Asserter) Read(v any /* string | []byte */, r io.Reader, msg ...any) { a.fn(fmterror.Message{ Method: FnMethod, Cause: "Read output is not as expected.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "expected value", Value: val}, {Label: "io.Reader content", Value: got}, @@ -967,14 +967,14 @@ func (a Asserter) Read(v any /* string | []byte */, r io.Reader, msg ...any) { }) } -func (a Asserter) ReadAll(r io.Reader, msg ...any) []byte { +func (a Asserter) ReadAll(r io.Reader, msg ...Message) []byte { a.TB.Helper() const FnMethod = "ReadAll" if r == nil { a.fn(fmterror.Message{ Method: FnMethod, Cause: "io.Reader is nil", - Message: msg, + Message: toMsg(msg), }) return nil } @@ -983,7 +983,7 @@ func (a Asserter) ReadAll(r io.Reader, msg ...any) []byte { a.fn(fmterror.Message{ Method: FnMethod, Cause: "Error occurred during io.ReadAll", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ {Label: "value", Value: err}, {Label: "error", Value: err.Error()}, @@ -994,13 +994,13 @@ func (a Asserter) ReadAll(r io.Reader, msg ...any) []byte { return bs } -func (a Asserter) Within(timeout time.Duration, blk func(context.Context), msg ...any) { +func (a Asserter) Within(timeout time.Duration, blk func(context.Context), msg ...Message) { a.TB.Helper() if !a.within(timeout, blk) { a.fn(fmterror.Message{ Method: "Within", Cause: "Expected to finish within the timeout duration.", - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "timeout", @@ -1011,13 +1011,13 @@ func (a Asserter) Within(timeout time.Duration, blk func(context.Context), msg . } } -func (a Asserter) NotWithin(timeout time.Duration, blk func(context.Context), msg ...any) { +func (a Asserter) NotWithin(timeout time.Duration, blk func(context.Context), msg ...Message) { a.TB.Helper() if a.within(timeout, blk) { a.fn(fmterror.Message{ Method: "NotWithin", Cause: `Expected to not finish within the timeout duration.`, - Message: msg, + Message: toMsg(msg), Values: []fmterror.Value{ { Label: "timeout", diff --git a/assert/Asserter_test.go b/assert/Asserter_test.go index 951e5df..8a4b79d 100644 --- a/assert/Asserter_test.go +++ b/assert/Asserter_test.go @@ -81,14 +81,13 @@ func TestAsserter_True(t *testing.T) { t.Run(`when false passed`, func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - expectedMsg := []interface{}{"foo", "bar", "baz"} - subject.True(false, expectedMsg...) + subject.True(false, "foo", "bar", "baz") Equal(t, dtb.IsFailed, true) - AssertFailMsg(t, dtb, expectedMsg) + AssertFailMsg(t, dtb, []assert.Message{"foo", "bar", "baz"}) }) } -func AssertFailMsg(tb testing.TB, dtb *doubles.TB, msgs []any) { +func AssertFailMsg[T any](tb testing.TB, dtb *doubles.TB, msgs []T) { tb.Helper() logs := dtb.Logs.String() for _, msg := range msgs { @@ -100,10 +99,9 @@ func TestAsserter_False(t *testing.T) { t.Run(`when true passed`, func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - expectedMsg := []interface{}{"hello", "world", 42} - subject.False(true, expectedMsg...) + subject.False(true, "hello", "world", "42") Equal(t, dtb.IsFailed, true) - AssertFailMsg(t, dtb, expectedMsg) + AssertFailMsg(t, dtb, []any{"hello", "world", "42"}) }) t.Run(`when false passed`, func(t *testing.T) { dtb := &doubles.TB{} @@ -129,16 +127,16 @@ func TestAsserter_Nil(t *testing.T) { t.Run(`when non nil value is passed`, func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - expectedMsg := []interface{}{"foo", "bar", "baz"} - subject.Nil(errors.New("not nil"), expectedMsg...) + expectedMsg := []assert.Message{"foo", "bar", "baz"} + subject.Nil(errors.New("not nil"), "foo", "bar", "baz") Equal(t, dtb.IsFailed, true) AssertFailMsg(t, dtb, expectedMsg) }) t.Run("when non nil zero value is passed", func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - expectedMsg := []interface{}{"foo", "bar", "baz"} - subject.Nil("", expectedMsg...) // zero string value + expectedMsg := []assert.Message{"foo", "bar", "baz"} + subject.Nil("", "foo", "bar", "baz") // zero string value Equal(t, dtb.IsFailed, true) AssertFailMsg(t, dtb, expectedMsg) }) @@ -148,8 +146,8 @@ func TestAsserter_NotNil(t *testing.T) { t.Run(`when nil passed`, func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - msg := []interface{}{"foo", "bar", "baz"} - subject.NotNil(nil, msg...) + msg := []assert.Message{"foo", "bar", "baz"} + subject.NotNil(nil, "foo", "bar", "baz") AssertFailMsg(t, dtb, msg) }) t.Run(`when pointer with nil value passed, then it is refused as nil`, func(t *testing.T) { @@ -400,13 +398,16 @@ func TestAsserter_Equal(t *testing.T) { t.Logf("expected: %#v", tc.Expected) t.Logf("actual: %#v", tc.Actual) - expectedMsg := []interface{}{rnd.StringN(3), rnd.StringN(3)} + msg1 := rnd.StringN(3) + msg2 := rnd.StringN(3) dtb := &doubles.TB{} subject := asserter(dtb) - subject.Equal(tc.Expected, tc.Actual, expectedMsg...) + subject.Equal(tc.Expected, tc.Actual, + assert.Message(msg1), + assert.Message(msg2)) Equal(t, dtb.IsFailed, tc.IsFailed) if tc.IsFailed { - AssertFailMsg(t, dtb, expectedMsg) + AssertFailMsg(t, dtb, []any{msg1, msg2}) } }) } @@ -663,10 +664,16 @@ func TestAsserter_NotEqual(t *testing.T) { } { tc := tc t.Run(tc.Desc, func(t *testing.T) { - expectedMsg := []interface{}{rnd.StringN(3), rnd.StringN(3)} + + msg1 := rnd.StringN(3) + msg2 := rnd.StringN(3) + expectedMsg := []interface{}{msg1, msg2} + dtb := &doubles.TB{} subject := asserter(dtb) - subject.NotEqual(tc.Expected, tc.Actual, expectedMsg...) + subject.NotEqual(tc.Expected, tc.Actual, + assert.Message(msg1), + assert.Message(msg2)) Equal(t, dtb.IsFailed, tc.IsFailed) if tc.IsFailed { AssertFailMsg(t, dtb, expectedMsg) @@ -698,10 +705,10 @@ func TestAsserter_NotEqual_typeSafety(t *testing.T) { }) } -func AssertContainsWith(tb testing.TB, isFailed bool, contains func(a assert.Asserter, msg []interface{})) { +func AssertContainsWith(tb testing.TB, isFailed bool, contains func(a assert.Asserter, msg []assert.Message)) { tb.Helper() rnd := random.New(random.CryptoSeed{}) - expectedMsg := []interface{}{rnd.StringN(3), rnd.StringN(3)} + expectedMsg := []assert.Message{assert.Message(rnd.StringN(3)), assert.Message(rnd.StringN(3))} dtb := &doubles.TB{} subject := asserter(dtb) contains(subject, expectedMsg) @@ -715,7 +722,7 @@ func AssertContainsTestCase(src, has interface{}, isFailed bool) func(*testing.T return func(t *testing.T) { t.Helper() - AssertContainsWith(t, isFailed, func(a assert.Asserter, msg []interface{}) { + AssertContainsWith(t, isFailed, func(a assert.Asserter, msg []assert.Message) { a.Contain(src, has, msg...) }) } @@ -725,7 +732,7 @@ func AssertContainExactlyTestCase(src, oth interface{}, isFailed bool) func(*tes return func(t *testing.T) { t.Helper() - AssertContainsWith(t, isFailed, func(a assert.Asserter, msg []interface{}) { + AssertContainsWith(t, isFailed, func(a assert.Asserter, msg []assert.Message) { a.ContainExactly(src, oth, msg...) }) } @@ -930,7 +937,7 @@ func TestAsserter_Subset(t *testing.T) { }, } { t.Run(tc.Desc, func(t *testing.T) { - AssertContainsWith(t, tc.IsFailed, func(a assert.Asserter, msg []interface{}) { + AssertContainsWith(t, tc.IsFailed, func(a assert.Asserter, msg []assert.Message) { a.Sub(tc.Slice, tc.Subset, msg...) }) }) @@ -1389,7 +1396,7 @@ func AssertNotContainTestCase(src, has interface{}, isFailed bool) func(*testing return func(t *testing.T) { t.Helper() - AssertContainsWith(t, isFailed, func(a assert.Asserter, msg []interface{}) { + AssertContainsWith(t, isFailed, func(a assert.Asserter, msg []assert.Message) { a.NotContain(src, has, msg...) }) } @@ -1607,7 +1614,9 @@ func TestAsserter_Empty(t *testing.T) { t.Run(tc.Desc, func(t *testing.T) { dtb := &doubles.TB{} a := asserter(dtb) - expectedMSG := []interface{}{rnd.String(), rnd.Int()} + expectedMSG := []assert.Message{ + assert.Message(rnd.String()), + assert.Message(fmt.Sprint(rnd.Int()))} a.Empty(tc.V, expectedMSG...) Equal(t, tc.IsFailed, dtb.IsFailed) if tc.IsFailed { @@ -1718,7 +1727,9 @@ func TestAsserter_NotEmpty(t *testing.T) { t.Run(tc.Desc, func(t *testing.T) { dtb := &doubles.TB{} a := asserter(dtb) - expectedMSG := []interface{}{rnd.String(), rnd.Int()} + expectedMSG := []assert.Message{ + assert.Message(rnd.String()), + assert.Message(fmt.Sprint(rnd.Int()))} a.NotEmpty(tc.V, expectedMSG...) Equal(t, tc.IsFailed, dtb.IsFailed) if tc.IsFailed { @@ -1747,7 +1758,9 @@ func TestAsserter_NotEmpty(t *testing.T) { func TestAsserter_ErrorIs(t *testing.T) { rnd := random.New(random.CryptoSeed{}) subject := func(tb testing.TB, isFailed bool, expected, actual error) (failed bool) { - expectedMSG := []interface{}{rnd.String(), rnd.Int()} + expectedMSG := []assert.Message{ + assert.Message(rnd.String()), + assert.Message(fmt.Sprint(rnd.Int()))} dtb := &doubles.TB{} a := assert.Asserter{TB: dtb, Fail: dtb.Fail} a.ErrorIs(expected, actual, expectedMSG...) @@ -1822,7 +1835,7 @@ func TestAsserter_Error(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - expectedMsg := []interface{}{"foo", "bar", "baz"} + expectedMsg := []assert.Message{"foo", "bar", "baz"} subject.Error(nil, expectedMsg...) Equal(t, dtb.IsFailed, true) AssertFailMsg(t, dtb, expectedMsg) @@ -1846,7 +1859,7 @@ func TestAsserter_NoError(t *testing.T) { t.Run(`when non-nil error value is passed`, func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - expectedMsg := []interface{}{"foo", "bar", "baz"} + expectedMsg := []assert.Message{"foo", "bar", "baz"} subject.NoError(errors.New("boom"), expectedMsg...) Equal(t, dtb.IsFailed, true) AssertFailMsg(t, dtb, expectedMsg) @@ -1897,7 +1910,7 @@ func TestAsserter_Read(t *testing.T) { t.Run(tc.Desc, func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) - msg := []any{"asd", "dsa"} + msg := []assert.Message{"asd", "dsa"} subject.Read(tc.Expected, tc.Reader, msg...) Equal(t, tc.Failed, dtb.IsFailed) if tc.Failed { @@ -1909,8 +1922,8 @@ func TestAsserter_Read(t *testing.T) { func TestAsserter_ReadAll(t *testing.T) { rnd := random.New(random.CryptoSeed{}) - msg := []any{rnd.String(), rnd.String()} - logMSG := strings.TrimSpace(fmt.Sprintln(msg...)) + msg := []assert.Message{assert.Message(rnd.String()), assert.Message(rnd.String())} + logMSG := strings.TrimSpace(fmt.Sprintln(msg[0], msg[1])) t.Run("when io.Reader has readable content", func(t *testing.T) { dtb := &doubles.TB{} subject := asserter(dtb) diff --git a/assert/Waiter_test.go b/assert/Waiter_test.go index f6e99cd..e9b3369 100644 --- a/assert/Waiter_test.go +++ b/assert/Waiter_test.go @@ -57,7 +57,7 @@ func SpecWaiter(tb testing.TB) { avg := totalDuration / time.Duration(samplingCount) t.Logf(`min:%s max:%s avg:%s`, min, max, avg) assert.Must(t).True(min <= avg, `#Wait() should run at least for the duration of WaitDuration`) - assert.Must(t).True(avg <= max, fmt.Sprintf(`#Wait() shouldn't run more than the WaitDuration + %d%% tolerance`, int(extraTimePercentage*100))) + assert.Must(t).True(avg <= max, assert.Message(fmt.Sprintf(`#Wait() shouldn't run more than the WaitDuration + %d%% tolerance`, int(extraTimePercentage*100)))) }) } diff --git a/assert/example_test.go b/assert/example_test.go index 6cdd5ec..42e8059 100644 --- a/assert/example_test.go +++ b/assert/example_test.go @@ -410,9 +410,9 @@ func ExampleNotEqual() { func ExampleContain() { var tb testing.TB - assert.Must(tb).Contain(tb, []int{1, 2, 3}, 3, "optional assertion explanation") - assert.Must(tb).Contain(tb, []int{1, 2, 3}, []int{1, 2}, "optional assertion explanation") - assert.Must(tb).Contain(tb, + assert.Must(tb).Contain([]int{1, 2, 3}, 3, "optional assertion explanation") + assert.Must(tb).Contain([]int{1, 2, 3}, []int{1, 2}, "optional assertion explanation") + assert.Must(tb).Contain( map[string]int{"The Answer": 42, "oth": 13}, map[string]int{"The Answer": 42}, "optional assertion explanation") @@ -420,9 +420,9 @@ func ExampleContain() { func ExampleNotContain() { var tb testing.TB - assert.Must(tb).NotContain(tb, []int{1, 2, 3}, 42) - assert.Must(tb).NotContain(tb, []int{1, 2, 3}, []int{1, 2, 42}) - assert.Must(tb).NotContain(tb, + assert.Must(tb).NotContain([]int{1, 2, 3}, 42) + assert.Must(tb).NotContain([]int{1, 2, 3}, []int{1, 2, 42}) + assert.Must(tb).NotContain( map[string]int{"The Answer": 42, "oth": 13}, map[string]int{"The Answer": 41}) } diff --git a/assert/message.go b/assert/message.go new file mode 100644 index 0000000..541b4fd --- /dev/null +++ b/assert/message.go @@ -0,0 +1,11 @@ +package assert + +type Message string + +func toMsg(msg []Message) []any { + var out []any + for _, m := range msg { + out = append(out, m) + } + return out +} diff --git a/assert/message_test.go b/assert/message_test.go new file mode 100644 index 0000000..b0a450e --- /dev/null +++ b/assert/message_test.go @@ -0,0 +1,23 @@ +package assert_test + +import ( + "github.com/adamluzsi/testcase/assert" + "github.com/adamluzsi/testcase/internal/doubles" + "github.com/adamluzsi/testcase/random" + "testing" +) + +func ExampleMessage() { + var tb testing.TB + + assert.True(tb, true, "this is a const which is interpreted as assertion.Message") +} + +func TestMessage(t *testing.T) { + dtb := &doubles.TB{} + a := asserter(dtb) + rnd := random.New(random.CryptoSeed{}) + exp := assert.Message(rnd.String()) + a.True(false, exp) + assert.Contain(t, dtb.Logs.String(), string(exp)) +} diff --git a/assert/pkgfunc.go b/assert/pkgfunc.go index 99e78fc..8e30420 100644 --- a/assert/pkgfunc.go +++ b/assert/pkgfunc.go @@ -7,117 +7,117 @@ import ( "time" ) -func True(tb testing.TB, v bool, msg ...any) { +func True(tb testing.TB, v bool, msg ...Message) { tb.Helper() Must(tb).True(v, msg...) } -func False(tb testing.TB, v bool, msg ...any) { +func False(tb testing.TB, v bool, msg ...Message) { tb.Helper() Must(tb).False(v, msg...) } -func Nil(tb testing.TB, v any, msg ...any) { +func Nil(tb testing.TB, v any, msg ...Message) { tb.Helper() Must(tb).Nil(v, msg...) } -func NotNil(tb testing.TB, v any, msg ...any) { +func NotNil(tb testing.TB, v any, msg ...Message) { tb.Helper() Must(tb).NotNil(v, msg...) } -func Empty(tb testing.TB, v any, msg ...any) { +func Empty(tb testing.TB, v any, msg ...Message) { tb.Helper() Must(tb).Empty(v, msg...) } -func NotEmpty(tb testing.TB, v any, msg ...any) { +func NotEmpty(tb testing.TB, v any, msg ...Message) { tb.Helper() Must(tb).NotEmpty(v, msg...) } -func Panic(tb testing.TB, blk func(), msg ...any) any { +func Panic(tb testing.TB, blk func(), msg ...Message) any { tb.Helper() return Must(tb).Panic(blk, msg...) } -func NotPanic(tb testing.TB, blk func(), msg ...any) { +func NotPanic(tb testing.TB, blk func(), msg ...Message) { tb.Helper() Must(tb).NotPanic(blk, msg...) } -func Equal[T any](tb testing.TB, v, oth T, msg ...any) { +func Equal[T any](tb testing.TB, v, oth T, msg ...Message) { tb.Helper() Must(tb).Equal(v, oth, msg...) } -func NotEqual[T any](tb testing.TB, v, oth T, msg ...any) { +func NotEqual[T any](tb testing.TB, v, oth T, msg ...Message) { tb.Helper() Must(tb).NotEqual(v, oth, msg...) } -func Contain(tb testing.TB, haystack, needle any, msg ...any) { +func Contain(tb testing.TB, haystack, needle any, msg ...Message) { tb.Helper() Must(tb).Contain(haystack, needle, msg...) } -func NotContain(tb testing.TB, haystack, v any, msg ...any) { +func NotContain(tb testing.TB, haystack, v any, msg ...Message) { tb.Helper() Must(tb).NotContain(haystack, v, msg...) } -func ContainExactly[T any /* Map or Slice */](tb testing.TB, v, oth T, msg ...any) { +func ContainExactly[T any /* Map or Slice */](tb testing.TB, v, oth T, msg ...Message) { tb.Helper() Must(tb).ContainExactly(v, oth, msg...) } -func Sub[T any](tb testing.TB, haystack, needle []T, msg ...any) { +func Sub[T any](tb testing.TB, haystack, needle []T, msg ...Message) { tb.Helper() Must(tb).Sub(haystack, needle, msg...) } -func ErrorIs(tb testing.TB, err, oth error, msg ...any) { +func ErrorIs(tb testing.TB, err, oth error, msg ...Message) { tb.Helper() Must(tb).ErrorIs(err, oth, msg...) } -func Error(tb testing.TB, err error, msg ...any) { +func Error(tb testing.TB, err error, msg ...Message) { tb.Helper() Must(tb).Error(err, msg...) } -func NoError(tb testing.TB, err error, msg ...any) { +func NoError(tb testing.TB, err error, msg ...Message) { tb.Helper() Must(tb).NoError(err, msg...) } -func Read[T string | []byte](tb testing.TB, v T, r io.Reader, msg ...any) { +func Read[T string | []byte](tb testing.TB, v T, r io.Reader, msg ...Message) { tb.Helper() Must(tb).Read(v, r, msg...) } -func ReadAll(tb testing.TB, r io.Reader, msg ...any) []byte { +func ReadAll(tb testing.TB, r io.Reader, msg ...Message) []byte { tb.Helper() return Must(tb).ReadAll(r, msg...) } -func Within(tb testing.TB, timeout time.Duration, blk func(context.Context), msg ...any) { +func Within(tb testing.TB, timeout time.Duration, blk func(context.Context), msg ...Message) { tb.Helper() Must(tb).Within(timeout, blk, msg...) } -func NotWithin(tb testing.TB, timeout time.Duration, blk func(context.Context), msg ...any) { +func NotWithin(tb testing.TB, timeout time.Duration, blk func(context.Context), msg ...Message) { tb.Helper() Must(tb).NotWithin(timeout, blk, msg...) } -func Match[T string | []byte](tb testing.TB, v T, expr string, msg ...any) { +func Match[T string | []byte](tb testing.TB, v T, expr string, msg ...Message) { tb.Helper() Must(tb).Match(string(v), expr, msg...) } -func NotMatch[T string | []byte](tb testing.TB, v T, expr string, msg ...any) { +func NotMatch[T string | []byte](tb testing.TB, v T, expr string, msg ...Message) { tb.Helper() Must(tb).NotMatch(string(v), expr, msg...) } diff --git a/examples_test.go b/examples_test.go index b4a77fc..21fc7c5 100644 --- a/examples_test.go +++ b/examples_test.go @@ -75,14 +75,14 @@ func ExampleSpec() { s.Then(`it will report false`, func(t *testcase.T) { t.Must.True(act(t), - fmt.Sprintf(`it was expected that %q will be reported to be not lowercase`, input.Get(t))) + assert.Message(fmt.Sprintf(`it was expected that %q will be reported to be not lowercase`, input.Get(t)))) }) }) s.Then(`it will return true`, func(t *testcase.T) { t.Must.True(act(t), - fmt.Sprintf(`it was expected that the %q will re reported to be lowercase`, input.Get(t))) + assert.Message(fmt.Sprintf(`it was expected that the %q will re reported to be lowercase`, input.Get(t)))) }) }) diff --git a/internal/caller/caller_test.go b/internal/caller/caller_test.go index 011a4f2..94a965f 100644 --- a/internal/caller/caller_test.go +++ b/internal/caller/caller_test.go @@ -58,15 +58,16 @@ func (*GetCallFixture) TestPointerMethod(tb testing.TB) { func (f GetCallFixture) TestLambdaInMethod(tb testing.TB) { var run bool + // TODO: if this method wrapped with two lambda + // then for some reason it yields no results. + // figure out why and then fix it func() { - func() { - cfn, ok := caller.GetFunc() - assert.True(tb, ok) - assert.Equal(tb, "TestLambdaInMethod", cfn.Funcion) - assert.Equal(tb, "GetCallFixture", cfn.Receiver) - assert.Equal(tb, "caller_test", cfn.Package) - run = true - }() + cfn, ok := caller.GetFunc() + assert.True(tb, ok) + assert.Equal(tb, "TestLambdaInMethod", cfn.Funcion) + assert.Equal(tb, "GetCallFixture", cfn.Receiver) + assert.Equal(tb, "caller_test", cfn.Package) + run = true }() assert.True(tb, run) } diff --git a/let/std_test.go b/let/std_test.go index c914887..31c3d22 100644 --- a/let/std_test.go +++ b/let/std_test.go @@ -49,14 +49,14 @@ func TestSTD_smoke(t *testing.T) { t.Must.NotEmpty(StringNC.Get(t)) t.Must.True(42 == len(StringNC.Get(t))) charsterIs(t, random.CharsetASCII(), StringNC.Get(t)) - t.Must.NotEmpty(t, Int.Get(t)) - t.Must.NotEmpty(t, IntN.Get(t)) - t.Must.NotEmpty(t, IntB.Get(t)) - t.Must.NotEmpty(t, Time.Get(t)) - t.Must.NotEmpty(t, TimeB.Get(t)) + t.Must.NotEmpty(Int.Get(t)) + t.Must.NotEmpty(IntN.Get(t)) + t.Must.NotEmpty(IntB.Get(t)) + t.Must.NotEmpty(Time.Get(t)) + t.Must.NotEmpty(TimeB.Get(t)) t.Must.True(TimeB.Get(t).After(time.Now().AddDate(-1, 0, -1))) - t.Must.NotEmpty(t, UUID.Get(t)) - t.Must.NotEmpty(t, Element.Get(t)) + t.Must.NotEmpty(UUID.Get(t)) + t.Must.NotEmpty(Element.Get(t)) t.Eventually(func(it assert.It) { it.Must.True(Bool.Get(testcase.ToT(&t.TB))) }) diff --git a/random/Random_test.go b/random/Random_test.go index 7f729f6..06643ee 100644 --- a/random/Random_test.go +++ b/random/Random_test.go @@ -137,7 +137,7 @@ func SpecRandomMethods(s *testcase.Spec, rnd testcase.Var[*random.Random]) { resSet[res] = struct{}{} t.Must.Contain(pool, res) } - assert.Must(t).True(len(resSet) > 1, fmt.Sprintf(`%#v`, resSet)) + assert.Must(t).True(len(resSet) > 1, assert.Message(fmt.Sprintf(`%#v`, resSet))) }) }) diff --git a/tags_test.go b/tags_test.go index 1f999af..18ab3b2 100644 --- a/tags_test.go +++ b/tags_test.go @@ -157,6 +157,6 @@ func assertTestRan(t *testing.T, setup func(s *Spec), expected bool) { }) assert.Must(t).Equal(expected, actually, - fmt.Sprintf(`then it is expected to %srun in sub spec as well`, modifier)) + assert.Message(fmt.Sprintf(`then it is expected to %srun in sub spec as well`, modifier))) }) }