Best Go-testdeep code snippet using td_test.Compare
td_struct_test.go
Source:td_struct_test.go
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 td_test7import (8 "bytes"9 "errors"10 "testing"11 "time"12 "github.com/maxatome/go-testdeep/internal/dark"13 "github.com/maxatome/go-testdeep/internal/test"14 "github.com/maxatome/go-testdeep/td"15)16func TestStruct(t *testing.T) {17 gotStruct := MyStruct{18 MyStructMid: MyStructMid{19 MyStructBase: MyStructBase{20 ValBool: true,21 },22 ValStr: "foobar",23 },24 ValInt: 123,25 }26 //27 // Using pointer28 checkOK(t, &gotStruct,29 td.Struct(&MyStruct{}, td.StructFields{30 "ValBool": true,31 "ValStr": "foobar",32 "ValInt": 123,33 "Ptr": nil,34 }))35 checkOK(t, &gotStruct,36 td.Struct(37 &MyStruct{38 MyStructMid: MyStructMid{39 ValStr: "zip",40 },41 ValInt: 666,42 },43 td.StructFields{44 "ValBool": true,45 "> ValStr": "foobar",46 ">ValInt": 123,47 }))48 checkOK(t, &gotStruct,49 td.Struct((*MyStruct)(nil), td.StructFields{50 "ValBool": true,51 "ValStr": "foobar",52 "ValInt": 123,53 "Ptr": nil,54 }))55 checkError(t, 123,56 td.Struct(&MyStruct{}, td.StructFields{}),57 expectedError{58 Message: mustBe("type mismatch"),59 Path: mustBe("DATA"),60 Got: mustContain("int"),61 Expected: mustContain("*td_test.MyStruct"),62 })63 checkError(t, &MyStructBase{},64 td.Struct(&MyStruct{}, td.StructFields{}),65 expectedError{66 Message: mustBe("type mismatch"),67 Path: mustBe("DATA"),68 Got: mustContain("*td_test.MyStructBase"),69 Expected: mustContain("*td_test.MyStruct"),70 })71 checkError(t, &gotStruct,72 td.Struct(&MyStruct{}, td.StructFields{73 "ValBool": false, // â does not match74 "ValStr": "foobar",75 "ValInt": 123,76 }),77 expectedError{78 Message: mustBe("values differ"),79 Path: mustBe("DATA.ValBool"),80 Got: mustContain("true"),81 Expected: mustContain("false"),82 })83 checkOK(t, &gotStruct,84 td.Struct(&MyStruct{85 MyStructMid: MyStructMid{86 MyStructBase: MyStructBase{87 ValBool: true,88 },89 ValStr: "foobar",90 },91 ValInt: 123,92 }, nil))93 checkError(t, &gotStruct,94 td.Struct(&MyStruct{95 MyStructMid: MyStructMid{96 MyStructBase: MyStructBase{97 ValBool: true,98 },99 ValStr: "foobax", // â does not match100 },101 ValInt: 123,102 }, nil),103 expectedError{104 Message: mustBe("values differ"),105 Path: mustBe("DATA.ValStr"),106 Got: mustContain("foobar"),107 Expected: mustContain("foobax"),108 })109 // Zero values110 checkOK(t, &MyStruct{},111 td.Struct(&MyStruct{}, td.StructFields{112 "ValBool": false,113 "ValStr": "",114 "ValInt": 0,115 }))116 // nil cases117 checkError(t, nil, td.Struct(&MyStruct{}, nil),118 expectedError{119 Message: mustBe("values differ"),120 Path: mustBe("DATA"),121 Got: mustContain("nil"),122 Expected: mustContain("*td_test.MyStruct"),123 })124 checkError(t, (*MyStruct)(nil), td.Struct(&MyStruct{}, nil),125 expectedError{126 Message: mustBe("values differ"),127 Path: mustBe("DATA"),128 Got: mustContain("nil"),129 Expected: mustBe("non-nil"),130 })131 //132 // Without pointer133 checkOK(t, gotStruct,134 td.Struct(MyStruct{}, td.StructFields{135 "ValBool": true,136 "ValStr": "foobar",137 "ValInt": 123,138 }))139 checkOK(t, gotStruct,140 td.Struct(141 MyStruct{142 MyStructMid: MyStructMid{143 ValStr: "zip",144 },145 ValInt: 666,146 },147 td.StructFields{148 "ValBool": true,149 "> ValStr": "foobar",150 ">ValInt": 123,151 }))152 checkError(t, 123, td.Struct(MyStruct{}, td.StructFields{}),153 expectedError{154 Message: mustBe("type mismatch"),155 Path: mustBe("DATA"),156 Got: mustContain("int"),157 Expected: mustContain("td_test.MyStruct"),158 })159 checkError(t, gotStruct,160 td.Struct(MyStruct{}, td.StructFields{161 "ValBool": false, // â does not match162 "ValStr": "foobar",163 "ValInt": 123,164 }),165 expectedError{166 Message: mustBe("values differ"),167 Path: mustBe("DATA.ValBool"),168 Got: mustContain("true"),169 Expected: mustContain("false"),170 })171 checkOK(t, gotStruct,172 td.Struct(MyStruct{173 MyStructMid: MyStructMid{174 MyStructBase: MyStructBase{175 ValBool: true,176 },177 ValStr: "foobar",178 },179 ValInt: 123,180 }, nil))181 checkError(t, gotStruct,182 td.Struct(MyStruct{183 MyStructMid: MyStructMid{184 MyStructBase: MyStructBase{185 ValBool: true,186 },187 ValStr: "foobax", // â does not match188 },189 ValInt: 123,190 }, nil),191 expectedError{192 Message: mustBe("values differ"),193 Path: mustBe("DATA.ValStr"),194 Got: mustContain("foobar"),195 Expected: mustContain("foobax"),196 })197 // Zero values198 checkOK(t, MyStruct{},199 td.Struct(MyStruct{}, td.StructFields{200 "ValBool": false,201 "ValStr": "",202 "ValInt": 0,203 }))204 // nil cases205 checkError(t, nil, td.Struct(MyStruct{}, nil),206 expectedError{207 Message: mustBe("values differ"),208 Path: mustBe("DATA"),209 Got: mustContain("nil"),210 Expected: mustContain("td_test.MyStruct"),211 })212 checkError(t, (*MyStruct)(nil), td.Struct(MyStruct{}, nil),213 expectedError{214 Message: mustBe("type mismatch"),215 Path: mustBe("DATA"),216 Got: mustBe("*td_test.MyStruct"),217 Expected: mustBe("td_test.MyStruct"),218 })219 //220 // Be lax...221 type Struct1 struct {222 name string223 age int224 }225 type Struct2 struct {226 name string227 age int228 }229 // Without Lax â error230 checkError(t,231 Struct1{name: "Bob", age: 42},232 td.Struct(Struct2{name: "Bob", age: 42}, nil),233 expectedError{234 Message: mustBe("type mismatch"),235 })236 // With Lax â OK237 checkOK(t,238 Struct1{name: "Bob", age: 42},239 td.Lax(td.Struct(Struct2{name: "Bob", age: 42}, nil)))240 //241 // IgnoreUnexported242 t.Run("IgnoreUnexported", func(tt *testing.T) {243 type SType struct {244 Public int245 private string246 }247 got := SType{Public: 42, private: "test"}248 expected := td.Struct(SType{Public: 42, private: "zip"}, nil)249 checkError(tt, got, expected,250 expectedError{251 Message: mustBe("values differ"),252 Path: mustBe("DATA.private"),253 Got: mustBe(`"test"`),254 Expected: mustBe(`"zip"`),255 })256 // Ignore unexported globally257 defer func() { td.DefaultContextConfig.IgnoreUnexported = false }()258 td.DefaultContextConfig.IgnoreUnexported = true259 checkOK(tt, got, expected)260 td.DefaultContextConfig.IgnoreUnexported = false261 ttt := test.NewTestingTB(t.Name())262 t := td.NewT(ttt).IgnoreUnexported(SType{}) // ignore only for SType263 test.IsTrue(tt, t.Cmp(got, expected))264 })265 //266 // Bad usage267 checkError(t, "never tested",268 td.Struct("test", nil),269 expectedError{270 Message: mustBe("bad usage of Struct operator"),271 Path: mustBe("DATA"),272 Summary: mustBe("usage: Struct(STRUCT|&STRUCT, EXPECTED_FIELDS), but received string as 1st parameter"),273 })274 i := 12275 checkError(t, "never tested",276 td.Struct(&i, nil),277 expectedError{278 Message: mustBe("bad usage of Struct operator"),279 Path: mustBe("DATA"),280 Summary: mustBe("usage: Struct(STRUCT|&STRUCT, EXPECTED_FIELDS), but received *int (ptr) as 1st parameter"),281 })282 checkError(t, "never tested",283 td.Struct(&MyStruct{}, td.StructFields{"UnknownField": 123}),284 expectedError{285 Message: mustBe("bad usage of Struct operator"),286 Path: mustBe("DATA"),287 Summary: mustBe(`struct td_test.MyStruct has no field "UnknownField"`),288 })289 checkError(t, "never tested",290 td.Struct(&MyStruct{}, td.StructFields{">\tUnknownField": 123}),291 expectedError{292 Message: mustBe("bad usage of Struct operator"),293 Path: mustBe("DATA"),294 Summary: mustBe(`struct td_test.MyStruct has no field "UnknownField" (from ">\tUnknownField")`),295 })296 checkError(t, "never tested",297 td.Struct(&MyStruct{}, td.StructFields{"ValBool": 123}),298 expectedError{299 Message: mustBe("bad usage of Struct operator"),300 Path: mustBe("DATA"),301 Summary: mustBe("type int of field expected value ValBool differs from struct one (bool)"),302 })303 checkError(t, "never tested",304 td.Struct(&MyStruct{}, td.StructFields{">ValBool": 123}),305 expectedError{306 Message: mustBe("bad usage of Struct operator"),307 Path: mustBe("DATA"),308 Summary: mustBe(`type int of field expected value ValBool (from ">ValBool") differs from struct one (bool)`),309 })310 checkError(t, "never tested",311 td.Struct(&MyStruct{}, td.StructFields{"ValBool": nil}),312 expectedError{313 Message: mustBe("bad usage of Struct operator"),314 Path: mustBe("DATA"),315 Summary: mustBe("expected value of field ValBool cannot be nil as it is a bool"),316 })317 checkError(t, "never tested",318 td.Struct(&MyStruct{319 MyStructMid: MyStructMid{320 MyStructBase: MyStructBase{321 ValBool: true,322 },323 },324 },325 td.StructFields{"ValBool": false}),326 expectedError{327 Message: mustBe("bad usage of Struct operator"),328 Path: mustBe("DATA"),329 Summary: mustBe("non zero field ValBool in model already exists in expectedFields"),330 })331 //332 // String333 test.EqualStr(t,334 td.Struct(MyStruct{335 MyStructMid: MyStructMid{336 ValStr: "foobar",337 },338 ValInt: 123,339 },340 td.StructFields{341 "ValBool": false,342 }).String(),343 `Struct(td_test.MyStruct{344 ValBool: false345 ValInt: 123346 ValStr: "foobar"347})`)348 test.EqualStr(t,349 td.Struct(&MyStruct{350 MyStructMid: MyStructMid{351 ValStr: "foobar",352 },353 ValInt: 123,354 },355 td.StructFields{356 "ValBool": false,357 }).String(),358 `Struct(*td_test.MyStruct{359 ValBool: false360 ValInt: 123361 ValStr: "foobar"362})`)363 test.EqualStr(t,364 td.Struct(&MyStruct{}, td.StructFields{}).String(),365 `Struct(*td_test.MyStruct{})`)366 // Erroneous op367 test.EqualStr(t, td.Struct("test", nil).String(), "Struct(<ERROR>)")368}369func TestStructPrivateFields(t *testing.T) {370 type privateKey struct {371 num int372 name string373 }374 type privateValue struct {375 value string376 weight int377 }378 type MyTime time.Time379 type structPrivateFields struct {380 byKey map[privateKey]*privateValue381 name string382 nameb []byte383 err error384 iface any385 properties []int386 birth time.Time387 birth2 MyTime388 next *structPrivateFields389 }390 d := func(rfc3339Date string) (ret time.Time) {391 var err error392 ret, err = time.Parse(time.RFC3339Nano, rfc3339Date)393 if err != nil {394 panic(err)395 }396 return397 }398 got := structPrivateFields{399 byKey: map[privateKey]*privateValue{400 {num: 1, name: "foo"}: {value: "test", weight: 12},401 {num: 2, name: "bar"}: {value: "tset", weight: 23},402 {num: 3, name: "zip"}: {value: "ttse", weight: 34},403 },404 name: "foobar",405 nameb: []byte("foobar"),406 err: errors.New("the error"),407 iface: 1234,408 properties: []int{20, 22, 23, 21},409 birth: d("2018-04-01T10:11:12.123456789Z"),410 birth2: MyTime(d("2018-03-01T09:08:07.987654321Z")),411 next: &structPrivateFields{412 byKey: map[privateKey]*privateValue{},413 name: "sub",414 iface: bytes.NewBufferString("buffer!"),415 birth: d("2018-04-02T10:11:12.123456789Z"),416 birth2: MyTime(d("2018-03-02T09:08:07.987654321Z")),417 },418 }419 checkOK(t, got,420 td.Struct(structPrivateFields{}, td.StructFields{421 "name": "foobar",422 }))423 checkOK(t, got,424 td.Struct(structPrivateFields{}, td.StructFields{425 "name": td.Re("^foo"),426 }))427 checkOK(t, got,428 td.Struct(structPrivateFields{}, td.StructFields{429 "nameb": td.Re("^foo"),430 }))431 checkOKOrPanicIfUnsafeDisabled(t, got,432 td.Struct(structPrivateFields{}, td.StructFields{433 "err": td.Re("error"),434 }))435 checkError(t, got,436 td.Struct(structPrivateFields{}, td.StructFields{437 "iface": td.Re("buffer"),438 }),439 expectedError{440 Message: mustBe("bad type"),441 Path: mustBe("DATA.iface"),442 Got: mustBe("int"),443 Expected: mustBe("string (convertible) OR fmt.Stringer OR error OR []uint8"),444 })445 checkOKOrPanicIfUnsafeDisabled(t, got,446 td.Struct(structPrivateFields{}, td.StructFields{447 "next": td.Struct(&structPrivateFields{}, td.StructFields{448 "iface": td.Re("buffer"),449 }),450 }))451 checkOK(t, got,452 td.Struct(structPrivateFields{}, td.StructFields{453 "properties": []int{20, 22, 23, 21},454 }))455 checkOK(t, got,456 td.Struct(structPrivateFields{}, td.StructFields{457 "properties": td.ArrayEach(td.Between(20, 23)),458 }))459 checkOK(t, got,460 td.Struct(structPrivateFields{}, td.StructFields{461 "byKey": td.MapEach(td.Struct(&privateValue{}, td.StructFields{462 "weight": td.Between(12, 34),463 "value": td.Any(td.HasPrefix("t"), td.HasSuffix("e")),464 })),465 }))466 checkOK(t, got,467 td.Struct(structPrivateFields{}, td.StructFields{468 "byKey": td.SuperMapOf(469 map[privateKey]*privateValue{470 {num: 3, name: "zip"}: {value: "ttse", weight: 34},471 },472 td.MapEntries{473 privateKey{num: 2, name: "bar"}: &privateValue{value: "tset", weight: 23},474 }),475 }))476 expected := td.Struct(structPrivateFields{}, td.StructFields{477 "birth": td.TruncTime(d("2018-04-01T10:11:12Z"), time.Second),478 "birth2": td.TruncTime(MyTime(d("2018-03-01T09:08:07Z")), time.Second),479 })480 if !dark.UnsafeDisabled {481 checkOK(t, got, expected)482 } else {483 checkError(t, got, expected,484 expectedError{485 Message: mustBe("cannot compare"),486 Path: mustBe("DATA.birth"),487 Summary: mustBe("unexported field that cannot be overridden"),488 })489 }490 checkError(t, got,491 td.Struct(structPrivateFields{}, td.StructFields{492 "next": td.Struct(&structPrivateFields{}, td.StructFields{493 "name": "sub",494 "birth": td.Code(func(t time.Time) bool { return true }),495 }),496 }),497 expectedError{498 Message: mustBe("cannot compare unexported field"),499 Path: mustBe("DATA.next.birth"),500 Summary: mustBe("use Code() on surrounding struct instead"),501 })502 checkError(t, got,503 td.Struct(structPrivateFields{}, td.StructFields{504 "next": td.Struct(&structPrivateFields{}, td.StructFields{505 "name": "sub",506 "birth": td.Smuggle(507 func(t time.Time) string { return t.String() },508 "2018-04-01T10:11:12.123456789Z"),509 }),510 }),511 expectedError{512 Message: mustBe("cannot smuggle unexported field"),513 Path: mustBe("DATA.next.birth"),514 Summary: mustBe("work on surrounding struct instead"),515 })516}517func TestStructPatterns(t *testing.T) {518 type paAnon struct {519 alphaNum int520 betaNum int521 }522 type paTest struct {523 paAnon524 Num int525 }526 got := paTest{527 paAnon: paAnon{528 alphaNum: 1000,529 betaNum: 2000,530 },531 Num: 666,532 }533 t.Run("Shell pattern", func(t *testing.T) {534 checkOK(t, got,535 td.Struct(paTest{Num: 666},536 td.StructFields{537 "=*Num": td.Gte(1000), // matches alphaNum & betaNum538 }))539 checkOK(t, got,540 td.Struct(paTest{Num: 666},541 td.StructFields{542 "=a*Num": td.Lt(0), // no remaining fields to match543 "=*": td.Gte(1000), // first, matches alphaNum & betaNum544 "=b*Num": td.Lt(0), // no remaining fields to match545 }),546 "Default sorting uses patterns")547 checkOK(t, got,548 td.Struct(paTest{Num: 666},549 td.StructFields{550 "1 = a*Num": td.Between(999, 1001), // matches alphaNum551 "2 = *": td.Gte(2000), // matches betaNum552 "3 = b*Num": td.Gt(3000), // no remaining fields to match553 }),554 "Explicitly sorted")555 checkOK(t, got,556 td.Struct(paTest{Num: 666},557 td.StructFields{558 "1 ! beta*": 1000, // matches alphaNum559 "2 = *": 2000, // matches betaNum560 }),561 "negative shell pattern")562 checkError(t, "never tested",563 td.Struct(paTest{Num: 666}, td.StructFields{"= al[pha": 123}),564 expectedError{565 Message: mustBe("bad usage of Struct operator"),566 Path: mustBe("DATA"),567 Summary: mustContain("bad shell pattern field `= al[pha`: "),568 })569 checkError(t, "never tested",570 td.Struct(paTest{Num: 666}, td.StructFields{"= alpha*": nil}), expectedError{571 Message: mustBe("bad usage of Struct operator"),572 Path: mustBe("DATA"),573 Summary: mustBe("expected value of field alphaNum (from pattern `= alpha*`) cannot be nil as it is a int"),574 })575 })576 t.Run("Regexp", func(t *testing.T) {577 checkOK(t, got,578 td.Struct(paTest{Num: 666},579 td.StructFields{580 "=~Num$": td.Gte(1000), // matches alphaNum & betaNum581 }))582 checkOK(t, got,583 td.Struct(paTest{Num: 666},584 td.StructFields{585 "=~^a.*Num$": td.Lt(0), // no remaining fields to match586 "=~.": td.Gte(1000), // first, matches alphaNum & betaNum587 "=~^b.*Num$": td.Lt(0), // no remaining fields to match588 }),589 "Default sorting uses patterns")590 checkOK(t, got,591 td.Struct(paTest{Num: 666},592 td.StructFields{593 "1 =~ ^a.*Num$": td.Between(999, 1001), // matches alphaNum594 "2 =~ .": td.Gte(2000), // matches betaNum595 "3 =~ ^b.*Num$": td.Gt(3000), // no remaining fields to match596 }),597 "Explicitly sorted")598 checkOK(t, got,599 td.Struct(paTest{Num: 666},600 td.StructFields{601 "1 !~ ^beta": 1000, // matches alphaNum602 "2 =~ .": 2000, // matches betaNum603 }),604 "negative regexp")605 checkError(t, "never tested",606 td.Struct(paTest{Num: 666}, td.StructFields{"=~ al(*": 123}),607 expectedError{608 Message: mustBe("bad usage of Struct operator"),609 Path: mustBe("DATA"),610 Summary: mustContain("bad regexp field `=~ al(*`: "),611 })612 checkError(t, "never tested",613 td.Struct(paTest{Num: 666}, td.StructFields{"=~ alpha": nil}),614 expectedError{615 Message: mustBe("bad usage of Struct operator"),616 Path: mustBe("DATA"),617 Summary: mustBe("expected value of field alphaNum (from pattern `=~ alpha`) cannot be nil as it is a int"),618 })619 })620}621func TestStructTypeBehind(t *testing.T) {622 equalTypes(t, td.Struct(MyStruct{}, nil), MyStruct{})623 equalTypes(t, td.Struct(&MyStruct{}, nil), &MyStruct{})624 // Erroneous op625 equalTypes(t, td.Struct("test", nil), nil)626}627func TestSStruct(t *testing.T) {628 gotStruct := MyStruct{629 MyStructMid: MyStructMid{630 MyStructBase: MyStructBase{631 ValBool: true,632 },633 ValStr: "foobar",634 },635 ValInt: 123,636 }637 //638 // Using pointer639 checkOK(t, &gotStruct,640 td.SStruct(&MyStruct{}, td.StructFields{641 "ValBool": true,642 "ValStr": "foobar",643 "ValInt": 123,644 // nil Ptr645 }))646 checkOK(t, &gotStruct,647 td.SStruct(648 &MyStruct{649 MyStructMid: MyStructMid{650 ValStr: "zip",651 },652 ValInt: 666,653 },654 td.StructFields{655 "ValBool": true,656 "> ValStr": "foobar",657 ">ValInt": 123,658 }))659 checkOK(t, &gotStruct,660 td.SStruct((*MyStruct)(nil), td.StructFields{661 "ValBool": true,662 "ValStr": "foobar",663 "ValInt": 123,664 // nil Ptr665 }))666 checkError(t, 123,667 td.SStruct(&MyStruct{}, td.StructFields{}),668 expectedError{669 Message: mustBe("type mismatch"),670 Path: mustBe("DATA"),671 Got: mustContain("int"),672 Expected: mustContain("*td_test.MyStruct"),673 })674 checkError(t, &MyStructBase{},675 td.SStruct(&MyStruct{}, td.StructFields{}),676 expectedError{677 Message: mustBe("type mismatch"),678 Path: mustBe("DATA"),679 Got: mustContain("*td_test.MyStructBase"),680 Expected: mustContain("*td_test.MyStruct"),681 })682 checkError(t, &gotStruct,683 td.SStruct(&MyStruct{}, td.StructFields{684 // ValBool false â does not match685 "ValStr": "foobar",686 "ValInt": 123,687 }),688 expectedError{689 Message: mustBe("values differ"),690 Path: mustBe("DATA.ValBool"),691 Got: mustContain("true"),692 Expected: mustContain("false"),693 })694 checkOK(t, &gotStruct,695 td.SStruct(&MyStruct{696 MyStructMid: MyStructMid{697 MyStructBase: MyStructBase{698 ValBool: true,699 },700 ValStr: "foobar",701 },702 ValInt: 123,703 }, nil))704 checkError(t, &gotStruct,705 td.SStruct(&MyStruct{706 MyStructMid: MyStructMid{707 MyStructBase: MyStructBase{708 ValBool: true,709 },710 ValStr: "foobax", // â does not match711 },712 ValInt: 123,713 }, nil),714 expectedError{715 Message: mustBe("values differ"),716 Path: mustBe("DATA.ValStr"),717 Got: mustContain("foobar"),718 Expected: mustContain("foobax"),719 })720 // Zero values721 checkOK(t, &MyStruct{}, td.SStruct(&MyStruct{}, nil))722 checkOK(t, &MyStruct{}, td.SStruct(&MyStruct{}, td.StructFields{}))723 // nil cases724 checkError(t, nil, td.SStruct(&MyStruct{}, nil),725 expectedError{726 Message: mustBe("values differ"),727 Path: mustBe("DATA"),728 Got: mustContain("nil"),729 Expected: mustContain("*td_test.MyStruct"),730 })731 checkError(t, (*MyStruct)(nil), td.SStruct(&MyStruct{}, nil),732 expectedError{733 Message: mustBe("values differ"),734 Path: mustBe("DATA"),735 Got: mustContain("nil"),736 Expected: mustBe("non-nil"),737 })738 //739 // Without pointer740 checkOK(t, gotStruct,741 td.SStruct(MyStruct{}, td.StructFields{742 "ValBool": true,743 "ValStr": "foobar",744 "ValInt": 123,745 }))746 checkOK(t, gotStruct,747 td.SStruct(748 MyStruct{749 MyStructMid: MyStructMid{750 ValStr: "zip",751 },752 ValInt: 666,753 },754 td.StructFields{755 "ValBool": true,756 "> ValStr": "foobar",757 ">ValInt": 123,758 }))759 checkError(t, 123, td.SStruct(MyStruct{}, td.StructFields{}),760 expectedError{761 Message: mustBe("type mismatch"),762 Path: mustBe("DATA"),763 Got: mustContain("int"),764 Expected: mustContain("td_test.MyStruct"),765 })766 checkError(t, gotStruct,767 td.SStruct(MyStruct{}, td.StructFields{768 // "ValBool" false â does not match769 "ValStr": "foobar",770 "ValInt": 123,771 }),772 expectedError{773 Message: mustBe("values differ"),774 Path: mustBe("DATA.ValBool"),775 Got: mustContain("true"),776 Expected: mustContain("false"),777 })778 checkOK(t, gotStruct,779 td.SStruct(MyStruct{780 MyStructMid: MyStructMid{781 MyStructBase: MyStructBase{782 ValBool: true,783 },784 ValStr: "foobar",785 },786 ValInt: 123,787 }, nil))788 checkError(t, gotStruct,789 td.SStruct(MyStruct{790 MyStructMid: MyStructMid{791 MyStructBase: MyStructBase{792 ValBool: true,793 },794 ValStr: "foobax", // â does not match795 },796 ValInt: 123,797 }, nil),798 expectedError{799 Message: mustBe("values differ"),800 Path: mustBe("DATA.ValStr"),801 Got: mustContain("foobar"),802 Expected: mustContain("foobax"),803 })804 // Zero values805 checkOK(t, MyStruct{}, td.Struct(MyStruct{}, td.StructFields{}))806 checkOK(t, MyStruct{}, td.Struct(MyStruct{}, nil))807 // nil cases808 checkError(t, nil, td.SStruct(MyStruct{}, nil),809 expectedError{810 Message: mustBe("values differ"),811 Path: mustBe("DATA"),812 Got: mustContain("nil"),813 Expected: mustContain("td_test.MyStruct"),814 })815 checkError(t, (*MyStruct)(nil), td.SStruct(MyStruct{}, nil),816 expectedError{817 Message: mustBe("type mismatch"),818 Path: mustBe("DATA"),819 Got: mustBe("*td_test.MyStruct"),820 Expected: mustBe("td_test.MyStruct"),821 })822 //823 // Be lax...824 type Struct1 struct {825 name string826 age int827 }828 type Struct2 struct {829 name string830 age int831 }832 // Without Lax â error833 checkError(t,834 Struct1{name: "Bob", age: 42},835 td.SStruct(Struct2{name: "Bob", age: 42}, nil),836 expectedError{837 Message: mustBe("type mismatch"),838 })839 // With Lax â OK840 checkOK(t,841 Struct1{name: "Bob", age: 42},842 td.Lax(td.SStruct(Struct2{name: "Bob", age: 42}, nil)))843 //844 // IgnoreUnexported845 t.Run("IgnoreUnexported", func(tt *testing.T) {846 type SType struct {847 Public int848 private string849 }850 got := SType{Public: 42, private: "test"}851 expected := td.SStruct(SType{Public: 42}, nil)852 checkError(tt, got, expected,853 expectedError{854 Message: mustBe("values differ"),855 Path: mustBe("DATA.private"),856 Got: mustBe(`"test"`),857 Expected: mustBe(`""`),858 })859 // Ignore unexported globally860 defer func() { td.DefaultContextConfig.IgnoreUnexported = false }()861 td.DefaultContextConfig.IgnoreUnexported = true862 checkOK(tt, got, expected)863 td.DefaultContextConfig.IgnoreUnexported = false864 ttt := test.NewTestingTB(t.Name())865 t := td.NewT(ttt).IgnoreUnexported(SType{}) // ignore only for SType866 test.IsTrue(tt, t.Cmp(got, expected))867 })868 //869 // Bad usage870 checkError(t, "never tested",871 td.SStruct("test", nil),872 expectedError{873 Message: mustBe("bad usage of SStruct operator"),874 Path: mustBe("DATA"),875 Summary: mustBe("usage: SStruct(STRUCT|&STRUCT, EXPECTED_FIELDS), but received string as 1st parameter"),876 })877 i := 12878 checkError(t, "never tested",879 td.SStruct(&i, nil),880 expectedError{881 Message: mustBe("bad usage of SStruct operator"),882 Path: mustBe("DATA"),883 Summary: mustBe("usage: SStruct(STRUCT|&STRUCT, EXPECTED_FIELDS), but received *int (ptr) as 1st parameter"),884 })885 checkError(t, "never tested",886 td.SStruct(&MyStruct{}, td.StructFields{"UnknownField": 123}),887 expectedError{888 Message: mustBe("bad usage of SStruct operator"),889 Path: mustBe("DATA"),890 Summary: mustBe(`struct td_test.MyStruct has no field "UnknownField"`),891 })892 checkError(t, "never tested",893 td.SStruct(&MyStruct{}, td.StructFields{">\tUnknownField": 123}),894 expectedError{895 Message: mustBe("bad usage of SStruct operator"),896 Path: mustBe("DATA"),897 Summary: mustBe(`struct td_test.MyStruct has no field "UnknownField" (from ">\tUnknownField")`),898 })899 checkError(t, "never tested",900 td.SStruct(&MyStruct{}, td.StructFields{"ValBool": 123}),901 expectedError{902 Message: mustBe("bad usage of SStruct operator"),903 Path: mustBe("DATA"),904 Summary: mustBe("type int of field expected value ValBool differs from struct one (bool)"),905 })906 checkError(t, "never tested",907 td.SStruct(&MyStruct{}, td.StructFields{">ValBool": 123}),908 expectedError{909 Message: mustBe("bad usage of SStruct operator"),910 Path: mustBe("DATA"),911 Summary: mustBe(`type int of field expected value ValBool (from ">ValBool") differs from struct one (bool)`),912 })913 checkError(t, "never tested",914 td.SStruct(&MyStruct{}, td.StructFields{"ValBool": nil}),915 expectedError{916 Message: mustBe("bad usage of SStruct operator"),917 Path: mustBe("DATA"),918 Summary: mustBe("expected value of field ValBool cannot be nil as it is a bool"),919 })920 checkError(t, "never tested",921 td.SStruct(&MyStruct{922 MyStructMid: MyStructMid{923 MyStructBase: MyStructBase{924 ValBool: true,925 },926 },927 },928 td.StructFields{"ValBool": false}),929 expectedError{930 Message: mustBe("bad usage of SStruct operator"),931 Path: mustBe("DATA"),932 Summary: mustBe("non zero field ValBool in model already exists in expectedFields"),933 })934 //935 // String936 test.EqualStr(t,937 td.SStruct(MyStruct{938 MyStructMid: MyStructMid{939 ValStr: "foobar",940 },941 ValInt: 123,942 },943 td.StructFields{944 "ValBool": false,945 }).String(),946 `SStruct(td_test.MyStruct{947 Ptr: (*int)(<nil>)948 ValBool: false949 ValInt: 123950 ValStr: "foobar"951})`)952 test.EqualStr(t,953 td.SStruct(&MyStruct{954 MyStructMid: MyStructMid{955 ValStr: "foobar",956 },957 ValInt: 123,958 },959 td.StructFields{960 "ValBool": false,961 }).String(),962 `SStruct(*td_test.MyStruct{963 Ptr: (*int)(<nil>)964 ValBool: false965 ValInt: 123966 ValStr: "foobar"967})`)968 test.EqualStr(t,969 td.SStruct(&MyStruct{}, td.StructFields{}).String(),970 `SStruct(*td_test.MyStruct{971 Ptr: (*int)(<nil>)972 ValBool: false973 ValInt: 0974 ValStr: ""975})`)976 // Erroneous op977 test.EqualStr(t, td.SStruct("test", nil).String(), "SStruct(<ERROR>)")978}979func TestSStructPattern(t *testing.T) {980 // Patterns are already fully tested in TestStructPatterns981 type paAnon struct {982 alphaNum int983 betaNum int984 }985 type paTest struct {986 paAnon987 Num int988 }989 got := paTest{990 paAnon: paAnon{991 alphaNum: 1000,992 betaNum: 2000,993 },994 Num: 666,995 }996 checkOK(t, got,997 td.SStruct(paTest{},998 td.StructFields{999 "=*Num": td.Gte(666), // matches Num, alphaNum & betaNum1000 }))1001 checkOK(t, got,1002 td.SStruct(paTest{},1003 td.StructFields{1004 "=~Num$": td.Gte(666), // matches Num, alphaNum & betaNum1005 }))1006 checkOK(t, paTest{Num: 666},1007 td.SStruct(paTest{},1008 td.StructFields{1009 "=~^Num": 666, // only matches Num1010 // remaining fields are tested as 01011 }))1012}1013func TestSStructTypeBehind(t *testing.T) {1014 equalTypes(t, td.SStruct(MyStruct{}, nil), MyStruct{})1015 equalTypes(t, td.SStruct(&MyStruct{}, nil), &MyStruct{})1016 // Erroneous op1017 equalTypes(t, td.SStruct("test", nil), nil)1018}...
td_between_test.go
Source:td_between_test.go
...555 checkOK(t, now, td.Gt(now.Add(-time.Second)))556 checkOK(t, now, td.Lt(now.Add(time.Second)))557}558type compareType int559func (i compareType) Compare(j compareType) int {560 if i < j {561 return -1562 }563 if i > j {564 return 1565 }566 return 0567}568type lessType int569func (i lessType) Less(j lessType) bool {570 return i < j571}572func TestBetweenCmp(t *testing.T) {573 t.Run("compareType", func(t *testing.T) {...
td_error_is_test.go
Source:td_error_is_test.go
1// Copyright (c) 2022, 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 td_test7import (8 "fmt"9 "testing"10 "github.com/maxatome/go-testdeep/internal/dark"11 "github.com/maxatome/go-testdeep/internal/test"12 "github.com/maxatome/go-testdeep/td"13)14func TestErrorIs(t *testing.T) {15 insideErr1 := fmt.Errorf("failure1")16 insideErr2 := fmt.Errorf("failure2: %w", insideErr1)17 insideErr3 := fmt.Errorf("failure3: %w", insideErr2)18 err := fmt.Errorf("failure4: %w", insideErr3)19 checkOK(t, err, td.ErrorIs(err))20 checkOK(t, err, td.ErrorIs(insideErr3))21 checkOK(t, err, td.ErrorIs(insideErr2))22 checkOK(t, err, td.ErrorIs(insideErr1))23 checkOK(t, nil, td.ErrorIs(nil))24 var errNil error25 checkOK(t, &errNil, td.Ptr(td.ErrorIs(nil)))26 checkError(t, nil, td.ErrorIs(insideErr1),27 expectedError{28 Message: mustBe("nil value"),29 Path: mustBe("DATA"),30 Got: mustBe("nil"),31 Expected: mustBe("anything implementing error interface"),32 })33 checkError(t, 45, td.ErrorIs(insideErr1),34 expectedError{35 Message: mustBe("int does not implement error interface"),36 Path: mustBe("DATA"),37 Got: mustBe("45"),38 Expected: mustBe("anything implementing error interface"),39 })40 checkError(t, 45, td.ErrorIs(fmt.Errorf("another")),41 expectedError{42 Message: mustBe("int does not implement error interface"),43 Path: mustBe("DATA"),44 Got: mustBe("45"),45 Expected: mustBe("anything implementing error interface"),46 })47 checkError(t, err, td.ErrorIs(fmt.Errorf("another")),48 expectedError{49 Message: mustBe("is not the error"),50 Path: mustBe("DATA"),51 Got: mustBe(`(*fmt.wrapError) "failure4: failure3: failure2: failure1"`),52 Expected: mustBe(`(*errors.errorString) "another"`),53 })54 checkError(t, err, td.ErrorIs(nil),55 expectedError{56 Message: mustBe("is not the error"),57 Path: mustBe("DATA"),58 Got: mustBe(`(*fmt.wrapError) "failure4: failure3: failure2: failure1"`),59 Expected: mustBe(`nil`),60 })61 type private struct{ err error }62 got := private{err: err}63 for _, expErr := range []error{err, insideErr3} {64 expected := td.Struct(private{}, td.StructFields{"err": td.ErrorIs(expErr)})65 if dark.UnsafeDisabled {66 checkError(t, got, expected,67 expectedError{68 Message: mustBe("cannot compare"),69 Path: mustBe("DATA.err"),70 Summary: mustBe("unexported field that cannot be overridden"),71 })72 } else {73 checkOK(t, got, expected)74 }75 }76 if !dark.UnsafeDisabled {77 got = private{}78 checkOK(t, got, td.Struct(private{}, td.StructFields{"err": td.ErrorIs(nil)}))79 }80 //81 // String82 test.EqualStr(t, td.ErrorIs(insideErr1).String(), "ErrorIs(failure1)")83 test.EqualStr(t, td.ErrorIs(nil).String(), "ErrorIs(nil)")84}85func TestErrorIsTypeBehind(t *testing.T) {86 equalTypes(t, td.ErrorIs(fmt.Errorf("another")), nil)87}...
Compare
Using AI Code Generation
1import "fmt"2func main() {3 t1 = td_test{1, 2}4 t2 = td_test{1, 2}5 t3 = td_test{2, 1}6 fmt.Println("t1 == t2", t1 == t2)7 fmt.Println("t1 == t3", t1 == t3)8}
Compare
Using AI Code Generation
1import (2type td_test struct {3}4func main() {5 if reflect.DeepEqual(s1, s2) {6 fmt.Println("Equal")7 } else {8 fmt.Println("Not Equal")9 }10}
Compare
Using AI Code Generation
1import (2func main() {3 t1 := td.New(1, 2)4 t2 := td.New(1, 2)5 t3 := td.New(2, 2)6 t4 := td.New(3, 2)7 t5 := td.New(1, 3)8 fmt.Println("t1==t2:", t1.Compare(t2))9 fmt.Println("t1==t3:", t1.Compare(t3))10 fmt.Println("t1==t4:", t1.Compare(t4))11 fmt.Println("t1==t5:", t1.Compare(t5))12}
Compare
Using AI Code Generation
1import (2func main() {3 fmt.Println("Enter 3 numbers")4 fmt.Scan(&a, &b, &c)5 test.Compare(a, b, c)6}7import (8func main() {9 fmt.Println("Enter 3 numbers")10 fmt.Scan(&a, &b, &c)11 test.Compare(a, b, c)12}13import (14func main() {15 fmt.Println("Enter 3 numbers")16 fmt.Scan(&a, &b, &c)17 test.Compare(a, b, c)18}19import (20func main() {21 fmt.Println("Enter 3 numbers")22 fmt.Scan(&a, &b, &c)23 test.Compare(a, b, c)24}25import (26func main() {27 fmt.Println("Enter 3 numbers")28 fmt.Scan(&a, &b, &c)29 test.Compare(a, b, c)30}31import (32func main() {33 fmt.Println("Enter 3 numbers")34 fmt.Scan(&a, &b, &c)35 test.Compare(a, b, c)36}37import (38func main() {39 fmt.Println("Enter 3 numbers")40 fmt.Scan(&a, &b, &c)41 test.Compare(a, b, c)42}
Compare
Using AI Code Generation
1import (2func main() {3 fmt.Println("Comparing two css files")4 td_test.Compare(s1, s2)5 fmt.Println("Comparing two html files")6 td_test.Compare(s3, s4)7 fmt.Println("Comparing two js files")8 td_test.Compare(s5, s6)9 fmt.Println("Comparing two json files")10 td_test.Compare(s7, s8)11 fmt.Println("Comparing two xml files")12 td_test.Compare(s9, s10)13 fmt.Println("Comparing two yaml files")14 td_test.Compare(s11, s12)15 fmt.Println("Comparing two txt files")16 td_test.Compare(s13, s14)17}18import (19func main() {20 fmt.Println("Comparing two css files")21 td_test.Compare(s1, s2)
Compare
Using AI Code Generation
1import "fmt"2func main() {3 c := td_test{1, 2}4 d := td_test{1, 2}5 fmt.Println(c.Compare(d))6}7import (8type td_test struct {9}10func main() {11 c := td_test{1, 2}12 d := td_test{1, 2}13 fmt.Println(reflect.DeepEqual(c, d))14}
Compare
Using AI Code Generation
1import (2func main() {3 td1 := td_test{1, "test1", 1.1}4 td2 := td_test{2, "test2", 2.2}5 if td1.Compare(td2) {6 fmt.Println("td1 is equal to td2")7 } else {8 fmt.Println("td1 is not equal to td2")9 }10}11func (t Type) methodName(parameter list) return type {12}13import (14type td_test struct {15}16func (t td_test) printDetails() {17 fmt.Println("id:", t.id)18 fmt.Println("name:", t.name)19 fmt.Println("age:", t.age)20}21func main() {22 td1 := td_test{1, "test1", 1.1}23 td1.printDetails()24}
Compare
Using AI Code Generation
1import (2func main() {3 t.Set(1)4 fmt.Println(t.Compare(1))5}6import (7func main() {8 t.Set(1)9 fmt.Println(t.Compare(2))10}11import (12func main() {13 t.Set(1)14 fmt.Println(t.Compare(3))15}16import (17func main() {18 t.Set(1)19 fmt.Println(t.Compare(4))20}21import (22func main() {23 t.Set(1)24 fmt.Println(t.Compare(5))25}26import (27func main() {28 t.Set(1)29 fmt.Println(t.Compare(6))30}31import (32func main() {33 t.Set(1)34 fmt.Println(t.Compare(7))35}36import (37func main() {38 t.Set(1)39 fmt.Println(t.Compare(8))40}
Compare
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello, playground")4 fmt.Println(t1.Compare(t2))5 fmt.Println(t1.Compare(t1))6 fmt.Println(t2.Compare(t2))7}
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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!