1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
// SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net>
// SPDX-License-Identifier: Apache-2.0
package assert_test
import (
"errors"
"fmt"
"os"
"regexp"
"testing"
"go.xyrillian.de/gg/assert"
"go.xyrillian.de/gg/testcapture"
)
func TestErrEqual(t *testing.T) {
noError := error(nil)
fooError := errors.New("foo error")
barError := errors.New("bar error")
nestedFooError := fmt.Errorf("nested error: %w", fooError)
// test matching against nil
assert.ErrEqual(t, noError, nil)
assert.ErrEqual(t, noError, (*os.PathError)(nil))
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, fooError, nil)
}, `expected no error, but got "foo error"`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, fooError, (*os.PathError)(nil))
}, `expected no error, but got "foo error"`)
// test matching against error
assert.ErrEqual(t, fooError, fooError)
assert.ErrEqual(t, nestedFooError, fooError)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, fooError, nestedFooError) // error nesting does not work the other way, we need to see the full `expected`error in`actual`
}, `expected "nested error: foo error", but got "foo error"`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, barError, fooError) // check with unrelated errors for completeness
}, `expected "foo error", but got "bar error"`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, nil, fooError)
}, `expected "foo error", but got no error`)
// test matching against string
assert.ErrEqual(t, fooError, "foo error")
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, nestedFooError, "foo error") // partial matches do not work
}, `expected "foo error", but got "nested error: foo error"`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, barError, "foo error") // check with unrelated errors for completeness
}, `expected "foo error", but got "bar error"`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, nil, "foo error")
}, `expected "foo error", but got no error`)
// test matching against regexp
fooRegexp := regexp.MustCompile(`foo`)
assert.ErrEqual(t, fooError, fooRegexp) // partial matches allowed here as long as regexp does not use ^ and $
assert.ErrEqual(t, nestedFooError, fooRegexp)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, barError, fooRegexp) // check with unrelated errors for completeness
}, `expected an error matching /foo/, but got "bar error"`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, nil, fooRegexp)
}, `expected an error matching /foo/, but got no error`)
// test matching against unexpected type
result := testcapture.Capture(t.Context(), t.Name(), func(t assert.TestingTB) {
assert.ErrEqual(t, errors.New("42"), 42)
})
assert.Equal(t, result, testcapture.Result{
Outcome: testcapture.OutcomePanicked,
Panic: "cannot handle `expected` of type int",
})
// an earlier version had a bug because this call caused reflect.Value.IsNil() to be called on a value of kind Struct
expectErrors(t, func(t assert.TestingTB) {
assert.ErrEqual(t, nil, structTypedError{"foo"})
}, `expected "foo", but got no error`)
}
type structTypedError struct {
Message string
}
// Error implements the builtin/error interface.
func (e structTypedError) Error() string {
return e.Message
}
func TestErrsEqual(t *testing.T) {
// NOTE: ErrsEqual() uses the same basic machinery as ErrEqual(), so we're not comparing all types here.
// We just need to check the machinery of iterating over `actual` and `expected` and dealing with slice length mismatches.
errs := []error{
errors.New("first error"),
errors.New("second error"),
}
assert.ErrsEqual(t, errs, []string{"first error", "second error"})
expectErrors(t, func(t assert.TestingTB) {
assert.ErrsEqual(t, errs, []string{"second error", "first error"})
}, `
in actual[0]: expected "second error", but got "first error"
in actual[1]: expected "first error", but got "second error"
`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrsEqual(t, errs, []string{"first error"})
}, `in actual[1]: expected <missing>, but got "second error"`)
expectErrors(t, func(t assert.TestingTB) {
assert.ErrsEqual(t, errs, []string{"first error", "second error", "third error"})
}, `in actual[2]: expected "third error", but got <missing>`)
}
|