mirror of
https://github.com/samber/lo.git
synced 2025-09-26 20:11:13 +08:00
feat(assertions): add Assert
and Assertf
(#638)
Co-authored-by: ynn <contact@your-diary.io>
This commit is contained in:
41
README.md
41
README.md
@@ -327,6 +327,11 @@ Error handling:
|
||||
- [TryCatchWithErrorValue](#trycatchwitherrorvalue)
|
||||
- [ErrorsAs](#errorsas)
|
||||
|
||||
Assertions:
|
||||
|
||||
- [Assert](#assert)
|
||||
- [Assertf](#assertf)
|
||||
|
||||
Constraints:
|
||||
|
||||
- Clonable
|
||||
@@ -4095,6 +4100,42 @@ if rateLimitErr, ok := lo.ErrorsAs[*RateLimitError](err); ok {
|
||||
|
||||
[[play](https://go.dev/play/p/8wk5rH8UfrE)]
|
||||
|
||||
### Assert
|
||||
|
||||
C/C++ style assertion.
|
||||
|
||||
It does nothing when the condition is `true`, otherwise it panics with an optional message.
|
||||
|
||||
Think twice before using it, given that [Go intentionally omits assertions from its standard library](https://go.dev/doc/faq#assertions).
|
||||
|
||||
```go
|
||||
age := getUserAge()
|
||||
|
||||
lo.Assert(age >= 15)
|
||||
```
|
||||
|
||||
```go
|
||||
age := getUserAge()
|
||||
|
||||
lo.Assert(age >= 15, "user age must be >= 15")
|
||||
```
|
||||
|
||||
[[play](https://go.dev/play/p/Xv8LLKBMNwI)]
|
||||
|
||||
### Assertf
|
||||
|
||||
Like `Assert`, but with `fmt.Printf`-like formatting.
|
||||
|
||||
Think twice before using it, given that [Go intentionally omits assertions from its standard library](https://go.dev/doc/faq#assertions).
|
||||
|
||||
```go
|
||||
age := getUserAge()
|
||||
|
||||
lo.Assertf(age >= 15, "user age must be >= 15, got %d", age)
|
||||
```
|
||||
|
||||
[[play](https://go.dev/play/p/TVPEmVcyrdY)]
|
||||
|
||||
## 🛩 Benchmark
|
||||
|
||||
We executed a simple benchmark with a dead-simple `lo.Map` loop:
|
||||
|
28
assertions.go
Normal file
28
assertions.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package lo
|
||||
|
||||
import "fmt"
|
||||
|
||||
const defaultAssertionFailureMessage = "assertion failed"
|
||||
|
||||
// Assert does nothing when the condition is true, otherwise it panics with an optional message.
|
||||
func Assert(condition bool, message ...string) {
|
||||
if condition {
|
||||
return
|
||||
}
|
||||
|
||||
panicMessage := defaultAssertionFailureMessage
|
||||
if len(message) > 0 {
|
||||
panicMessage = fmt.Sprintf("%s: %s", defaultAssertionFailureMessage, message[0])
|
||||
}
|
||||
panic(panicMessage)
|
||||
}
|
||||
|
||||
// Assertf does nothing when the condition is true, otherwise it panics with a formatted message.
|
||||
func Assertf(condition bool, format string, args ...any) {
|
||||
if condition {
|
||||
return
|
||||
}
|
||||
|
||||
panicMessage := fmt.Sprintf("%s: %s", defaultAssertionFailureMessage, fmt.Sprintf(format, args...))
|
||||
panic(panicMessage)
|
||||
}
|
45
assertions_example_test.go
Normal file
45
assertions_example_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package lo
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ExampleAssert() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println(r)
|
||||
}
|
||||
}()
|
||||
|
||||
age := 20
|
||||
|
||||
// won't panic
|
||||
Assert(age >= 18)
|
||||
|
||||
// won't panic
|
||||
Assert(age >= 18, "age must be at least 18")
|
||||
|
||||
// will panic
|
||||
Assert(age < 18)
|
||||
|
||||
// will panic
|
||||
Assert(age < 18, "age must be less than 18")
|
||||
|
||||
// Output: assertion failed
|
||||
}
|
||||
|
||||
func ExampleAssertf() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println(r)
|
||||
}
|
||||
}()
|
||||
|
||||
age := 20
|
||||
|
||||
// won't panic
|
||||
Assertf(age >= 18, "age must be at least 18, got %d", age)
|
||||
|
||||
// will panic
|
||||
Assertf(age < 18, "age must be less than 18, got %d", age)
|
||||
|
||||
// Output: assertion failed: age must be less than 18, got 20
|
||||
}
|
68
assertions_test.go
Normal file
68
assertions_test.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package lo
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAssert(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
is.NotPanics(func() {
|
||||
Assert(true)
|
||||
})
|
||||
|
||||
is.NotPanics(func() {
|
||||
Assert(true, "user defined message")
|
||||
})
|
||||
|
||||
is.PanicsWithValue("assertion failed", func() {
|
||||
Assert(false)
|
||||
})
|
||||
|
||||
is.PanicsWithValue("assertion failed: user defined message", func() {
|
||||
Assert(false, "user defined message")
|
||||
})
|
||||
|
||||
//checks that the examples in `README.md` compile
|
||||
{
|
||||
age := 20
|
||||
is.NotPanics(func() {
|
||||
Assert(age >= 15)
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Assert(age >= 15, "user age must be >= 15")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssertf(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
is.NotPanics(func() {
|
||||
Assertf(true, "user defined message")
|
||||
})
|
||||
|
||||
is.NotPanics(func() {
|
||||
Assertf(true, "user defined message %d %d", 1, 2)
|
||||
})
|
||||
|
||||
is.PanicsWithValue("assertion failed: user defined message", func() {
|
||||
Assertf(false, "user defined message")
|
||||
})
|
||||
|
||||
is.PanicsWithValue("assertion failed: user defined message 1 2", func() {
|
||||
Assertf(false, "user defined message %d %d", 1, 2)
|
||||
})
|
||||
|
||||
//checks that the example in `README.md` compiles
|
||||
{
|
||||
age := 7
|
||||
is.PanicsWithValue("assertion failed: user age must be >= 15, got 7", func() {
|
||||
Assertf(age >= 15, "user age must be >= 15, got %d", age)
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user