Releases · maxatome/go-testdeep
v1.15.0
Features
- go-testdeep is now dependency-free!
- add
Listoperator to compare an array or a slice in strict order (can be seen as a lighter alternative toArrayandSlice):td.Cmp(t, []int{1, 9, 5}, td.List(1, 9, 5)) // works with slices/arrays of any type td.Cmp(t, personSlice, td.List( Person{Name: "Bob", Age: 32}, Person{Name: "Alice", Age: 26}, ))
- add
Sortoperator to sort an array or slice before comparing its content (can be seen as an alternative toBag):td.Cmp(intSlice, td.Sort(-1, []int{4, 5, 9, 10})) // check intSlice content after sorting it in descending order // the key(s) on which the sorting applies can be quite complex type A struct{ props map[string]int } p12 := A{props: map[string]int{"priority": 12}} p23 := A{props: map[string]int{"priority": 23}} p34 := A{props: map[string]int{"priority": 34}} got := []A{p23, p12, p34} td.Cmp(t, got, td.Sort("-props[priority]", []A{p34, p23, p12})) // can be used inside JSON operator got := map[string][]string{"labels": {"c", "a", "b"}} td.Cmp(t, got, td.JSON(`{ "labels": Sort(1, ["a", "b", "c"]) }`)) // or more complex td.Cmp(t, got, td.JSON(`{ "people": Sort([ "-age", "name" ], [ // sort by age desc, then by name asc {"name": "Marcel", "age": 25}, {"name": "Brian", "age": 22}, {"name": "Alice", "age": 20}, {"name": "Bob", "age": 19}, {"name": "Stephen", "age": 19}, ]) }`))
- add
Sortedoperator to check an array or slice is sorted, examples:td.Cmp(t, aSlice, td.Sorted()) // checks aSlice is sorted in ascending order td.Cmp(t, aStructSlice, td.Sorted("-FieldName")) // checks aStructSlice is sorted in descending order // can be used inside JSON operator got := map[string][]string{"labels": {"a", "b", "c"}} td.Cmp(t, got, td.JSON(`{ "labels": Sorted }`))
- new
Must,Must2&Must3functions allowing to do:// before val, err := myfunction() td.Require(t).CmpNoError(err) // now val := td.Must(myfunction())
Smugglefields-path can now contains method calls, allowing to dotd.Smuggle("A.B.C.MethodName().D.E", expected)for example, and referencemap[string]...using.keyinstead of[key]before;Map,SubMapOf,SuperMapOf,Array,Slice&SuperSliceOfexpectedEntriesparameter is now optional or multiple;Flattennow acceptsfunc(T, X...) V|(V, bool)function signatures as well as an int to produce an int range;- regexp or shell pattern fields of
Struct&SStructnow appear clearly in failure report; tdhttp.TestAPI: addClone,DefaultRequestParams&AddDefaultRequestParamsmethods;tdhttp.TestAPInow setsHostfield;tdhttp.NewRequestand all other functions +tdhttp.TestAPImethods building HTTP requests also accept hook asfunc(*http.Request) error;tdhttp.TestAPI: addDefaultHeader&DefaultHookmethods to define header values & automatically called hook for each future requests sent bytdhttp.TestAPI;- add
tdsynctesthelper package, a simple wrapper aroundtesting/synctestpowered by go-testdeep; - new
tdutil.CmpValuesFuncfunction is able to sort[]reflect.Valueslices thanks toslices.SortFunc; tdutil.SortableValuesnow usesT.Compare(T) intmethod when it is available.
Fixes
- operators errors are no longer hidden when used inside another operator;
tdutilinternal tests for go1.25 was broken;Grep,Last&FirstString()method now shows the expected value;- in some cases, tests continued after a failure instead of stopping immediately;
Grep: if got is a specific named slice type, then expect this type .
What's Changed in details
- docs(README): v1.14.0 release announce by @maxatome in #254
- docs(ErrorIs): fix typo by @maxatome in #255
- docs: fix typos by @maxatome in #256
- Add tdhttp.TestAPI's DefaultRequestParams & AddDefaultRequestParams by @maxatome in #258
- feat(tdhttp): add testAPI.Clone feature by @c-roussel in #259
- Switch CI to go 1.22 & golangci-lint 1.55.2 by @maxatome in #260
- feat(tdhttp): request creation methods/functions init Host field by @maxatome in #261
- fix: smuggle hooks can return interface, as the doc always said by @maxatome in #262
- Delay type checks by @maxatome in #264
- feat(tdhttp): request creation accepts hooks by @maxatome in #263
- feat(Smuggle): fields-path param can contain method calls by @maxatome in #265
- chore: switch CI to go 1.23 & golangci-lint 1.60.1 by @maxatome in #266
- chore: switch CI to go 1.24 & golangci-lint 2.0.2 by @maxatome in #268
- docs: fix typo by @maxatome in #270
- fix: operators errors are no longer hidden when used inside another operator by @maxatome in #271
- test: add td.Smuggle tests by @maxatome in #272
- Prepare the ground for upcoming Sort & Sorted operators by @maxatome in #273
- Add Sort & Sorted operators by @maxatome in #267
- feat(tdutil): add new function CmpValuesFunc for slices.SortFunc by @maxatome in #274
- Support go1.25 by @maxatome in #275
- docs: add references to Sort & Sorted by @maxatome in #276
- Import go spew by @maxatome in #277
- chore: tools/gen_funcs.pl computes go lines by @maxatome in #278
- docs: add cross references by @maxatome in #280
- feat: add tdsynctest helper, a wrapper around testing/synctest by @maxatome in #281
- feat: add List operator by @maxatome in #282
- feat(Flatten): allow func(T, X...) V|(V, bool) function signatures by @maxatome in #284
- add location unit tests by @plutov in #285
- feat(Flatten): Flatten accepts an int to produce an int range by @maxatome in #286
- Some features before the release by @maxatome in #287
New Contributors
Full Changelog: v1.14.0...v1.15.0
v1.14.0
Features
ErrorIsbecomes a smuggler operator usingerrors.Asbehind the scene;StructandSStructintroduce lazy-model feature, i.e. the model is guessed at run-time.
Fixes
- in error reports, the origin operator was sometimes missing and sometimes wrong when using
JSON,SubJSONOfandSuperJSONOfoperators; - fix
JSON,SubJSONOfandSuperJSONOfpanic when using a bad placeholder several times in the same operator.
What's Changed in details
- test: fix empty GOPROXY when testing with tip by @maxatome in #240
- fix(JSON): errors with wrong origin operator by @maxatome in #239
- ci: add workflow_dispatch as event trigger by @maxatome in #241
- feat(ErrorIs): becomes a smuggler operator with errors.As feature by @maxatome in #242
- refactor: make golangci-lint v1.52.2 happy by @maxatome in #243
- ci: switch to install-go v3.4 by @maxatome in #244
- Minor fixes by @maxatome in #246
- feat(Struct): introduce lazy-Struct & lazy-SStruct by @maxatome in #247
- test: use go 1.21 & golangci-lint 1.54.1 in CI by @maxatome in #248
- Correct spelling least by @aktasfatih in #249
- docs: clarify panic(nil) case since go 1.21 introduced a change by @maxatome in #250
- Fix json panic by @maxatome in #251
- fix(tdsuite): verbose tests raised an error by @maxatome in #253
New Contributors
- @aktasfatih made their first contribution in #249
Full Changelog: v1.13.0...v1.14.0
v1.13.0
Features
- New operators:
ErrorIsto check the data is an error and matches a wrapped error (useserrors.Isbehind the scene),Firstto find the first matching item of a slice or an array then compare its content,Grepto reduce a slice or an array before comparing its content,Lastto find the last matching item of a slice or an array then compare its content,Recvto read from a channel and test value;
- rework of
JSONparsing:- introduction of raw strings,
- literal
\n,\r&\taccepted in strings, $^Operator(params...)is possible,"$^Operator(params...)"is possible,Operator(without parenthesis) is possible,- accepts
json.RawMessage;
- anchoring is now possible using
td.Aandtd.Anchor, the generic versions oftd.T.Aandtd.T.Anchor; td.Flattennow accepts an optional function to filter and/or transform the items before flattening them;*td.TgainsAssertandRequiremethods, to be consistent with existingtd.Assertandtd.Require;- introduce
td.Sfunction, to produce strings without needingfmt, shorter to write and following the same calling convention as test names (in other words auto-detectingPrintflike format); - new
TestDeepInGotOKconfig to allow to test go-testdeep operators (is forbidden by default, but useful when go-testdeep is used outside golang tests) includingtd.T.TestDeepInGotOKmethod; tdhttppackage:tdhttp.TestAPIcan now test HTTP responses as a whole (CmpResponse) as well as HTTP trailer (CmpTrailer),tdhttp.PostFormandtdhttp.TestAPI.PostFormnow also accepttdhttp.Qas data.
As usual: enjoy! :)
What's changed in details
- docs(README): v1.12.0 release announce by @maxatome in #212
- fix(doc,tdhttp): typo by @Linkid in #213
- Some refactoring by @maxatome in #214
- docs: fix typo by @maxatome in #215
- Grep, First & Last operators by @maxatome in #216
- refactor: go1.16 required now, so drop support for go1.9 to go1.15 by @maxatome in #221
- feat: add ErrorIs operator by @maxatome in #220
- fix(Recv): timeout can mask expected value by @maxatome in #222
- feat(tdhttp): add TestAPI's CmpResponse & CmpTrailer by @maxatome in #219
- feat: replacing bytes.Buffer instances used only to generate strings with strings.Builder. by @ellisonleao in #224
- feat(JSON): operators possible in JSON strings by @maxatome in #217
- refactor: Replace(a, b, -1) → ReplaceAll(a, b) by @maxatome in #226
- feat: go1.20 introduces slice to array convertibility by @maxatome in #227
- feat(tdhttp): allow usage of tdhttp.Q when using PostForm helpers by @c-roussel in #228
- fix(internal/json): avoid data race by @maxatome in #229
- feat: add TestDeepInGotOK allowing to test td.TestDeep operators by @maxatome in #230
- feat(internal): add (*ctxerr.Error).ErrorWithoutColors method by @maxatome in #231
- feat: add generic functions td.Anchor and td.A, another way to anchor by @maxatome in #232
- ci: test with go1.20 by @maxatome in #233
- style: remove useless comment by @maxatome in #234
- docs: fix README typo by @maxatome in #235
- feat(JSON): accept json.RawMessage as input by @deathiop in #237
- Flatten++ by @maxatome in #236
- chore: cosmetic changes before the release by @maxatome in #238
Full Changelog: v1.12.0...v1.13.0
v1.12.0
New features
Struct&SStructcan override model fields in expectedFields, as in:td.Cmp(t, got, td.Struct( Person{ Name: "John Doe", Age: 23, Children: 4, }, td.StructFields{ "> Age": td.Between(40, 45), ">Children": 0, // spaces after ">" are optional }), )
Struct&SStructexpectedFields is now optional or multiple. If multiple, all maps are merged from left to right;- try to detect wrongly defined hooks in
tdsuite@deathiop
Given the 5 hooks: - try to detect possible
tdsuite.Run()misuse, warn the user when it is called with a non-pointer suite, and some key methods are only available via a pointer suite; - add
tdhttp.Optionsfunction &tdhttp.TestAPI.Optionsmethod; Codecan now officially delegate its comparison, using two new kinds of function:func(t *td.T, arg)func(assert, require *td.T, arg)
this way the usage of*td.Tmethods is secure. Note that these functions do not return anything;
- using a
*td.Tinstance asCmp*first parameter now allows to inherit its configuration.is the same as:td.Cmp(td.Require(t), got, 42)
td.Require(t).Cmp(got, 42)
Fixes
Helper()was not called inT.LogTrace,T.ErrorTraceandT.FatalTracemethods. Fixed;UseEqual& anchoring feature didn't play well together. Fixed;- panic when comparing nested maps using private fields as key. Fixed.
Miscellaneous
- enhance & refactor doc comments with new go 1.19 features;
- documentation now uses
anyinstead ofinterface{}; - fix typos.
As usual: enjoy! :)
v1.11.0
New features
JSON,SubJSONOfandSuperJSONOfoperators:- Now:
act the same way. Since v1.10.1 rework, the second was not working as expected.
td.JSON(`{"foo": $1}`, td.Between(12, 34)) td.JSON(`{"foo": Between($1, $2)}`, 12, 34)
At the same time:now works as expected. It was rejected before,td.JSON(`{"foo": Between(12, 34, $1)}`, td.BoundsOutIn)
int_lit&float_litnumbers, as defined in go specification, are now accepted in JSON, allowing, for example, to embed hexadecimal numbers in expected JSON;
- Now:
Betweenoperator acceptstime.DurationasTOwhenFROMis atime.Time;Between,Gt,Gte,LtandLteoperators:- now handle values implementing
CompareorLessmethods:
Compareand/orLessmethods signatures follow:for example, the new go1.18func (a T) Less(b T) bool // returns true if a < b func (a T) Compare(b T) int // returns -1 if a < b, 1 if a > b, 0 if a == b
net/netip.Addrimplements both, - failure reports display numbers as elsewhere,
- some docs have been fixed;
- now handle values implementing
Smugglecan now cast values, allowing such things:// A string containing JSON got := `{ "foo": 123 }` td.Cmp(t, got, td.Smuggle(json.RawMessage{}, td.JSON(`{"foo":123}`)) // or td.Cmp(t, got, td.Smuggle((json.RawMessage)(nil), td.JSON(`{"foo":123}`))
- in report failures, the stack trace was displayed if it contained at least 2 levels. Now it is also displayed if it contains one level BUT the source file path contains a directory. It helps to localize quickly the errors in large repositories;
td.Tgains 3 new methods to log with a stack trace:LogTrace,ErrorTraceandFatalTrace;- handle go1.17
[]T→*[n]Tconvertibility edge case; - in failure reports
(float64)type is now omitted (like(int)and(bool)already were), but the value always contains a "." (except if±Inf,NaNor with exponent) to distinguish them fromint.
Fixes
Contains: slice in slice search didn't work at end of slice;JSON,SubJSONOfandSuperJSONOfoperators panicked when usingAll+JSON-operator+embeddedOp+$1;- anchoring 2 slices at the same time didn't work.
Miscellaneous
- CI build:
- now uses
install-go.plv3.0, sotiptest is very fast most of the time, - golangci-lint upgraded to v1.43.0,
- uses bidichk linter;
- now uses
//go:buildline added when// +buildwas already present, since go1.17 changes;//nolint:pragmas uniformized.
And happy new year!
v1.10.1
Fixes:
LenandCapcould not be embedded inJSON,SubJSONOfandSuperJSONOf. Fixed;BagandSetdidn't implementTypeBehind()method. Fixed;JSONPointerexpectedValue andJSONplaceholders didn't have the same behavior. Now the pointed data is JSON-unmarshaled into a value using the same type of expectedValue (forJSONPointer) or any placeholder (forJSON) before comparison;CatchTypeBehind()method didn't use the type of target when the type behind expectedValue could not be determined. Fixed;(*tdhttp.TestApi).CmpJSONBody(nil)panicked. Fixed;- and some typos fixed.
Enjoy!
v1.10.0
New features:
- add
SuperSliceOfoperator, to compare only parts of slices/arrays; - JSON parser of
JSON,SubJSONOfandSuperJSONOfis now more lax:are allowed (comma just before "}" or "]" for non-empty {…} and […]);{"foo": "bar",} [ 1, 2, 3, ] Smugglefields-path param can now dereference maps, arrays & slices:Contrary totd.Smuggle("Group.Persons[3].Age", td.Between(23, 32))JSONPointeroperator, private fields can be followed;Struct&SStructnow understand shell patterns & regexps to match struct fields;- add
IgnoreUnexportedfeature and reworkUseEqual: they both can now be scoped to some types.Struct&SStructcomply with the newIgnoreUnexported; - add
(*td.T).Parallel()method (@abhinav); - do not panic on operator misuses anymore, but raise an error on operator use. So it is easier to understand;
- introduce
nocolorhelper to easily disable coloring output of failure reports, typically useful in golang playground; tdhttppackage:- introduce multipart requests as defined in RFC 2046, see
(*tdhttp.TestAPI).PostMultipartFormData(),tdhttp.PostMultipartFormData()andtdhttp.MultipartBodytype; - headers handle
http.Cookieout-of-the-box, seetdhttp.NewRequest()documentation for details; - new
tdhttp.BasicAuthHeader()function allows to easily inject Basic Authorization header; - add
(*tdhttp.TestAPI).CmpCookies()to easily compare cookies content (@Julien2313); - add
tdhttp.Qtype to easily declare query parameters in requests, seetdhttp.NewRequest()documentation for details. Note thaturl.Valuestype is now supported as well.
- introduce multipart requests as defined in RFC 2046, see
Fixes:
- multi-lines colored text → color-off \n color-on for each line (@siadat);
JSONTypeBehind()method is now delegated when an operator is at the root of the JSON;tdhttppackage:- chaining of
Cmp*methods can lead to skewFailed()result.
- chaining of
Enjoy!
v1.9.2
Fixes:
- deeply nested operators in
JSONparams was json.Marshal()led. It is now detected and avoided; - a specific error message is provided to the user when he tries to wrongly use
td.JSON()as body in(*tdhttp.TestAPI).XxxJSON()calls; - in
tdsuite,Cleanup()was sometimes incorrectly called inPreTest/PostTesthooks.
v1.9.1
Fixes:
- traces displayed when a
Cmpfailure occurs, are now properly stripped to ignoretesting,td,tdhttpandtdsuiteinternal calls; - JSON unmarshal bug when
\uxxxxis first escaping sequence in a string.
v1.9.0
New features:
- introducing new
tdsuitehelper, allowing to easily create testing suites, fully integrated with go-testdeep; JSON,SubJSONOfandSuperJSONOfnow accept almost all operators embedded directly in JSON thanks to our new custom JSON decoder:td.Cmp(t, got, td.JSON(`{"name": HasPrefix("Bob"), "age": Between(20, 25)}`), )
ReandReAllcapture parameter can now be a[]interface{}(only[]stringuntil now);Flattenis now able to flatten maps, can be useful when creating request usingtdhttppackage;- when a
Cmpfailure occurs outside the root of a test function, a trace of all successive function calls is displayed to help the user to understand/locate the error; - in
tdhttphelper (aka the ultimate HTTP API tester),tdhttp.TestAPIgains several methods:AutoDumpResponseallows to dump the HTTP response when the first error is encountered after a request,OrDumpResponsedumps the response if at least one previous test failed,Runruns a subtest,Treturns the internal instance of*td.T,Withcreates a new*TestAPIinstance.
Fixes:
reflect.Interfacecontainingnilcould produce wrong comparisons.
Enjoy!