Best Go-testdeep code snippet using td.AnchorsPersistTemporarily
test_api.go
Source:test_api.go
...494// }))495//496// It fails if no request has been sent yet.497func (ta *TestAPI) CmpResponse(expectedResponse any) *TestAPI {498 defer ta.t.AnchorsPersistTemporarily()()499 ta.t.Helper()500 if !ta.checkRequestSent() {501 ta.failed |= responseFailed502 return ta503 }504 if !ta.t.RootName("Response").505 Cmp(ta.response.Result(), expectedResponse, ta.name+"full response should match") {506 ta.failed |= responseFailed507 if ta.autoDumpResponse {508 ta.dumpResponse()509 }510 }511 return ta512}513// CmpStatus tests the last request response status against514// expectedStatus. expectedStatus can be an int to match a fixed HTTP515// status code, or a [td.TestDeep] operator.516//517// ta := tdhttp.NewTestAPI(t, mux)518//519// ta.Get("/test").520// CmpStatus(http.StatusOK)521//522// ta.PostJSON("/new", map[string]string{"name": "Bob"}).523// CmpStatus(td.Between(200, 202))524//525// It fails if no request has been sent yet.526func (ta *TestAPI) CmpStatus(expectedStatus any) *TestAPI {527 defer ta.t.AnchorsPersistTemporarily()()528 ta.t.Helper()529 if !ta.checkRequestSent() {530 ta.failed |= statusFailed531 return ta532 }533 if !ta.t.RootName("Response.Status").534 CmpLax(ta.response.Code, expectedStatus, ta.name+"status code should match") {535 ta.failed |= statusFailed536 if ta.autoDumpResponse {537 ta.dumpResponse()538 }539 }540 return ta541}542// CmpHeader tests the last request response header against543// expectedHeader. expectedHeader can be a [http.Header] or a544// [td.TestDeep] operator. Keep in mind that if it is a [http.Header],545// it has to match exactly the response header. Often only the546// presence of a header key is needed:547//548// ta := tdhttp.NewTestAPI(t, mux).549// PostJSON("/new", map[string]string{"name": "Bob"}).550// CmdStatus(201).551// CmpHeader(td.ContainsKey("X-Custom"))552//553// or some specific key, value pairs:554//555// ta.CmpHeader(td.SuperMapOf(556// http.Header{557// "X-Account": []string{"Bob"},558// },559// td.MapEntries{560// "X-Token": td.Bag(td.Re(`^[a-z0-9-]{32}\z`)),561// }),562// )563//564// Note that CmpHeader calls can be chained:565//566// ta.CmpHeader(td.ContainsKey("X-Account")).567// CmpHeader(td.ContainsKey("X-Token"))568//569// instead of doing all tests in one call as [td.All] operator allows it:570//571// ta.CmpHeader(td.All(572// td.ContainsKey("X-Account"),573// td.ContainsKey("X-Token"),574// ))575//576// It fails if no request has been sent yet.577func (ta *TestAPI) CmpHeader(expectedHeader any) *TestAPI {578 defer ta.t.AnchorsPersistTemporarily()()579 ta.t.Helper()580 if !ta.checkRequestSent() {581 ta.failed |= headerFailed582 return ta583 }584 if !ta.t.RootName("Response.Header").585 CmpLax(ta.response.Result().Header, expectedHeader, ta.name+"header should match") {586 ta.failed |= headerFailed587 if ta.autoDumpResponse {588 ta.dumpResponse()589 }590 }591 return ta592}593// CmpTrailer tests the last request response trailer against594// expectedTrailer. expectedTrailer can be a [http.Header] or a595// [td.TestDeep] operator. Keep in mind that if it is a [http.Header],596// it has to match exactly the response trailer. Often only the597// presence of a trailer key is needed:598//599// ta := tdhttp.NewTestAPI(t, mux).600// PostJSON("/new", map[string]string{"name": "Bob"}).601// CmdStatus(201).602// CmpTrailer(td.ContainsKey("X-Custom"))603//604// or some specific key, value pairs:605//606// ta.CmpTrailer(td.SuperMapOf(607// http.Header{608// "X-Account": []string{"Bob"},609// },610// td.MapEntries{611// "X-Token": td.Re(`^[a-z0-9-]{32}\z`),612// }),613// )614//615// Note that CmpTrailer calls can be chained:616//617// ta.CmpTrailer(td.ContainsKey("X-Account")).618// CmpTrailer(td.ContainsKey("X-Token"))619//620// instead of doing all tests in one call as [td.All] operator allows it:621//622// ta.CmpTrailer(td.All(623// td.ContainsKey("X-Account"),624// td.ContainsKey("X-Token"),625// ))626//627// It fails if no request has been sent yet.628//629// Note that until go1.19, it does not handle multiple values in630// a single Trailer header field.631func (ta *TestAPI) CmpTrailer(expectedTrailer any) *TestAPI {632 defer ta.t.AnchorsPersistTemporarily()()633 ta.t.Helper()634 if !ta.checkRequestSent() {635 ta.failed |= trailerFailed636 return ta637 }638 if !ta.t.RootName("Response.Trailer").639 CmpLax(ta.response.Result().Trailer, expectedTrailer, ta.name+"trailer should match") {640 ta.failed |= trailerFailed641 if ta.autoDumpResponse {642 ta.dumpResponse()643 }644 }645 return ta646}647// CmpCookies tests the last request response cookies against648// expectedCookies. expectedCookies can be a [][*http.Cookie] or a649// [td.TestDeep] operator. Keep in mind that if it is a650// [][*http.Cookie], it has to match exactly the response651// cookies. Often only the presence of a cookie key is needed:652//653// ta := tdhttp.NewTestAPI(t, mux).654// PostJSON("/login", map[string]string{"name": "Bob", "password": "Sponge"}).655// CmdStatus(200).656// CmpCookies(td.SuperBagOf(td.Struct(&http.Cookie{Name: "cookie_session"}, nil))).657// CmpCookies(td.SuperBagOf(td.Smuggle("Name", "cookie_session"))) // shorter658//659// To make tests easier, [http.Cookie.Raw] and [http.Cookie.RawExpires] fields660// of each [*http.Cookie] are zeroed before doing the comparison. So no need661// to fill them when comparing against a simple literal as in:662//663// ta := tdhttp.NewTestAPI(t, mux).664// PostJSON("/login", map[string]string{"name": "Bob", "password": "Sponge"}).665// CmdStatus(200).666// CmpCookies([]*http.Cookies{667// {Name: "cookieName1", Value: "cookieValue1"},668// {Name: "cookieName2", Value: "cookieValue2"},669// })670//671// It fails if no request has been sent yet.672func (ta *TestAPI) CmpCookies(expectedCookies any) *TestAPI {673 defer ta.t.AnchorsPersistTemporarily()()674 ta.t.Helper()675 if !ta.checkRequestSent() {676 ta.failed |= cookiesFailed677 return ta678 }679 // Empty Raw* fields to make comparisons easier680 cookies := ta.response.Result().Cookies()681 for _, c := range cookies {682 c.RawExpires, c.Raw = "", ""683 }684 if !ta.t.RootName("Response.Cookie").685 CmpLax(cookies, expectedCookies, ta.name+"cookies should match") {686 ta.failed |= cookiesFailed687 if ta.autoDumpResponse {688 ta.dumpResponse()689 }690 }691 return ta692}693// findCmpXBodyCaller finds the oldest Cmp* method called.694func findCmpXBodyCaller() string {695 var (696 fn string697 pc [20]uintptr698 found bool699 )700 if num := runtime.Callers(5, pc[:]); num > 0 {701 frames := runtime.CallersFrames(pc[:num])702 for {703 frame, more := frames.Next()704 if pos := strings.Index(frame.Function, "tdhttp.(*TestAPI).Cmp"); pos > 0 {705 fn = frame.Function[pos+18:]706 found = true707 } else if found {708 more = false709 }710 if !more {711 break712 }713 }714 }715 return fn716}717func (ta *TestAPI) cmpMarshaledBody(718 acceptEmptyBody bool,719 unmarshal func([]byte, any) error,720 expectedBody any,721) *TestAPI {722 defer ta.t.AnchorsPersistTemporarily()()723 ta.t.Helper()724 if !ta.checkRequestSent() {725 ta.failed |= bodyFailed726 return ta727 }728 if !acceptEmptyBody &&729 !ta.t.RootName("Response body").Code(ta.response.Body.Bytes(),730 func(b []byte) error {731 if len(b) > 0 {732 return nil733 }734 return &ctxerr.Error{735 Message: "%% is empty!",736 Summary: ctxerr.NewSummary(737 "Body cannot be empty when using " + findCmpXBodyCaller()),738 }739 },740 ta.name+"body should not be empty") {741 ta.failed |= bodyFailed742 if ta.autoDumpResponse {743 ta.dumpResponse()744 }745 return ta746 }747 tt := ta.t.RootName("Response.Body")748 var bodyType reflect.Type749 // If expectedBody is a TestDeep operator, try to ask it the type750 // behind it. It should work in most cases (typically Struct(),751 // Map() & Slice()).752 var unknownExpectedType, showRawBody bool753 op, ok := expectedBody.(td.TestDeep)754 if ok {755 bodyType = op.TypeBehind()756 if bodyType == nil {757 // As the expected body type cannot be guessed, try to758 // unmarshal in an any759 bodyType = types.Interface760 unknownExpectedType = true761 // Special case for Ignore & NotEmpty operators762 switch op.GetLocation().Func {763 case "Ignore", "NotEmpty":764 showRawBody = (ta.failed & statusFailed) != 0 // Show real body if status failed765 }766 }767 } else {768 bodyType = reflect.TypeOf(expectedBody)769 if bodyType == nil {770 bodyType = types.Interface771 }772 }773 // For unmarshaling below, body must be a pointer774 bodyPtr := reflect.New(bodyType)775 // Try to unmarshal body776 if !tt.RootName("unmarshal(Response.Body)").777 CmpNoError(unmarshal(ta.response.Body.Bytes(), bodyPtr.Interface()), ta.name+"body unmarshaling") {778 // If unmarshal failed, perhaps it's coz the expected body type779 // is unknown?780 if unknownExpectedType {781 tt.Logf("Cannot guess the body expected type as %[1]s TestDeep\n"+782 "operator does not know the type behind it.\n"+783 "You can try All(Isa(EXPECTED_TYPE), %[1]s(â¦)) to disambiguateâ¦",784 op.GetLocation().Func)785 }786 showRawBody = true // let's show its real body contents787 ta.failed |= bodyFailed788 } else if !tt.Cmp(bodyPtr.Elem().Interface(), expectedBody, ta.name+"body contents is OK") {789 // Try to catch bad body expected type when nothing has been set790 // to non-zero during unmarshaling body. In this case, require791 // to show raw body contents.792 if len(ta.response.Body.Bytes()) > 0 &&793 td.EqDeeply(bodyPtr.Interface(), reflect.New(bodyType).Interface()) {794 showRawBody = true795 tt.Log("Hmm⦠It seems nothing has been set during unmarshalingâ¦")796 }797 ta.failed |= bodyFailed798 }799 if showRawBody || ((ta.failed&bodyFailed) != 0 && ta.autoDumpResponse) {800 ta.dumpResponse()801 }802 return ta803}804// CmpMarshaledBody tests that the last request response body can be805// unmarshaled using unmarshal function and then, that it matches806// expectedBody. expectedBody can be any type unmarshal function can807// handle, or a [td.TestDeep] operator.808//809// See [TestAPI.CmpJSONBody] and [TestAPI.CmpXMLBody] sources for810// examples of use.811//812// It fails if no request has been sent yet.813func (ta *TestAPI) CmpMarshaledBody(unmarshal func([]byte, any) error, expectedBody any) *TestAPI {814 ta.t.Helper()815 return ta.cmpMarshaledBody(false, unmarshal, expectedBody)816}817// CmpBody tests the last request response body against818// expectedBody. expectedBody can be a []byte, a string or a819// [td.TestDeep] operator.820//821// ta := tdhttp.NewTestAPI(t, mux)822//823// ta.Get("/test").824// CmpStatus(http.StatusOK).825// CmpBody("OK!\n")826//827// ta.Get("/test").828// CmpStatus(http.StatusOK).829// CmpBody(td.Contains("OK"))830//831// It fails if no request has been sent yet.832func (ta *TestAPI) CmpBody(expectedBody any) *TestAPI {833 ta.t.Helper()834 if expectedBody == nil {835 return ta.NoBody()836 }837 return ta.cmpMarshaledBody(838 true, // accept empty body839 func(body []byte, target any) error {840 switch target := target.(type) {841 case *string:842 *target = string(body)843 case *[]byte:844 *target = body845 case *any:846 *target = body847 default:848 // cmpMarshaledBody always calls us with target as a pointer849 return fmt.Errorf(850 "CmpBody only accepts expectedBody be a []byte, a string or a TestDeep operator allowing to match these types, but not type %s",851 reflect.TypeOf(target).Elem())852 }853 return nil854 },855 expectedBody)856}857// CmpJSONBody tests that the last request response body can be858// [json.Unmarshal]'ed and that it matches expectedBody. expectedBody859// can be any type one can [json.Unmarshal] into, or a [td.TestDeep]860// operator.861//862// ta := tdhttp.NewTestAPI(t, mux)863//864// ta.Get("/person/42").865// CmpStatus(http.StatusOK).866// CmpJSONBody(Person{867// ID: 42,868// Name: "Bob",869// Age: 26,870// })871//872// ta.PostJSON("/person", Person{Name: "Bob", Age: 23}).873// CmpStatus(http.StatusCreated).874// CmpJSONBody(td.SStruct(875// Person{876// Name: "Bob",877// Age: 26,878// },879// td.StructFields{880// "ID": td.NotZero(),881// }))882//883// The same with anchoring, and so without [td.SStruct]:884//885// ta := tdhttp.NewTestAPI(tt, mux)886//887// ta.PostJSON("/person", Person{Name: "Bob", Age: 23}).888// CmpStatus(http.StatusCreated).889// CmpJSONBody(Person{890// ID: ta.Anchor(td.NotZero(), uint64(0)).(uint64),891// Name: "Bob",892// Age: 26,893// })894//895// The same using [td.JSON]:896//897// ta.PostJSON("/person", Person{Name: "Bob", Age: 23}).898// CmpStatus(http.StatusCreated).899// CmpJSONBody(td.JSON(`900// {901// "id": NotZero(),902// "name": "Bob",903// "age": 26904// }`))905//906// It fails if no request has been sent yet.907func (ta *TestAPI) CmpJSONBody(expectedBody any) *TestAPI {908 ta.t.Helper()909 return ta.CmpMarshaledBody(json.Unmarshal, expectedBody)910}911// CmpXMLBody tests that the last request response body can be912// [xml.Unmarshal]'ed and that it matches expectedBody. expectedBody913// can be any type one can [xml.Unmarshal] into, or a [td.TestDeep]914// operator.915//916// ta := tdhttp.NewTestAPI(t, mux)917//918// ta.Get("/person/42").919// CmpStatus(http.StatusOK).920// CmpXMLBody(Person{921// ID: 42,922// Name: "Bob",923// Age: 26,924// })925//926// ta.Get("/person/43").927// CmpStatus(http.StatusOK).928// CmpXMLBody(td.SStruct(929// Person{930// Name: "Bob",931// Age: 26,932// },933// td.StructFields{934// "ID": td.NotZero(),935// }))936//937// The same with anchoring:938//939// ta := tdhttp.NewTestAPI(tt, mux)940//941// ta.Get("/person/42").942// CmpStatus(http.StatusOK).943// CmpXMLBody(Person{944// ID: ta.Anchor(td.NotZero(), uint64(0)).(uint64),945// Name: "Bob",946// Age: 26,947// })948//949// It fails if no request has been sent yet.950func (ta *TestAPI) CmpXMLBody(expectedBody any) *TestAPI {951 ta.t.Helper()952 return ta.CmpMarshaledBody(xml.Unmarshal, expectedBody)953}954// NoBody tests that the last request response body is empty.955//956// It fails if no request has been sent yet.957func (ta *TestAPI) NoBody() *TestAPI {958 defer ta.t.AnchorsPersistTemporarily()()959 ta.t.Helper()960 if !ta.checkRequestSent() {961 ta.failed |= bodyFailed962 return ta963 }964 ok := ta.t.RootName("Response.Body").965 Code(len(ta.response.Body.Bytes()) == 0,966 func(empty bool) error {967 if empty {968 return nil969 }970 return &ctxerr.Error{971 Message: "%% is not empty",972 Got: types.RawString("not empty"),...
t_anchor.go
Source:t_anchor.go
...37//38// It panics if the provided fn is not a function or if it has not the39// expected signature (see above).40//41// See also [T.Anchor], [T.AnchorsPersistTemporarily],42// [T.DoAnchorsPersist], [T.ResetAnchors] and [T.SetAnchorsPersist].43func AddAnchorableStructType(fn any) {44 err := anchors.AddAnchorableStructType(fn)45 if err != nil {46 panic(color.Bad(err.Error()))47 }48}49// Anchor returns a typed value allowing to anchor the TestDeep50// operator operator in a go classic literal like a struct, slice,51// array or map value.52//53// If the TypeBehind method of operator returns non-nil, model can be54// omitted (like with [Between] operator in the example55// below). Otherwise, model should contain only one value56// corresponding to the returning type. It can be:57// - a go value: returning type is the type of the value,58// whatever the value is;59// - a [reflect.Type].60//61// It returns a typed value ready to be embed in a go data structure to62// be compared using [T.Cmp] or [T.CmpLax]:63//64// import (65// "testing"66//67// "github.com/maxatome/go-testdeep/td"68// )69//70// func TestFunc(tt *testing.T) {71// got := Func()72//73// t := td.NewT(tt)74// t.Cmp(got, &MyStruct{75// Name: "Bob",76// Details: &MyDetails{77// Nick: t.Anchor(td.HasPrefix("Bobby"), "").(string),78// Age: t.Anchor(td.Between(40, 50)).(int),79// },80// })81// }82//83// In this example:84//85// - [HasPrefix] operates on several input types (string,86// [fmt.Stringer], error, â¦), so its TypeBehind method returns always87// nil as it can not guess in advance on which type it operates. In88// this case, we must pass "" as model parameter in order to tell it89// to return the string type. Note that the .(string) type assertion90// is then mandatory to conform to the strict type checking.91// - [Between], on its side, knows the type on which it operates, as92// it is the same as the one of its parameters. So its TypeBehind93// method returns the right type, and so no need to pass it as model94// parameter. Note that the .(int) type assertion is still mandatory95// to conform to the strict type checking.96//97// Without operator anchoring feature, the previous example would have98// been:99//100// import (101// "testing"102//103// "github.com/maxatome/go-testdeep/td"104// )105//106// func TestFunc(tt *testing.T) {107// got := Func()108//109// t := td.NewT(tt)110// t.Cmp(got, td.Struct(&MyStruct{Name: "Bob"},111// td.StructFields{112// "Details": td.Struct(&MyDetails{},113// td.StructFields{114// "Nick": td.HasPrefix("Bobby"),115// "Age": td.Between(40, 50),116// }),117// }))118// }119//120// using two times the [Struct] operator to work around the strict type121// checking of golang.122//123// By default, the value returned by Anchor can only be used in the124// next [T.Cmp] or [T.CmpLax] call. To make it persistent across calls,125// see [T.SetAnchorsPersist] and [T.AnchorsPersistTemporarily] methods.126//127// See [T.A] method for a shorter synonym of Anchor.128//129// See also [T.AnchorsPersistTemporarily], [T.DoAnchorsPersist],130// [T.ResetAnchors], [T.SetAnchorsPersist] and [AddAnchorableStructType].131func (t *T) Anchor(operator TestDeep, model ...any) any {132 if operator == nil {133 t.Helper()134 t.Fatal(color.Bad("Cannot anchor a nil TestDeep operator"))135 }136 var typ reflect.Type137 if len(model) > 0 {138 if len(model) != 1 {139 t.Helper()140 t.Fatal(color.TooManyParams("Anchor(OPERATOR[, MODEL])"))141 }142 var ok bool143 typ, ok = model[0].(reflect.Type)144 if !ok {145 typ = reflect.TypeOf(model[0])146 if typ == nil {147 t.Helper()148 t.Fatal(color.Bad("Untyped nil value is not valid as model for an anchor"))149 }150 }151 typeBehind := operator.TypeBehind()152 if typeBehind != nil && typeBehind != typ {153 t.Helper()154 t.Fatal(color.Bad("Operator %s TypeBehind() returned %s which differs from model type %s. Omit model or ensure its type is %[2]s",155 operator.GetLocation().Func, typeBehind, typ))156 }157 } else {158 typ = operator.TypeBehind()159 if typ == nil {160 t.Helper()161 t.Fatal(color.Bad("Cannot anchor operator %s as TypeBehind() returned nil. Use model parameter to specify the type to return",162 operator.GetLocation().Func))163 }164 }165 nvm, err := t.Config.anchors.AddAnchor(typ, reflect.ValueOf(operator))166 if err != nil {167 t.Helper()168 t.Fatal(color.Bad(err.Error()))169 }170 return nvm.Interface()171}172// A is a synonym for [T.Anchor].173//174// import (175// "testing"176//177// "github.com/maxatome/go-testdeep/td"178// )179//180// func TestFunc(tt *testing.T) {181// got := Func()182//183// t := td.NewT(tt)184// t.Cmp(got, &MyStruct{185// Name: "Bob",186// Details: &MyDetails{187// Nick: t.A(td.HasPrefix("Bobby"), "").(string),188// Age: t.A(td.Between(40, 50)).(int),189// },190// })191// }192//193// See also [T.AnchorsPersistTemporarily], [T.DoAnchorsPersist],194// [T.ResetAnchors], [T.SetAnchorsPersist] and [AddAnchorableStructType].195func (t *T) A(operator TestDeep, model ...any) any {196 t.Helper()197 return t.Anchor(operator, model...)198}199func (t *T) resetNonPersistentAnchors() {200 t.Config.anchors.ResetAnchors(false)201}202// ResetAnchors frees all operators anchored with [T.Anchor]203// method. Unless operators anchoring persistence has been enabled204// with [T.SetAnchorsPersist], there is no need to call this205// method. Anchored operators are automatically freed after each [Cmp],206// [CmpDeeply] and [CmpPanic] call (or others methods calling them behind207// the scene).208//209// See also [T.Anchor], [T.AnchorsPersistTemporarily],210// [T.DoAnchorsPersist], [T.SetAnchorsPersist] and [AddAnchorableStructType].211func (t *T) ResetAnchors() {212 t.Config.anchors.ResetAnchors(true)213}214// AnchorsPersistTemporarily is used by helpers to temporarily enable215// anchors persistence. See [tdhttp] package for an example of use. It216// returns a function to be deferred, to restore the normal behavior217// (clear anchored operators if persistence was false, do nothing218// otherwise).219//220// Typically used as:221//222// defer t.AnchorsPersistTemporarily()()223// // or224// t.Cleanup(t.AnchorsPersistTemporarily())225//226// See also [T.Anchor], [T.DoAnchorsPersist], [T.ResetAnchors],227// [T.SetAnchorsPersist] and [AddAnchorableStructType].228//229// [tdhttp]: https://pkg.go.dev/github.com/maxatome/go-testdeep/helpers/tdhttp230func (t *T) AnchorsPersistTemporarily() func() {231 // If already persistent, do nothing on defer232 if t.DoAnchorsPersist() {233 return func() {}234 }235 t.SetAnchorsPersist(true)236 return func() {237 t.SetAnchorsPersist(false)238 t.Config.anchors.ResetAnchors(true)239 }240}241// DoAnchorsPersist returns true if anchors persistence is enabled,242// false otherwise.243//244// See also [T.Anchor], [T.AnchorsPersistTemporarily],245// [T.ResetAnchors], [T.SetAnchorsPersist] and [AddAnchorableStructType].246func (t *T) DoAnchorsPersist() bool {247 return t.Config.anchors.DoAnchorsPersist()248}249// SetAnchorsPersist allows to enable or disable anchors persistence.250//251// See also [T.Anchor], [T.AnchorsPersistTemporarily],252// [T.DoAnchorsPersist], [T.ResetAnchors] and [AddAnchorableStructType].253func (t *T) SetAnchorsPersist(persist bool) {254 t.Config.anchors.SetAnchorsPersist(persist)255}256func (t *T) initAnchors() {257 if t.Config.anchors != nil {258 return259 }260 name := t.Name()261 allAnchorsMu.Lock()262 defer allAnchorsMu.Unlock()263 t.Config.anchors = allAnchors[name]264 if t.Config.anchors == nil {265 t.Config.anchors = anchors.NewInfo()...
t_anchor_test.go
Source:t_anchor_test.go
...60 td.CmpFalse(tt, t.Cmp(got, MyStruct{Num: numOp}))61 })62 tt.Run("with persistence", func(tt *testing.T) {63 numOp := t.Anchor(td.Between(int64(135), int64(137))).(int64)64 defer t.AnchorsPersistTemporarily()()65 td.CmpTrue(tt, t.Cmp(got, MyStruct{Num: numOp}))66 td.CmpTrue(tt, t.Cmp(got, MyStruct{Num: numOp}))67 t.ResetAnchors() // force reset anchored operators68 td.CmpFalse(tt, t.Cmp(got, MyStruct{Num: numOp}))69 })70 // Errors71 tt.Run("errors", func(tt *testing.T) {72 td.Cmp(tt, ttt.CatchFatal(func() { t.Anchor(nil) }),73 "Cannot anchor a nil TestDeep operator")74 td.Cmp(tt, ttt.CatchFatal(func() { t.Anchor(td.Ignore(), 1, 2) }),75 "usage: Anchor(OPERATOR[, MODEL]), too many parameters")76 td.Cmp(tt, ttt.CatchFatal(func() { t.Anchor(td.Ignore(), nil) }),77 "Untyped nil value is not valid as model for an anchor")78 td.Cmp(tt, ttt.CatchFatal(func() { t.Anchor(td.Between(1, 2), 12.3) }),79 "Operator Between TypeBehind() returned int which differs from model type float64. Omit model or ensure its type is int")80 td.Cmp(tt, ttt.CatchFatal(func() { t.Anchor(td.Ignore()) }),81 "Cannot anchor operator Ignore as TypeBehind() returned nil. Use model parameter to specify the type to return")82 })83}84type privStruct struct {85 num int6486}87func (p privStruct) Num() int64 {88 return p.num89}90func TestAddAnchorableStructType(tt *testing.T) {91 type MyStruct struct {92 Priv privStruct93 }94 ttt := test.NewTestingTB(tt.Name())95 t := td.NewT(ttt)96 // We want to anchor this operator97 op := td.Smuggle((privStruct).Num, int64(42))98 // Without making privStruct anchorable, it does not work99 td.Cmp(tt, ttt.CatchFatal(func() { t.A(op, privStruct{}) }),100 "td_test.privStruct struct type is not supported as an anchor. Try AddAnchorableStructType")101 // Make privStruct anchorable102 td.AddAnchorableStructType(func(nextAnchor int) privStruct {103 return privStruct{num: int64(2e9 - nextAnchor)}104 })105 td.CmpTrue(tt,106 t.Cmp(MyStruct{Priv: privStruct{num: 42}},107 MyStruct{108 Priv: t.A(op, privStruct{}).(privStruct), // â now it works109 }))110 // Error111 test.CheckPanic(tt,112 func() { td.AddAnchorableStructType(123) },113 "usage: AddAnchorableStructType(func (nextAnchor int) STRUCT_TYPE)")114}115func TestAnchorsPersist(tt *testing.T) {116 ttt := test.NewTestingTB(tt.Name())117 t1 := td.NewT(ttt)118 t2 := td.NewT(ttt)119 t3 := td.NewT(t1)120 tt.Run("without anchors persistence", func(tt *testing.T) {121 // Anchors persistence is shared for a same testing.TB122 td.CmpFalse(tt, t1.DoAnchorsPersist())123 td.CmpFalse(tt, t2.DoAnchorsPersist())124 td.CmpFalse(tt, t3.DoAnchorsPersist())125 func() {126 defer t1.AnchorsPersistTemporarily()()127 td.CmpTrue(tt, t1.DoAnchorsPersist())128 td.CmpTrue(tt, t2.DoAnchorsPersist())129 td.CmpTrue(tt, t3.DoAnchorsPersist())130 }()131 td.CmpFalse(tt, t1.DoAnchorsPersist())132 td.CmpFalse(tt, t2.DoAnchorsPersist())133 td.CmpFalse(tt, t3.DoAnchorsPersist())134 })135 tt.Run("with anchors persistence", func(tt *testing.T) {136 t3.SetAnchorsPersist(true)137 td.CmpTrue(tt, t1.DoAnchorsPersist())138 td.CmpTrue(tt, t2.DoAnchorsPersist())139 td.CmpTrue(tt, t3.DoAnchorsPersist())140 func() {141 defer t1.AnchorsPersistTemporarily()()142 td.CmpTrue(tt, t1.DoAnchorsPersist())143 td.CmpTrue(tt, t2.DoAnchorsPersist())144 td.CmpTrue(tt, t3.DoAnchorsPersist())145 }()146 td.CmpTrue(tt, t1.DoAnchorsPersist())147 td.CmpTrue(tt, t2.DoAnchorsPersist())148 td.CmpTrue(tt, t3.DoAnchorsPersist())149 })150}...
AnchorsPersistTemporarily
Using AI Code Generation
1import (2func main() {3 file = xlsx.NewFile()4 sheet, err = file.AddSheet("Sheet1")5 if err != nil {6 fmt.Printf(err.Error())7 }8 row = sheet.AddRow()9 cell = row.AddCell()10 cell.SetString("Hello")11 cell = row.AddCell()12 cell.SetString("World")13 err = file.Save("AnchorsPersistTemporarily.xlsx")14 if err != nil {15 fmt.Printf(err.Error())16 }17}
AnchorsPersistTemporarily
Using AI Code Generation
1import (2func main() {3 xlFile, err := xlsx.OpenFile("sample.xlsx")4 if err != nil {5 fmt.Println(err)6 }7 for _, sheet := range xlFile.Sheets {8 for _, row := range sheet.Rows {9 for _, cell := range row.Cells {10 text := cell.String()11 fmt.Printf("%s\t", text)12 }13 fmt.Println()14 }15 }16}17import (18func main() {19 xlFile, err := xlsx.OpenFile("sample.xlsx")20 if err != nil {21 fmt.Println(err)22 }23 for _, sheet := range xlFile.Sheets {24 for _, row := range sheet.Rows {25 for _, cell := range row.Cells {26 text := cell.String()27 fmt.Printf("%s\t", text)28 }29 fmt.Println()30 }31 }32}33import (34func main() {35 xlFile, err := xlsx.OpenFile("sample.xlsx")36 if err != nil {37 fmt.Println(err)38 }39 for _, sheet := range xlFile.Sheets {40 for _, row := range sheet.Rows {
AnchorsPersistTemporarily
Using AI Code Generation
1import (2func main() {3 if len(os.Args) < 2 {4 fmt.Println("How to run:\n\tgo run 2.go [video file]")5 }6 webcam, err := gocv.VideoCaptureFile(os.Args[1])7 if err != nil {8 fmt.Printf("Error opening video capture device: %v\n", 0)9 }10 defer webcam.Close()11 img := gocv.NewMat()12 defer img.Close()13 img2 := gocv.NewMat()14 defer img2.Close()15 blue := color.RGBA{0, 0, 255, 0}16 red := color.RGBA{255, 0, 0, 0}17 white := color.RGBA{255, 255, 255, 0}18 classifier := gocv.NewCascadeClassifier()19 defer classifier.Close()20 if !classifier.Load("data/haarcascade_frontalface_default.xml") {21 fmt.Println("Error reading cascade file: data/haarcascade_frontalface_default.xml")22 }23 window := gocv.NewWindow("Face Detect")24 defer window.Close()25 window2 := gocv.NewWindow("Face Detect")26 defer window2.Close()27 fmt.Printf("Start reading device: %v\n", 0)28 for {29 if ok := webcam.Read(&img); !ok {30 fmt.Printf("Device closed: %v\n", 0)31 }32 if img.Empty() {33 }34 rects := classifier.DetectMultiScale(img)35 fmt.Printf("found %d faces\n", len(rects))
AnchorsPersistTemporarily
Using AI Code Generation
1import (2func main() {3 db, err := sqlx.Connect("sqlite3", "./foo.db")4 if err != nil {5 fmt.Println(err)6 }7 db.MustExec(`CREATE TABLE IF NOT EXISTS foo (8 db.MustExec(`INSERT INTO foo (name) VALUES ($1)`, "Bar")9 err = db.Get(&name, `SELECT name FROM foo WHERE id = ?`, 1)10}11import (12func main() {13 db, err := sqlx.Connect("sqlite3", "./foo.db")14 if err != nil {15 fmt.Println(err)16 }17 db.MustExec(`CREATE TABLE IF NOT EXISTS foo (18 db.MustExec(`INSERT INTO foo (name) VALUES ($1)`, "Bar")19 err = db.Get(&name, `SELECT name FROM foo WHERE id = ?`, 1)20}21import (22func main() {23 db, err := sqlx.Connect("sqlite3", "./foo.db")24 if err != nil {25 fmt.Println(err)26 }27 db.MustExec(`CREATE TABLE IF NOT EXISTS foo (
AnchorsPersistTemporarily
Using AI Code Generation
1import (2func main() {3 td := time.Date(2020, 2, 3, 0, 0, 0, 0, time.UTC)4 fmt.Println(td)5 fmt.Println(td.AddDate(0, 0, 1))6 fmt.Println(td.AddDate(0, 0, -1))7}8import (9func main() {10 td := time.Date(2020, 2, 3, 0, 0, 0, 0, time.UTC)11 fmt.Println(td)12 fmt.Println(td.AddDate(0, 0, 1))13 fmt.Println(td.AddDate(0, 0, -1))14}15import (16func main() {17 td := time.Date(2020, 2, 3, 0, 0, 0, 0, time.UTC)18 fmt.Println(td)19 fmt.Println(td.Add(24 * time.Hour))20 fmt.Println(td.Add(-24 * time.Hour))21}22import (23func main() {24 td := time.Date(2020, 2, 3, 0, 0, 0, 0, time.UTC)25 fmt.Println(td)26 fmt.Println(td.After(time.Now()))27}28import (29func main() {30 td := time.Date(2020, 2, 3, 0, 0, 0, 0, time.UTC)31 fmt.Println(td)32 fmt.Println(td.Before(time.Now()))33}34import (35func main() {36 td := time.Date(2020, 2, 3, 0, 0, 0, 0, time.UTC)37 fmt.Println(td)38 fmt.Println(td.Equal(time.Now()))39}
AnchorsPersistTemporarily
Using AI Code Generation
1import (2func main() {3 xlFile, err := xlsx.OpenFile(excelFileName)4 if err != nil {5 fmt.Println(err)6 }7 err = xlFile.Save(excelFileName)8 if err != nil {9 fmt.Println(err)10 }11}
AnchorsPersistTemporarily
Using AI Code Generation
1import (2var (3func main() {4 img := image.NewRGBA(image.Rect(0, 0, width, height))5 draw.Draw(img, img.Bounds(), &image.Uniform{color.RGBA{0, 0, 0, 255}}, image.ZP, draw.Src)6 file, err := os.Create("image.png")7 if err != nil {8 log.Fatal(err)9 }10 defer file.Close()11 rand.Seed(time.Now().UnixNano())12 anchors := []image.Point{13 image.Point{0, 0},14 image.Point{width, 0},15 image.Point{width, height},16 image.Point{0, height},17 }18 initialPoint := image.Point{0, 0}19 AnchorsPersistTemporarily(img, anchors, initialPoint, iterations)20 err = png.Encode(file, img)21 if err != nil {22 log.Fatal(err)23 }24}25func AnchorsPersistTemporarily(img draw.Image, anchors []image.Point, initialPoint image.Point, iterations int) {26 color := color.RGBA{255, 255, 255, 255}27 for i := 0; i < iterations; i++ {28 r := rand.Intn(4)29 newPoint := image.Pt((currentPoint.X+anchors[r].X)/2, (currentPoint.Y+anchors[r].Y)/2)
AnchorsPersistTemporarily
Using AI Code Generation
1import (2func main() {3 file, err := xlsx.OpenFile("test.xlsx")4 if err != nil {5 fmt.Println(err)6 }7 cell := sheet.Cell(0, 0)8 anchor := cell.GetAnchor("A1")9 err = file.Save("test.xlsx")10 if err != nil {11 fmt.Println(err)12 }13}14import (15func main() {16 file, err := xlsx.OpenFile("test.xlsx")17 if err != nil {18 fmt.Println(err)19 }20 cell := sheet.Cell(0, 0)21 anchor := cell.GetAnchor("A1")22 anchor.ColOff = xlsx.ColOff(10000)23 err = file.Save("test.xlsx")24 if err != nil {25 fmt.Println(err)26 }27}28import (29func main() {30 file, err := xlsx.OpenFile("test.xlsx")31 if err != nil {32 fmt.Println(err)33 }34 cell := sheet.Cell(0, 0)35 anchor := cell.GetAnchor("A1")36 anchor.ColOff = xlsx.ColOff(10000)37 err = file.Save("test.xlsx")38 if err != nil {39 fmt.Println(err)40 }41}
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!!