Skip to content

Commit 04fa9cc

Browse files
committed
Q&D test to optimize assert.Zero even it's generics, good strategy
1 parent 767a53d commit 04fa9cc

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

assert/assert.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -899,11 +899,15 @@ func Less[T Number](val, want T, a ...any) {
899899
// are used to override the auto-generated assert violation message.
900900
func Zero[T Number](val T, a ...any) {
901901
if val != 0 {
902-
defMsg := fmt.Sprintf(assertionMsg+": got '%v', want (== '0')", val)
903-
current().reportAssertionFault(defMsg, a)
902+
doZero(val, a)
904903
}
905904
}
906905

906+
func doZero[T Number](val T, a []any) {
907+
defMsg := fmt.Sprintf(assertionMsg+": got '%v', want (== '0')", val)
908+
current().newReportAssertionFault(defMsg, a)
909+
}
910+
907911
// NotZero asserts that the value != 0. If it is not it panics and builds a
908912
// violation message. Thanks to inlining, the performance penalty is equal to a
909913
// single 'if-statement' that is almost nothing.

assert/asserter.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,36 @@ func (asserter asserter) reportAssertionFault(defaultMsg string, a []any) {
8686
}
8787
}
8888

89+
func (asserter asserter) newReportAssertionFault(defaultMsg string, a []any) {
90+
if asserter.hasStackTrace() {
91+
if asserter.isUnitTesting() {
92+
// Note. that the assert in the test function is printed in
93+
// reportPanic below
94+
const stackLvl = 4 // amount of functions before we're here
95+
debug.PrintStackForTest(os.Stderr, stackLvl)
96+
} else {
97+
// amount of functions before we're here, which is different
98+
// between runtime (this) and test-run (above)
99+
const stackLvl = 1
100+
debug.PrintStack(stackLvl)
101+
}
102+
}
103+
if asserter.hasCallerInfo() {
104+
defaultMsg = asserter.newCallerInfo(defaultMsg)
105+
}
106+
if len(a) > 0 {
107+
if format, ok := a[0].(string); ok {
108+
allowDefMsg := !asserter.isErrorOnly() && defaultMsg != ""
109+
f := x.Whom(allowDefMsg, defaultMsg+conCatErrStr+format, format)
110+
asserter.reportPanic(fmt.Sprintf(f, a[1:]...))
111+
} else {
112+
asserter.reportPanic(fmt.Sprintln(append([]any{defaultMsg}, a...)))
113+
}
114+
} else {
115+
asserter.reportPanic(defaultMsg)
116+
}
117+
}
118+
89119
func (asserter asserter) reportPanic(s string) {
90120
if asserter.isUnitTesting() && asserter.hasCallerInfo() {
91121
fmt.Fprintln(os.Stderr, officialTestOutputPrefix+s)
@@ -144,6 +174,24 @@ func (asserter asserter) callerInfo(msg string) (info string) {
144174
return
145175
}
146176

177+
func (asserter asserter) newCallerInfo(msg string) (info string) {
178+
ourFmtStr := shortFmtStr
179+
if asserter.hasFormattedCallerInfo() {
180+
ourFmtStr = longFmtStr
181+
}
182+
183+
const framesToSkip = 4 // how many fn calls there is before FuncName call
184+
includePath := asserter.isUnitTesting()
185+
funcName, filename, line, ok := str.FuncName(framesToSkip, includePath)
186+
if ok {
187+
info = fmt.Sprintf(ourFmtStr,
188+
filename, line,
189+
funcName, msg)
190+
}
191+
192+
return
193+
}
194+
147195
func (asserter asserter) isErrorOnly() bool {
148196
return asserter == asserterToError
149197
}

0 commit comments

Comments
 (0)