How to use anyStruct method of td Package

Best Go-testdeep code snippet using td.anyStruct

td_struct.go

Source:td_struct.go Github

copy

Full Screen

...200 "(STRUCT|&STRUCT, EXPECTED_FIELDS)",201 model, 1, true)202 return &st, reflect.Value{}203}204func anyStruct(model any, expectedFields StructFields, strict bool) *tdStruct {205 st, vmodel := newStruct(model, strict)206 if st.err != nil {207 return st208 }209 st.expectedFields = make([]fieldInfo, 0, len(expectedFields))210 checkedFields := make(map[string]bool, len(expectedFields))211 var matchers fieldMatcherSlice //nolint: prealloc212 // Check that all given fields are available in model213 stType := st.expectedType214 for fieldName, expectedValue := range expectedFields {215 field, found := stType.FieldByName(fieldName)216 if found {217 st.addExpectedValue(field, expectedValue, "")218 if st.err != nil {219 return st220 }221 checkedFields[fieldName] = false222 continue223 }224 // overwrite model field: ">fieldName", "> fieldName"225 if strings.HasPrefix(fieldName, ">") {226 name := strings.TrimSpace(fieldName[1:])227 field, found = stType.FieldByName(name)228 if !found {229 st.err = ctxerr.OpBad(st.location.Func,230 "struct %s has no field %q (from %q)", stType, name, fieldName)231 return st232 }233 st.addExpectedValue(234 field, expectedValue,235 fmt.Sprintf(" (from %q)", fieldName),236 )237 if st.err != nil {238 return st239 }240 checkedFields[name] = true241 continue242 }243 // matcher: "=~At$", "!~At$", "=*At", "!*At"244 matcher, err := newFieldMatcher(fieldName, expectedValue)245 if err != nil {246 if err == errNotAMatcher {247 st.err = ctxerr.OpBad(st.location.Func,248 "struct %s has no field %q", stType, fieldName)249 } else {250 st.err = ctxerr.OpBad(st.location.Func, err.Error())251 }252 return st253 }254 matchers = append(matchers, matcher)255 }256 // Get all field names257 allFields := map[string]struct{}{}258 stType.FieldByNameFunc(func(fieldName string) bool {259 allFields[fieldName] = struct{}{}260 return false261 })262 // Check initialized fields in model263 if vmodel.IsValid() {264 for fieldName := range allFields {265 overwrite, alreadySet := checkedFields[fieldName]266 if overwrite {267 continue268 }269 field, _ := stType.FieldByName(fieldName)270 if field.Anonymous {271 continue272 }273 vfield := vmodel.FieldByIndex(field.Index)274 // Try to force access to unexported fields275 fieldIf, ok := dark.GetInterface(vfield, true)276 if !ok {277 // Probably in an environment where "unsafe" package is forbidden… :(278 fmt.Fprintf(os.Stderr, //nolint: errcheck279 "%s(): field %s is unexported and cannot be overridden, skip it from model.\n",280 st.location.Func,281 fieldName)282 continue283 }284 // If non-zero field285 if !reflect.DeepEqual(reflect.Zero(field.Type).Interface(), fieldIf) {286 if alreadySet {287 st.err = ctxerr.OpBad(st.location.Func,288 "non zero field %s in model already exists in expectedFields",289 fieldName)290 return st291 }292 st.expectedFields = append(st.expectedFields, fieldInfo{293 name: fieldName,294 expected: vfield,295 index: field.Index,296 unexported: field.PkgPath != "",297 })298 checkedFields[fieldName] = true299 }300 }301 }302 // At least one matcher (regexp/shell pattern)303 if matchers != nil {304 sort.Sort(matchers) // always process matchers in the same order305 for _, m := range matchers {306 for fieldName := range allFields {307 if _, ok := checkedFields[fieldName]; ok {308 continue309 }310 field, _ := stType.FieldByName(fieldName)311 if field.Anonymous {312 continue313 }314 ok, err := m.match(fieldName)315 if err != nil {316 st.err = ctxerr.OpBad(st.location.Func,317 "bad shell pattern field %#q: %s", m.name, err)318 return st319 }320 if ok == m.ok {321 st.addExpectedValue(322 field, m.expected,323 fmt.Sprintf(" (from pattern %#q)", m.name),324 )325 if st.err != nil {326 return st327 }328 checkedFields[fieldName] = true329 }330 }331 }332 }333 // If strict, fill non explicitly expected fields to zero334 if strict {335 for fieldName := range allFields {336 if _, ok := checkedFields[fieldName]; ok {337 continue338 }339 field, _ := stType.FieldByName(fieldName)340 if field.Anonymous {341 continue342 }343 st.expectedFields = append(st.expectedFields, fieldInfo{344 name: fieldName,345 expected: reflect.New(field.Type).Elem(), // zero346 index: field.Index,347 unexported: field.PkgPath != "",348 })349 }350 }351 sort.Sort(st.expectedFields)352 return st353}354func (s *tdStruct) addExpectedValue(field reflect.StructField, expectedValue any, ctxInfo string) {355 var vexpectedValue reflect.Value356 if expectedValue == nil {357 switch field.Type.Kind() {358 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map,359 reflect.Ptr, reflect.Slice:360 vexpectedValue = reflect.Zero(field.Type) // change to a typed nil361 default:362 s.err = ctxerr.OpBad(s.location.Func,363 "expected value of field %s%s cannot be nil as it is a %s",364 field.Name, ctxInfo, field.Type)365 return366 }367 } else {368 vexpectedValue = reflect.ValueOf(expectedValue)369 if _, ok := expectedValue.(TestDeep); !ok {370 if !vexpectedValue.Type().AssignableTo(field.Type) {371 s.err = ctxerr.OpBad(s.location.Func,372 "type %s of field expected value %s%s differs from struct one (%s)",373 vexpectedValue.Type(),374 field.Name,375 ctxInfo,376 field.Type)377 return378 }379 }380 }381 s.expectedFields = append(s.expectedFields, fieldInfo{382 name: field.Name,383 expected: vexpectedValue,384 index: field.Index,385 unexported: field.PkgPath != "",386 })387}388// summary(Struct): compares the contents of a struct or a pointer on389// a struct390// input(Struct): struct,ptr(ptr on struct)391// Struct operator compares the contents of a struct or a pointer on a392// struct against the non-zero values of model (if any) and the393// values of expectedFields. See [SStruct] to compares against zero394// fields without specifying them in expectedFields.395//396// model must be the same type as compared data.397//398// expectedFields can be omitted, if no zero entries are expected399// and no [TestDeep] operators are involved. If expectedFields400// contains more than one item, all items are merged before their use,401// from left to right.402//403// td.Cmp(t, got, td.Struct(404// Person{405// Name: "John Doe",406// },407// td.StructFields{408// "Children": 4,409// },410// td.StructFields{411// "Age": td.Between(40, 45),412// "Children": 0, // overwrite 4413// }),414// )415//416// It is an error to set a non-zero field in model AND to set the417// same field in expectedFields, as in such cases the Struct418// operator does not know if the user wants to override the non-zero419// model field value or if it is an error. To explicitly override a420// non-zero model in expectedFields, just prefix its name with a421// ">" (followed by some optional spaces), as in:422//423// td.Cmp(t, got, td.Struct(424// Person{425// Name: "John Doe",426// Age: 23,427// Children: 4,428// },429// td.StructFields{430// "> Age": td.Between(40, 45),431// ">Children": 0, // spaces after ">" are optional432// }),433// )434//435// expectedFields can also contain regexps or shell patterns to436// match multiple fields not explicitly listed in model and in437// expectedFields. Regexps are prefixed by "=~" or "!~" to438// respectively match or don't-match. Shell patterns are prefixed by "="439// or "!" to respectively match or don't-match.440//441// td.Cmp(t, got, td.Struct(442// Person{443// Name: "John Doe",444// },445// td.StructFields{446// "=*At": td.Lte(time.Now()), // matches CreatedAt & UpdatedAt fields using shell pattern447// "=~^[a-z]": td.Ignore(), // explicitly ignore private fields using a regexp448// }),449// )450//451// When several patterns can match a same field, it is advised to tell452// go-testdeep in which order patterns should be tested, as once a453// pattern matches a field, the other patterns are ignored for this454// field. To do so, each pattern can be prefixed by a number, as in:455//456// td.Cmp(t, got, td.Struct(457// Person{458// Name: "John Doe",459// },460// td.StructFields{461// "1=*At": td.Lte(time.Now()),462// "2=~^[a-z]": td.NotNil(),463// }),464// )465//466// This way, "*At" shell pattern is always used before "^[a-z]"467// regexp, so if a field "createdAt" exists it is tested against468// time.Now() and never against [NotNil]. A pattern without a469// prefix number is the same as specifying "0" as prefix.470//471// To make it clearer, some spaces can be added, as well as bigger472// numbers used:473//474// td.Cmp(t, got, td.Struct(475// Person{476// Name: "John Doe",477// },478// td.StructFields{479// " 900 = *At": td.Lte(time.Now()),480// "2000 =~ ^[a-z]": td.NotNil(),481// }),482// )483//484// The following example combines all possibilities:485//486// td.Cmp(t, got, td.Struct(487// Person{488// NickName: "Joe",489// },490// td.StructFields{491// "Firstname": td.Any("John", "Johnny"),492// "1 = *[nN]ame": td.NotEmpty(), // matches LastName, lastname, …493// "2 ! [A-Z]*": td.NotZero(), // matches all private fields494// "3 =~ ^(Crea|Upda)tedAt$": td.Gte(time.Now()),495// "4 !~ ^(Dogs|Children)$": td.Zero(), // matches all remaining fields except Dogs and Children496// "5 =~ .": td.NotNil(), // matches all remaining fields (same as "5 = *")497// }),498// )499//500// During a match, all expected fields must be found to501// succeed. Non-expected fields are ignored.502//503// TypeBehind method returns the [reflect.Type] of model.504//505// See also [SStruct].506func Struct(model any, expectedFields ...StructFields) TestDeep {507 return anyStruct(model, mergeStructFields(expectedFields...), false)508}509// summary(SStruct): strictly compares the contents of a struct or a510// pointer on a struct511// input(SStruct): struct,ptr(ptr on struct)512// SStruct operator (aka strict-[Struct]) compares the contents of a513// struct or a pointer on a struct against values of model (if any)514// and the values of expectedFields. The zero values are compared515// too even if they are omitted from expectedFields: that is the516// difference with [Struct] operator.517//518// model must be the same type as compared data.519//520// expectedFields can be omitted, if no [TestDeep] operators are521// involved. If expectedFields contains more than one item, all522// items are merged before their use, from left to right.523//524// To ignore a field, one has to specify it in expectedFields and525// use the [Ignore] operator.526//527// td.Cmp(t, got, td.SStruct(528// Person{529// Name: "John Doe",530// },531// td.StructFields{532// "Children": 4,533// },534// td.StructFields{535// "Age": td.Between(40, 45),536// "Children": td.Ignore(), // overwrite 4537// }),538// )539//540// It is an error to set a non-zero field in model AND to set the541// same field in expectedFields, as in such cases the SStruct542// operator does not know if the user wants to override the non-zero543// model field value or if it is an error. To explicitly override a544// non-zero model in expectedFields, just prefix its name with a545// ">" (followed by some optional spaces), as in:546//547// td.Cmp(t, got, td.SStruct(548// Person{549// Name: "John Doe",550// Age: 23,551// Children: 4,552// },553// td.StructFields{554// "> Age": td.Between(40, 45),555// ">Children": 0, // spaces after ">" are optional556// }),557// )558//559// expectedFields can also contain regexps or shell patterns to560// match multiple fields not explicitly listed in model and in561// expectedFields. Regexps are prefixed by "=~" or "!~" to562// respectively match or don't-match. Shell patterns are prefixed by "="563// or "!" to respectively match or don't-match.564//565// td.Cmp(t, got, td.SStruct(566// Person{567// Name: "John Doe",568// },569// td.StructFields{570// "=*At": td.Lte(time.Now()), // matches CreatedAt & UpdatedAt fields using shell pattern571// "=~^[a-z]": td.Ignore(), // explicitly ignore private fields using a regexp572// }),573// )574//575// When several patterns can match a same field, it is advised to tell576// go-testdeep in which order patterns should be tested, as once a577// pattern matches a field, the other patterns are ignored for this578// field. To do so, each pattern can be prefixed by a number, as in:579//580// td.Cmp(t, got, td.SStruct(581// Person{582// Name: "John Doe",583// },584// td.StructFields{585// "1=*At": td.Lte(time.Now()),586// "2=~^[a-z]": td.NotNil(),587// }),588// )589//590// This way, "*At" shell pattern is always used before "^[a-z]"591// regexp, so if a field "createdAt" exists it is tested against592// time.Now() and never against [NotNil]. A pattern without a593// prefix number is the same as specifying "0" as prefix.594//595// To make it clearer, some spaces can be added, as well as bigger596// numbers used:597//598// td.Cmp(t, got, td.SStruct(599// Person{600// Name: "John Doe",601// },602// td.StructFields{603// " 900 = *At": td.Lte(time.Now()),604// "2000 =~ ^[a-z]": td.NotNil(),605// }),606// )607//608// The following example combines all possibilities:609//610// td.Cmp(t, got, td.SStruct(611// Person{612// NickName: "Joe",613// },614// td.StructFields{615// "Firstname": td.Any("John", "Johnny"),616// "1 = *[nN]ame": td.NotEmpty(), // matches LastName, lastname, …617// "2 ! [A-Z]*": td.NotZero(), // matches all private fields618// "3 =~ ^(Crea|Upda)tedAt$": td.Gte(time.Now()),619// "4 !~ ^(Dogs|Children)$": td.Zero(), // matches all remaining fields except Dogs and Children620// "5 =~ .": td.NotNil(), // matches all remaining fields (same as "5 = *")621// }),622// )623//624// During a match, all expected and zero fields must be found to625// succeed.626//627// TypeBehind method returns the [reflect.Type] of model.628//629// See also [SStruct].630func SStruct(model any, expectedFields ...StructFields) TestDeep {631 return anyStruct(model, mergeStructFields(expectedFields...), true)632}633func (s *tdStruct) Match(ctx ctxerr.Context, got reflect.Value) (err *ctxerr.Error) {634 if s.err != nil {635 return ctx.CollectError(s.err)636 }637 err = s.checkPtr(ctx, &got, false)638 if err != nil {639 return ctx.CollectError(err)640 }641 err = s.checkType(ctx, got)642 if err != nil {643 return ctx.CollectError(err)644 }645 ignoreUnexported := ctx.IgnoreUnexported || ctx.Hooks.IgnoreUnexported(got.Type())...

Full Screen

Full Screen

td_zero.go

Source:td_zero.go Github

copy

Full Screen

1// Copyright (c) 2018, Maxime Soulé2// All rights reserved.3//4// This source code is licensed under the BSD-style license found in the5// LICENSE file in the root directory of this source tree.6package td7import (8 "reflect"9 "github.com/maxatome/go-testdeep/internal/ctxerr"10)11type tdZero struct {12 baseOKNil13}14var _ TestDeep = &tdZero{}15// summary(Zero): checks data against its zero'ed conterpart16// input(Zero): all17// Zero operator checks that data is zero regarding its type.18//19// - nil is the zero value of pointers, maps, slices, channels and functions;20// - 0 is the zero value of numbers;21// - "" is the 0 value of strings;22// - false is the zero value of booleans;23// - zero value of structs is the struct with no fields initialized.24//25// Beware that:26//27// td.Cmp(t, AnyStruct{}, td.Zero()) // is true28// td.Cmp(t, &AnyStruct{}, td.Zero()) // is false, coz pointer ≠ nil29// td.Cmp(t, &AnyStruct{}, td.Ptr(td.Zero())) // is true30//31// See also [Empty], [Nil] and [NotZero].32func Zero() TestDeep {33 return &tdZero{34 baseOKNil: newBaseOKNil(3),35 }36}37func (z *tdZero) Match(ctx ctxerr.Context, got reflect.Value) (err *ctxerr.Error) {38 // nil case39 if !got.IsValid() {40 return nil41 }42 return deepValueEqual(ctx, got, reflect.New(got.Type()).Elem())43}44func (z *tdZero) String() string {45 return "Zero()"46}47type tdNotZero struct {48 baseOKNil49}50var _ TestDeep = &tdNotZero{}51// summary(NotZero): checks that data is not zero regarding its type52// input(NotZero): all53// NotZero operator checks that data is not zero regarding its type.54//55// - nil is the zero value of pointers, maps, slices, channels and functions;56// - 0 is the zero value of numbers;57// - "" is the 0 value of strings;58// - false is the zero value of booleans;59// - zero value of structs is the struct with no fields initialized.60//61// Beware that:62//63// td.Cmp(t, AnyStruct{}, td.NotZero()) // is false64// td.Cmp(t, &AnyStruct{}, td.NotZero()) // is true, coz pointer ≠ nil65// td.Cmp(t, &AnyStruct{}, td.Ptr(td.NotZero())) // is false66//67// See also [NotEmpty], [NotNil] and [Zero].68func NotZero() TestDeep {69 return &tdNotZero{70 baseOKNil: newBaseOKNil(3),71 }72}73func (z *tdNotZero) Match(ctx ctxerr.Context, got reflect.Value) (err *ctxerr.Error) {74 if got.IsValid() && !deepValueEqualOK(got, reflect.New(got.Type()).Elem()) {75 return nil76 }77 if ctx.BooleanError {78 return ctxerr.BooleanError79 }80 return ctx.CollectError(&ctxerr.Error{81 Message: "zero value",82 Got: got,83 Expected: z,84 })85}86func (z *tdNotZero) String() string {87 return "NotZero()"88}...

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println("Name: ", t.name)6 fmt.Println("Age: ", t.age)7}8func main() {9 t := td{"Ganesh", 23}10 t.anyStruct()11}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println(t.a)6}7func main() {8 t := td{a: 1}9 t.anyStruct()10}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import "fmt"2type td struct {3}4func (t td) anyStruct() {5 fmt.Println(t.a, t.b)6}7func main() {8 t := td{1, 2}9 t.anyStruct()10}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println("This is a method of td struct")6}7func main() {8 t := td{1, 2}9 t.anyStruct()10}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println("a = ", t.a, "b = ", t.b)6}7func main() {8 t := td{3, 4}9 t.anyStruct()10 fmt.Println("a = ", t.a, "b = ", t.b)11}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println("I am in anyStruct method", t.name, t.age)6}7func main() {8 t := td{9 }10 t.anyStruct()11}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println("Inside anyStruct")6 fmt.Println("a=", t.a, "b=", t.b)7}8func main() {9 t.anyStruct()10}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println("In anyStruct method")6 fmt.Println("a=", t.a)7 fmt.Println("b=", t.b)8 fmt.Println("c=", t.c)9}10func main() {11 t := td{10, "Hello", 3.14}12 fmt.Println("t=", t)13 t.anyStruct()14 fmt.Println("t=", t)15 fmt.Println("t.a=", t.a)16 fmt.Println("t.b=", t.b)17 fmt.Println("t.c=", t.c)18 fmt.Println("t type is ", reflect.TypeOf(t))19}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 var td *T = new(T)4 td.anyStruct()5}6import (7func main() {8 var td *T = new(T)9 td.anyStruct()10}11import (12func main() {13 var td *T = new(T)14 td.anyStruct()15}

Full Screen

Full Screen

anyStruct

Using AI Code Generation

copy

Full Screen

1import (2type td struct {3}4func (t td) anyStruct() {5 fmt.Println("Name:", t.name, "Age:", t.age)6}7func main() {8 t := td{9 }10 anyStruct.anyStruct()11}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Go-testdeep automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful