aboutsummaryrefslogtreecommitdiff
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
parent99fd6c3185e810eb8b18c5f3fe582a3e91463608 (diff)
downloadgo-gg-8804729561d8e5edd7179f494d89c620459d319f.tar.gz
assert: represent string literals with backticks when appropriate
-rw-r--r--CHANGELOG.md6
-rw-r--r--assert/equal.go35
-rw-r--r--assert/equal_test.go13
3 files changed, 43 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 592bbae..391cadb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,12 @@ SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net>
SPDX-License-Identifier: Apache-2.0
-->
+# v1.10.2 (TBD)
+
+Changes:
+
+- In assert.Equal output, present string literals with backticks instead of quotes when it makes the output more readable.
+
# v1.10.1 (2026-06-20)
Changes:
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.
diff --git a/assert/equal_test.go b/assert/equal_test.go
index df6fd70..3872ab7 100644
--- a/assert/equal_test.go
+++ b/assert/equal_test.go
@@ -31,6 +31,19 @@ func TestEqual(t *testing.T) {
assert.Equal(t, false, true)
}, `expected true, but got false`)
+ // scalars: check that string values are formatted with backticks when it makes the output nicer
+ expectErrors(t, func(t assert.TestingTB) {
+ assert.Equal(t, "bar", "foo")
+ assert.Equal(t, "Please run `rm -rf /`.", "Please run `echo hello`.")
+ assert.Equal(t, `{"foo":1,"bar":3}`, `{"foo":1,"bar":2}`)
+ assert.Equal(t, "\x1B[1;31mError\x1B[0m", "\x1B[1;32mSuccess\x1B[0m")
+ }, strings.Join([]string{
+ `expected "foo", but got "bar"`,
+ "expected \"Please run `echo hello`.\", but got \"Please run `rm -rf /`.\"",
+ "expected `{\"foo\":1,\"bar\":2}`, but got `{\"foo\":1,\"bar\":3}`",
+ `expected "\x1b[1;32mSuccess\x1b[0m", but got "\x1b[1;31mError\x1b[0m"`,
+ }, "\n"))
+
// basic test for slices
correctSlice := []int{1, 2, 3}
wrongSlice := []int{1, 42, 3}