Skip to content

Commit

Permalink
Merge pull request #19 from lainio/issue-18
Browse files Browse the repository at this point in the history
issue 18
  • Loading branch information
lainio authored Aug 21, 2023
2 parents 035a755 + 7b5af1d commit 8fe8a79
Show file tree
Hide file tree
Showing 14 changed files with 388 additions and 62 deletions.
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

0 comments on commit 8fe8a79

Please sign in to comment.