Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,10 @@ Please see the full version history from [CHANGELOG](./CHANGELOG.md).

### Latest Release

##### 0.9.41
- Issue #18: **bug fixed**: noerr-handler had to be the last one of the err2
handlers

##### 0.9.40
- Significant performance boost for: `defer err2.Handle/Catch()`
- **3x faster happy path than the previous version, which is now equal to
Expand Down
39 changes: 25 additions & 14 deletions assert/assert.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,45 @@ import (
type defInd = uint32

const (
// Production is the best asserter for most uses. The assertion violations
// are treated as Go error values. And only a pragmatic caller info is
// automatically included into the error message like file name, line
// number, and caller function.
// Production (pkg default) is the best asserter for most uses. The
// assertion violations are treated as Go error values. And only a
// pragmatic caller info is automatically included into the error message
// like file name, line number, and caller function, all in one line:
//
// copy file: main.go:37: CopyFile(): assertion violation: string shouldn't be empty
Production defInd = 0 + iota

// Development is the best asserter for most development uses. The
// assertion violations are treated as Go error values. And a formatted
// caller info is automatically included to the error message like file
// name, line number, and caller function.
// name, line number, and caller function. Everything in a beautiful
// multi-line message:
//
// --------------------------------
// Assertion Fault at:
// main.go:37 CopyFile():
// assertion violation: string shouldn't be empty
// --------------------------------
Development

// Test minimalistic asserter for unit test use. More pragmatic is the
// TestFull asserter (default).
// TestFull asserter (test default).
//
// Use this asserter if your IDE/editor doesn't support long file names, or
// for temporary problem solving for your programming environment.
// Use this asserter if your IDE/editor doesn't support full file names and
// it relies a relative path (Go standard). You can use this also if you
// need temporary problem solving for your programming environment.
Test

// TestFull asserter (default). The TestFull asserter includes caller info
// and call stack for unit testing, similarly like err2's error traces.
// TestFull asserter (test default). The TestFull asserter includes the
// caller info and the call stack for unit testing, similarly like err2's
// error traces.
//
// The call stack produced by the test asserts can be used over Go module
// boundaries. For example, if your app and it's sub packages both use
// err2/assert for unit testing and runtime checks, the runtime assertions
// will be automatically converted to test asserts on the fly. If any of
// the runtime asserts in sub packages fails during the app tests, the
// current app test fails too.
// will be automatically converted to test asserts. If any of the runtime
// asserts of the sub packages fails during the app tests, the app test
// fails as well.
//
// Note, that the cross-module assertions produce long file names (path
// included), and some of the Go test result parsers cannot handle that.
Expand All @@ -53,7 +64,7 @@ const (
TestFull

// Debug asserter transforms assertion violations to panics which is the
// patter that e.g. Go's standard library uses:
// pattern that e.g. Go's standard library uses:
//
// if p == nil {
// panic("pkg: ptr cannot be nil")
Expand Down
9 changes: 9 additions & 0 deletions assert/asserter.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ const (
const officialTestOutputPrefix = " "

// NoImplementation always fails with no implementation.
// Deprecated: use e.g. assert.NotImplemented(), only default asserter is used.
func (asserter Asserter) NoImplementation(a ...any) {
asserter.reportAssertionFault("not implemented", a...)
}

// True asserts that term is true. If not it panics with the given formatting
// string. Note! This and Truef are the most performant of all the assertion
// functions.
// Deprecated: use e.g. assert.That(), only default asserter is used.
func (asserter Asserter) True(term bool, a ...any) {
if !term {
asserter.reportAssertionFault("assertion fault", a...)
Expand All @@ -63,6 +65,7 @@ func (asserter Asserter) True(term bool, a ...any) {

// Truef asserts that term is true. If not it panics with the given formatting
// string.
// Deprecated: use e.g. assert.That(), only default asserter is used.
func (asserter Asserter) Truef(term bool, format string, a ...any) {
if !term {
if asserter.hasStackTrace() {
Expand All @@ -76,6 +79,7 @@ func (asserter Asserter) Truef(term bool, format string, a ...any) {
// panics/errors (current Asserter) with the given msg. Note! This is very slow
// (before we have generics). If you need performance use EqualInt. It's not so
// convenient, though.
// Deprecated: use e.g. assert.Len(), only default asserter is used.
func (asserter Asserter) Len(obj any, length int, a ...any) {
ok, l := getLen(obj)
if !ok {
Expand All @@ -90,6 +94,7 @@ func (asserter Asserter) Len(obj any, length int, a ...any) {

// EqualInt asserts that integers are equal. If not it panics/errors (current
// Asserter) with the given msg.
// Deprecated: use e.g. assert.Equal(), only default asserter is used.
func (asserter Asserter) EqualInt(val, want int, a ...any) {
if want != val {
defMsg := fmt.Sprintf("got %d, want %d", val, want)
Expand All @@ -101,13 +106,15 @@ func (asserter Asserter) EqualInt(val, want int, a ...any) {
// panics/errors (current Asserter) with the given msg. Note! This is very slow
// (before we have generics). If you need performance use EqualInt. It's not so
// convenient, though.
// Deprecated: use e.g. assert.Len(), only default asserter is used.
func (asserter Asserter) Lenf(obj any, length int, format string, a ...any) {
args := combineArgs(format, a)
asserter.Len(obj, length, args...)
}

// Empty asserts that length of the object is zero. If not it panics with the
// given formatting string. Note! This is slow.
// Deprecated: use e.g. assert.Empty(), only default asserter is used.
func (asserter Asserter) Empty(obj any, msg ...any) {
ok, l := getLen(obj)
if !ok {
Expand All @@ -122,13 +129,15 @@ func (asserter Asserter) Empty(obj any, msg ...any) {

// NotEmptyf asserts that length of the object greater than zero. If not it
// panics with the given formatting string. Note! This is slow.
// Deprecated: use e.g. assert.NotEmpty(), only default asserter is used.
func (asserter Asserter) NotEmptyf(obj any, format string, msg ...any) {
args := combineArgs(format, msg)
asserter.Empty(obj, args...)
}

// NotEmpty asserts that length of the object greater than zero. If not it
// panics with the given formatting string. Note! This is slow.
// Deprecated: use e.g. assert.NotEmpty(), only default asserter is used.
func (asserter Asserter) NotEmpty(obj any, msg ...any) {
ok, l := getLen(obj)
if !ok {
Expand Down
1 change: 1 addition & 0 deletions assert/goid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
)

func TestGoid(t *testing.T) {
t.Parallel()
stackBytes := []byte(`goroutine 518 [running]:
`)

Expand Down
8 changes: 5 additions & 3 deletions err2.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,18 @@ var (
// an second argument:
//
// defer err2.Handle(&err, func(err error) error {
// os.Remove(dst)
// if rmErr := os.Remove(dst); rmErr != nil {
// return fmt.Errorf("%w: cleanup error: %w", err, rmErr)
// }
// return err
// })
//
// If you need to stop general panics in handler, you can do that by giving a
// panic handler function:
//
// defer err2.Handle(&err,
// err2.Err( func(error) { os.Remove(dst) }), // err2.Err keeps it short
// func(p any) {} // panic handler, it's stops panics, you can re-throw
// err2.Err( func(error) { os.Remove(dst) }), // err2.Err() keeps it short
// func(p any) {} // <- handler stops panics, re-throw or not
// )
func Handle(err *error, a ...any) {
// This and others are similar but we need to call `recover` here because
Expand Down
Loading