func Code(fn any) TestDeep
Code operator allows to check data using a custom function. So fn is a function that must take one parameter whose type must be the same as the type of the compared value.
fn can return a single bool
kind value, telling that yes or no
the custom test is successful:
td.Cmp(t, gotTime,
td.Code(func(date time.Time) bool {
return date.Year() == 2018
}))
or two values (bool
, string
) kinds. The bool
value has the same
meaning as above, and the string
value is used to describe the
test when it fails:
td.Cmp(t, gotTime,
td.Code(func(date time.Time) (bool, string) {
if date.Year() == 2018 {
return true, ""
}
return false, "year must be 2018"
}))
or a single error
value. If the returned error
is nil
, the test
succeeded, else the error
contains the reason of failure:
td.Cmp(t, gotJsonRawMesg,
td.Code(func(b json.RawMessage) error {
var c map[string]int
err := json.Unmarshal(b, &c)
if err != nil {
return err
}
if c["test"] != 42 {
return fmt.Errorf(`key "test" does not match 42`)
}
return nil
}))
This operator allows to handle any
specific comparison not handled
by standard operators.
It is not recommended to call Cmp
(or any
other Cmp*
functions or *T
methods) inside the body of fn, because of
confusion produced by output in case of failure. When the data
needs to be transformed before being compared again, Smuggle
operator should be used instead.
But in some cases it can be better to handle yourself the
comparison than to chain TestDeep operators. In this case, fn can
be a function receiving one or two *T
as first parameters and
returning no values.
When fn expects one *T
parameter, it is directly derived from the
testing.TB
instance passed originally to Cmp
(or its derivatives)
using NewT
:
td.Cmp(t, httpRequest, td.Code(func(t *td.T, r *http.Request) {
token, err := DecodeToken(r.Header.Get("X-Token-1"))
if t.CmpNoError(err) {
t.True(token.OK())
}
}))
When fn expects two *T
parameters, they are directly derived from
the testing.TB
instance passed originally to Cmp
(or its derivatives)
using AssertRequire
:
td.Cmp(t, httpRequest, td.Code(func(assert, require *td.T, r *http.Request) {
token, err := DecodeToken(r.Header.Get("X-Token-1"))
require.CmpNoError(err)
assert.True(token.OK())
}))
Note that these forms do not work when there is no initial
testing.TB
instance, like when using EqDeeplyError
or
EqDeeply
functions, or when the Code operator is called behind
the following operators, as they just check if a match occurs
without raising an error
: Any
, Bag
, Contains
, ContainsKey
,
None
, Not
, NotAny
, Set
, SubBagOf
, SubSetOf
,
SuperBagOf
and SuperSetOf
.
RootName is inherited but not the current path, but it can be recovered if needed:
got := map[string]int{"foo": 123}
td.NewT(t).
RootName("PIPO").
Cmp(got, td.Map(map[string]int{}, td.MapEntries{
"foo": td.Code(func(t *td.T, n int) {
t.Cmp(n, 124) // inherit only RootName
t.RootName(t.Config.OriginalPath()).Cmp(n, 125) // recover current path
t.RootName("").Cmp(n, 126) // undo RootName inheritance
}),
}))
produces the following errors:
--- FAIL: TestCodeCustom (0.00s)
td_code_test.go:339: Failed test
PIPO: values differ ← inherit only RootName
got: 123
expected: 124
td_code_test.go:338: Failed test
PIPO["foo"]: values differ ← recover current path
got: 123
expected: 125
td_code_test.go:342: Failed test
DATA: values differ ← undo RootName inheritance
got: 123
expected: 126
TypeBehind
method returns the reflect.Type
of last parameter of fn.
See also Code godoc.
func CmpCode(t TestingT, got, fn any, args ...any) bool
CmpCode is a shortcut for:
td.Cmp(t, got, td.Code(fn), args...)
See above for details.
Returns true if the test is OK, false if it fails.
If t is a *T
then its Config field is inherited.
args… are optional and allow to name the test. This name is
used in case of failure to qualify the test. If len(args) > 1
and
the first item of args is a string
and contains a ‘%’ rune
then
fmt.Fprintf
is used to compose the name, else args are passed to
fmt.Fprint
. Do not forget it is the name of the test, not the
reason of a potential failure.
See also CmpCode godoc.
func (t *T) Code(got, fn any, args ...any) bool
Code is a shortcut for:
t.Cmp(got, td.Code(fn), args...)
See above for details.
Returns true if the test is OK, false if it fails.
args… are optional and allow to name the test. This name is
used in case of failure to qualify the test. If len(args) > 1
and
the first item of args is a string
and contains a ‘%’ rune
then
fmt.Fprintf
is used to compose the name, else args are passed to
fmt.Fprint
. Do not forget it is the name of the test, not the
reason of a potential failure.
See also T.Code godoc.