Comments (5)
\cc @gnahckire @shurcooL (from #24)
from go-cmp.
@dsnet What you've described sounds quite positive and has nice properties.
I just want to point out, at least with the example given, I don't see why cmp
itself is needed to achieve that functionality. The code above is very readable, but to write it from scratch, you have to know in advance that CheckError
relates to EquateErrors()
. Without the latter, CheckError
won't do the right thing.
I could see the code above simplified to just:
type CheckError func(error) bool
func Test(t *testing.T) {
// nonNilError equates any non-nil error.
// This is usual for just checking that the result failed, but not how it failed.
nonNilError := CheckError(func(error) bool {
return true
})
// notExistError equates any error based on a function predicate.
notExistError := CheckError(os.IsNotExist)
// timeoutError equates any error that is a timeout error.
timeoutError := CheckError(func(e error) bool {
ne, ok := e.(net.Error)
return ok && ne.Timeout()
})
// containsEOF equates any error with EOF in the string.
// NOTE: string matching on error messages is heavily frowned upon.
containsEOF := CheckError(func(e error) bool {
return strings.Contains(e.Error(), "EOF")
})
tests := []struct {
err error
check CheckError
want bool
}{
{io.EOF, nonNilError, true},
{nil, nonNilError, false},
{io.EOF, notExistError, false},
{os.ErrNotExist, notExistError, true},
{os.ErrPermission, notExistError, false},
{io.EOF, timeoutError, false},
{&net.AddrError{}, timeoutError, false},
{syscall.ETIMEDOUT, timeoutError, true},
{io.EOF, containsEOF, true},
{io.ErrUnexpectedEOF, containsEOF, true},
{&net.ParseError{}, containsEOF, false},
}
for _, tt := range tests {
got := tt.check(tt.err)
if got != tt.want {
t.Errorf("check(%v) = %v, want %v", tt.err, got, tt.want)
}
}
}
Perhaps the mechanism you've described is useful when deep nested structs are being compared with cmp.Equal
, and one wants to compare errors in that context. But for the simple case of checking errors, it feels like using cmp
is not justified.
I hope this feedback is helpful, let me know if not. I might be missing some context.
from go-cmp.
Instead of an EquateErrors
function, can we have a general facility for smart comparisons of interface values?
- When comparing values
a
andb
- If
a
orb
has aCmpEqual(x T) bool
method - Where
b
ora
is assignable toT
- The comparison succeeds if
CmpEqual
returnstrue
.
Now CheckError
is:
type CheckError func(err error) bool
func (c CheckError) Error() string {
return fmt.Sprintf("%#v", c)
}
func (c CheckError) CmpEqual(err error) bool {
return c(err)
}
This general approach can then be applied to other cases where we may want to embed comparison information in the object being compared.
from go-cmp.
On hold for golang/go#29934
Presumably we would add:
func EquateErrors() cmp.Option {
return cmp.Comparerer(func (x, y error) bool {
return errors.Is(x, y) || errors.Is(y, x)
})
}
from go-cmp.
@dsnet is this still on hold?
Wasn't errors.Is
in the most recent Go release? Looks like it is part of errors
now
I wouldn't mind picking this one up.
from go-cmp.
Related Issues (20)
- Diff is extremely slow HOT 3
- How to ignore specific field by name? HOT 1
- Ideas for a v2 HOT 3
- Default support for the `netip` package HOT 1
- New minor release of the library? HOT 4
- cmp.Diff() switching from property diffs to "new object" diff when object changes significantly HOT 1
- Inconsistent whitespace produced by cmp.Diff HOT 2
- cmpopts: add EquateUnsetFields(want) or FilterFieldsFrom(want) HOT 1
- IgnoreFields and nested struct HOT 2
- Enable a dependency update tool HOT 2
- Package Name Mismatches HOT 4
- unhelpful output for difference in slices HOT 1
- How to implement jests.js's `expect.any(String)` like functionality? HOT 1
- cmpopts.IgnoreFields does not work on structs with an Equal method HOT 1
- Performance Issue Comparing Array Types HOT 1
- Naming clash for new cmp standard package HOT 4
- Comparing two fields with diffirent types that are semantically equivalent HOT 3
- String diff for UUIDs can use strings.Join syntax which makes it more confusing HOT 4
- Reporter truncating important context on diff output but leaving others alone
- How to add more context to Diff output?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go-cmp.