Skip to content

Commit 4d09b51

Browse files
Implement a few polishes and add NotNearlyEqual (#104)
1 parent f99220d commit 4d09b51

21 files changed

Lines changed: 351 additions & 95 deletions

config.go

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"math"
77
"strings"
8+
"unicode/utf8"
89
)
910

1011
const (
@@ -37,25 +38,35 @@ type failure[T any] struct {
3738
// String implements [fmt.Stringer] for failure, allowing it to print itself in the test log.
3839
func (f failure[T]) String() string {
3940
s := &strings.Builder{}
40-
s.WriteByte('\n')
41-
42-
s.WriteString(f.cfg.title)
43-
s.WriteByte('\n')
44-
s.WriteString(strings.Repeat("-", len(f.cfg.title)))
45-
s.WriteString("\n\n")
41+
f.cfg.writeHeader(s)
4642

4743
fmt.Fprintf(s, "Got:\t%+v\n", f.got)
4844
fmt.Fprintf(s, "Wanted:\t%+v\n", f.want)
4945

50-
if f.cfg.context != "" {
51-
fmt.Fprintf(s, "\n(%s)\n", f.cfg.context)
52-
}
46+
f.cfg.writeFooter(s)
47+
48+
return s.String()
49+
}
5350

54-
if f.cfg.reason != "" {
55-
fmt.Fprintf(s, "\nBecause: %s\n", f.cfg.reason)
51+
// writeHeader writes the title block (leading blank line, title, underline, blank line)
52+
// to s. The underline is sized by rune count so multi-byte titles align correctly.
53+
func (c config) writeHeader(s *strings.Builder) {
54+
s.WriteByte('\n')
55+
s.WriteString(c.title)
56+
s.WriteByte('\n')
57+
s.WriteString(strings.Repeat("-", utf8.RuneCountInString(c.title)))
58+
s.WriteString("\n\n")
59+
}
60+
61+
// writeFooter writes any optional context and reason lines to s.
62+
func (c config) writeFooter(s *strings.Builder) {
63+
if c.context != "" {
64+
fmt.Fprintf(s, "\n(%s)\n", c.context)
5665
}
5766

58-
return s.String()
67+
if c.reason != "" {
68+
fmt.Fprintf(s, "\nBecause: %s\n", c.reason)
69+
}
5970
}
6071

6172
// Option is a configuration option for a test.
@@ -79,7 +90,7 @@ func (o option) apply(cfg *config) error {
7990
// two floating point numbers before they are considered equal. This setting is only
8091
// used in [NearlyEqual] and [NotNearlyEqual].
8192
//
82-
// Setting threshold to ±math.Inf is an error and will fail the test.
93+
// Setting threshold to ±[math.Inf] is an error and will fail the test.
8394
//
8495
// The default is 1e-8, a sensible default for most cases.
8596
func FloatEqualityThreshold(threshold float64) Option {
@@ -137,12 +148,12 @@ func Title(title string) Option {
137148
// test.Ok(t, err, test.Context("something complicated failed"))
138149
func Context(format string, args ...any) Option {
139150
f := func(cfg *config) error {
140-
if format == "" {
151+
context := strings.TrimSpace(fmt.Sprintf(format, args...))
152+
if context == "" {
141153
return errors.New("cannot set context to an empty string")
142154
}
143155

144-
context := fmt.Sprintf(format, args...)
145-
cfg.context = strings.TrimSpace(context)
156+
cfg.context = context
146157

147158
return nil
148159
}

0 commit comments

Comments
 (0)