aboutsummaryrefslogtreecommitdiff
path: root/assert/equal.go
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2026-06-22 11:37:02 +0200
committerStefan Majewsky <majewsky@gmx.net>2026-06-22 11:38:31 +0200
commit8804729561d8e5edd7179f494d89c620459d319f (patch)
treea6d2979a13c04dff42c3d9874c171531dd30b081 /assert/equal.go
parent99fd6c3185e810eb8b18c5f3fe582a3e91463608 (diff)
downloadgo-gg-8804729561d8e5edd7179f494d89c620459d319f.tar.gz
assert: represent string literals with backticks when appropriate
Diffstat (limited to 'assert/equal.go')
-rw-r--r--assert/equal.go35
1 files changed, 24 insertions, 11 deletions
diff --git a/assert/equal.go b/assert/equal.go
index 2cafb44..1c8004c 100644
--- a/assert/equal.go
+++ b/assert/equal.go
@@ -8,6 +8,7 @@ import (
"reflect"
"slices"
"strings"
+ "unicode"
"unicode/utf8"
"go.xyrillian.de/gg/internal/path"
@@ -76,6 +77,18 @@ func formatValue(v reflect.Value) string {
return fmt.Sprintf("%#v", v)
}
+func formatString(str string) string {
+ if strings.ContainsRune(str, '"') && !strings.ContainsRune(str, '`') && !strings.ContainsFunc(str, isControlCharacter) {
+ return fmt.Sprintf("`%s`", str)
+ } else {
+ return fmt.Sprintf("%q", str)
+ }
+}
+
+func isControlCharacter(r rune) bool {
+ return unicode.Is(unicode.C, r)
+}
+
func findInequalities(p path.Path, actual, expected reflect.Value) (result []inequality) {
// try to recurse into structured type to find the specific location of the inequality
// (thus producing a more succinct error message esp. with large and deeply nested structures)
@@ -98,6 +111,15 @@ func findInequalities(p path.Path, actual, expected reflect.Value) (result []ine
result = findInequalities(subpath, actualElem, expectedElem)
}
}
+ case reflect.String:
+ // string types do not allow structured recursion, but they have a special case for formatting
+ actualStr := actual.Convert(reflect.TypeFor[string]()).Interface().(string)
+ expectedStr := expected.Convert(reflect.TypeFor[string]()).Interface().(string)
+ return []inequality{{
+ Pointer: p.AsGoExpression("actual"),
+ Actual: formatString(actualStr),
+ Expected: formatString(expectedStr),
+ }}
}
// if we do not have a recursion method for the type in question,
@@ -118,8 +140,8 @@ func findInequalitiesInArrayOrSlice(p path.Path, actual, expected reflect.Value)
if utf8.Valid(actualPayload) && utf8.Valid(expectedPayload) {
return []inequality{{
Pointer: p.AsGoExpression("actual"),
- Actual: formatByteSliceViaString(actualPayload),
- Expected: formatByteSliceViaString(expectedPayload),
+ Actual: fmt.Sprintf(`[]byte(%s)`, formatString(string(actualPayload))),
+ Expected: fmt.Sprintf(`[]byte(%s)`, formatString(string(expectedPayload))),
}}
}
}
@@ -166,15 +188,6 @@ func findInequalitiesInArrayOrSlice(p path.Path, actual, expected reflect.Value)
return result
}
-func formatByteSliceViaString(buf []byte) string {
- str := string(buf)
- if strings.Contains(str, `"`) && !strings.Contains(str, "`") {
- return fmt.Sprintf("[]byte(`%s`)", str)
- } else {
- return fmt.Sprintf("[]byte(%q)", str)
- }
-}
-
func buildSingleInequalityForArrayOrSlice(p path.Path, actual, expected reflect.Value) inequality {
// This is a helper for findInequalitiesInArrayOrSlice() that reports only a single inequality for the entire thing.
// But it still tries to be clever, and will omit the longest common prefix and suffix to shorten the output.