aboutsummaryrefslogtreecommitdiff
path: root/assert/errequal.go
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2026-06-18 23:23:36 +0200
committerStefan Majewsky <majewsky@gmx.net>2026-06-19 20:16:11 +0200
commit71d31d73e7dc3b9cdb3c53b4f343b1928a9e858b (patch)
treee1cd6d01837ef6ef07504ba3893c6f5e55f8740b /assert/errequal.go
parentb95ec7449ebec844221f80ecbf7976f3af878eee (diff)
downloadgo-gg-71d31d73e7dc3b9cdb3c53b4f343b1928a9e858b.tar.gz
add package testcapture, package assert (minimal implementation)
Diffstat (limited to 'assert/errequal.go')
-rw-r--r--assert/errequal.go72
1 files changed, 72 insertions, 0 deletions
diff --git a/assert/errequal.go b/assert/errequal.go
new file mode 100644
index 0000000..4752f26
--- /dev/null
+++ b/assert/errequal.go
@@ -0,0 +1,72 @@
+// SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net>
+// SPDX-License-Identifier: Apache-2.0
+
+package assert
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "regexp"
+)
+
+// ErrEqual checks if the actual error matches the expectation.
+// - If expected is nil, the actual error must be nil.
+// - If expected is of type error, the actual error must be exactly equal to it or contain it, as reported by the [errors.Is] function.
+// - If expected is of type string, the actual error must have a message exactly equal to it.
+// - If expected is of type [*regexp.Regexp], the actual error must have a message matching that regexp.
+// - If expected is of any other type, ErrEqual will panic.
+func ErrEqual(t TestingTB, actual error, expected any) bool {
+ // coerce all types that implement `error` into the interface type `error`,
+ // and also coerce all nil values of concrete `error` types into untyped nil
+ if expectedErr, ok := expected.(error); ok {
+ // convert nil values of concrete error types into a generic nil value
+ if reflect.ValueOf(expectedErr).IsNil() {
+ expected = nil
+ } else {
+ expected = expectedErr
+ }
+ }
+
+ switch expected := expected.(type) {
+ case nil:
+ if actual == nil {
+ return true
+ } else {
+ t.Errorf("expected no error, but got %q", actual.Error())
+ return false
+ }
+ case error:
+ if actual == nil {
+ t.Errorf("expected %q, but got no error", expected.Error())
+ return false
+ } else if errors.Is(actual, expected) {
+ return true
+ } else {
+ t.Errorf("expected %q, but got %q", expected.Error(), actual.Error())
+ return false
+ }
+ case string:
+ if actual == nil {
+ t.Errorf("expected %q, but got no error", expected)
+ return false
+ } else if actual.Error() == expected {
+ return true
+ } else {
+ t.Errorf("expected %q, but got %q", expected, actual.Error())
+ return false
+ }
+ case *regexp.Regexp:
+ if actual == nil {
+ t.Errorf("expected an error matching /%s/, but got no error", expected.String())
+ return false
+ } else if expected.MatchString(actual.Error()) {
+ return true
+ } else {
+ t.Errorf("expected an error matching /%s/, but got %q", expected.String(), actual.Error())
+ return false
+ }
+ default:
+ panic(fmt.Sprintf("cannot handle `expected` of type %T", expected))
+ }
+}