SStruct

func SStruct(model interface{}, expectedFields StructFields) TestDeep

SStruct operator (aka strict-Struct) compares the contents of a struct or a pointer on a struct against values of model (if any) and the values of expectedFields. The zero values are compared too even if they are omitted from expectedFields: that is the difference with Struct operator.

model must be the same type as compared data.

expectedFields can be nil, if no TestDeep operators are involved.

To ignore a field, one has to specify it in expectedFields and use the Ignore operator.

td.Cmp(t, got, td.SStruct(
  Person{
    Name: "John Doe",
  },
  td.StructFields{
    "Age":      td.Between(40, 45),
    "Children": td.Ignore(),
  }),
)

expectedFields can also contain regexps or shell patterns to match multiple fields not explicitly listed in model and in expectedFields. Regexps are prefixed by “=~” or “!~” to respectively match or don’t-match. Shell patterns are prefixed by “=” or “!” to respectively match or don’t-match.

td.Cmp(t, got, td.SStruct(
  Person{
    Name: "John Doe",
  },
  td.StructFields{
    "=*At":     td.Lte(time.Now()), // matches CreatedAt & UpdatedAt fields using shell pattern
    "=~^[a-z]": td.Ignore(),        // explicitly ignore private fields using a regexp
  }),
)

When several patterns can match a same field, it is advised to tell go-testdeep in which order patterns should be tested, as once a pattern matches a field, the other patterns are ignored for this field. To do so, each pattern can be prefixed by a number, as in:

td.Cmp(t, got, td.SStruct(
  Person{
    Name: "John Doe",
  },
  td.StructFields{
    "1=*At":     td.Lte(time.Now()),
    "2=~^[a-z]": td.NotNil(),
  }),
)

This way, “*At” shell pattern is always used before “^[a-z]” regexp, so if a field “createdAt” exists it is tested against time.Now() and never against NotNil. A pattern without a prefix number is the same as specifying “0” as prefix.

To make it clearer, some spaces can be added, as well as bigger numbers used:

td.Cmp(t, got, td.SStruct(
  Person{
    Name: "John Doe",
  },
  td.StructFields{
    " 900 =  *At":    td.Lte(time.Now()),
    "2000 =~ ^[a-z]": td.NotNil(),
  }),
)

The following example combines all possibilities:

td.Cmp(t, got, td.SStruct(
  Person{
    NickName: "Joe",
  },
  td.StructFields{
    "Firstname":               td.Any("John", "Johnny"),
    "1 =  *[nN]ame":           td.NotEmpty(), // matches LastName, lastname, …
    "2 !  [A-Z]*":             td.NotZero(),  // matches all private fields
    "3 =~ ^(Crea|Upda)tedAt$": td.Gte(time.Now()),
    "4 !~ ^(Dogs|Children)$":  td.Zero(),   // matches all remaining fields except Dogs and Children
    "5 =~ .":                  td.NotNil(), // matches all remaining fields (same as "5 = *")
  }),
)

During a match, all expected and zero fields must be found to succeed.

TypeBehind method returns the reflect.Type of model.

See also SStruct godoc.

Examples

Base example
Patterns example

CmpSStruct shortcut

func CmpSStruct(t TestingT, got, model interface{}, expectedFields StructFields, args ...interface{}) bool

CmpSStruct is a shortcut for:

td.Cmp(t, got, td.SStruct(model, expectedFields), 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 CmpSStruct godoc.

Examples

Base example
Patterns example

T.SStruct shortcut

func (t *T) SStruct(got, model interface{}, expectedFields StructFields, args ...interface{}) bool

SStruct is a shortcut for:

t.Cmp(got, td.SStruct(model, expectedFields), 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.SStruct godoc.

Examples

Base example
Patterns example