github.com/mailgun/holster/v4@v4.20.0/errors/errors_test.go (about)

     1  package errors
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestNew(t *testing.T) {
    13  	tests := []struct {
    14  		err  string
    15  		want error
    16  	}{
    17  		{"", fmt.Errorf("")},
    18  		{"foo", fmt.Errorf("foo")},
    19  		{"foo", New("foo")},
    20  		{"string with format specifiers: %v", errors.New("string with format specifiers: %v")},
    21  	}
    22  
    23  	for _, tt := range tests {
    24  		got := New(tt.err)
    25  		if got.Error() != tt.want.Error() {
    26  			t.Errorf("New.Error(): got: %q, want %q", got, tt.want)
    27  		}
    28  	}
    29  }
    30  
    31  func TestWrapNil(t *testing.T) {
    32  	got := Wrap(nil, "no error")
    33  	if got != nil {
    34  		t.Errorf("Wrap(nil, \"no error\"): got %#v, expected nil", got)
    35  	}
    36  }
    37  
    38  func TestWrap(t *testing.T) {
    39  	tests := []struct {
    40  		err     error
    41  		message string
    42  		want    string
    43  	}{
    44  		{io.EOF, "read error", "read error: EOF"},
    45  		{Wrap(io.EOF, "read error"), "client error", "client error: read error: EOF"},
    46  	}
    47  
    48  	for _, tt := range tests {
    49  		got := Wrap(tt.err, tt.message).Error()
    50  		if got != tt.want {
    51  			t.Errorf("Wrap(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
    52  		}
    53  	}
    54  }
    55  
    56  type nilError struct{}
    57  
    58  func (nilError) Error() string { return "nil error" }
    59  
    60  func TestCause(t *testing.T) {
    61  	x := New("error")
    62  	tests := []struct {
    63  		err  error
    64  		want error
    65  	}{{
    66  		// nil error is nil
    67  		err:  nil,
    68  		want: nil,
    69  	}, {
    70  		// explicit nil error is nil
    71  		err:  error(nil),
    72  		want: nil,
    73  	}, {
    74  		// typed nil is nil
    75  		err:  (*nilError)(nil),
    76  		want: (*nilError)(nil),
    77  	}, {
    78  		// uncaused error is unaffected
    79  		err:  io.EOF,
    80  		want: io.EOF,
    81  	}, {
    82  		// caused error returns cause
    83  		err:  Wrap(io.EOF, "ignored"),
    84  		want: io.EOF,
    85  	}, {
    86  		err:  x, // return from errors.New
    87  		want: x,
    88  	}, {
    89  		WithMessage(nil, "whoops"),
    90  		nil,
    91  	}, {
    92  		WithMessage(io.EOF, "whoops"),
    93  		io.EOF,
    94  	}, {
    95  		WithStack(nil),
    96  		nil,
    97  	}, {
    98  		WithStack(io.EOF),
    99  		io.EOF,
   100  	}}
   101  
   102  	for i, tt := range tests {
   103  		got := Cause(tt.err)
   104  		require.ErrorIsf(t, tt.want, got, "test %d: got %#v, want %#v", i+1, got, tt.want)
   105  	}
   106  }
   107  
   108  func TestWrapfNil(t *testing.T) {
   109  	got := Wrapf(nil, "no error")
   110  	if got != nil {
   111  		t.Errorf("Wrapf(nil, \"no error\"): got %#v, expected nil", got)
   112  	}
   113  }
   114  
   115  func TestWrapf(t *testing.T) {
   116  	tests := []struct {
   117  		err     error
   118  		message string
   119  		want    string
   120  	}{
   121  		{io.EOF, "read error", "read error: EOF"},
   122  		{Wrapf(io.EOF, "read error without format specifiers"), "client error", "client error: read error without format specifiers: EOF"},
   123  		{Wrapf(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"},
   124  	}
   125  
   126  	for _, tt := range tests {
   127  		got := Wrapf(tt.err, tt.message).Error()
   128  		if got != tt.want {
   129  			t.Errorf("Wrapf(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
   130  		}
   131  	}
   132  }
   133  
   134  func TestErrorf(t *testing.T) {
   135  	tests := []struct {
   136  		err  error
   137  		want string
   138  	}{
   139  		{Errorf("read error without format specifiers"), "read error without format specifiers"},
   140  		{Errorf("read error with %d format specifier", 1), "read error with 1 format specifier"},
   141  	}
   142  
   143  	for _, tt := range tests {
   144  		got := tt.err.Error()
   145  		if got != tt.want {
   146  			t.Errorf("Errorf(%v): got: %q, want %q", tt.err, got, tt.want)
   147  		}
   148  	}
   149  }
   150  
   151  func TestWithStackNil(t *testing.T) {
   152  	got := WithStack(nil)
   153  	if got != nil {
   154  		t.Errorf("WithStack(nil): got %#v, expected nil", got)
   155  	}
   156  }
   157  
   158  func TestWithStack(t *testing.T) {
   159  	tests := []struct {
   160  		err  error
   161  		want string
   162  	}{
   163  		{io.EOF, "EOF"},
   164  		{WithStack(io.EOF), "EOF"},
   165  	}
   166  
   167  	for _, tt := range tests {
   168  		got := WithStack(tt.err).Error()
   169  		if got != tt.want {
   170  			t.Errorf("WithStack(%v): got: %v, want %v", tt.err, got, tt.want)
   171  		}
   172  	}
   173  }
   174  
   175  func TestWithMessageNil(t *testing.T) {
   176  	got := WithMessage(nil, "no error")
   177  	if got != nil {
   178  		t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got)
   179  	}
   180  }
   181  
   182  func TestWithMessage(t *testing.T) {
   183  	tests := []struct {
   184  		err     error
   185  		message string
   186  		want    string
   187  	}{
   188  		{io.EOF, "read error", "read error: EOF"},
   189  		{WithMessage(io.EOF, "read error"), "client error", "client error: read error: EOF"},
   190  	}
   191  
   192  	for _, tt := range tests {
   193  		got := WithMessage(tt.err, tt.message).Error()
   194  		if got != tt.want {
   195  			t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want)
   196  		}
   197  	}
   198  }
   199  
   200  // errors.New, etc values are not expected to be compared by value
   201  // but the change in errors#27 made them incomparable. Assert that
   202  // various kinds of errors have a functional equality operator, even
   203  // if the result of that equality is always false.
   204  func TestErrorEquality(t *testing.T) {
   205  	vals := []error{
   206  		nil,
   207  		io.EOF,
   208  		errors.New("EOF"),
   209  		New("EOF"),
   210  		Errorf("EOF"),
   211  		Wrap(io.EOF, "EOF"),
   212  		Wrapf(io.EOF, "EOF%d", 2),
   213  		WithMessage(nil, "whoops"),
   214  		WithMessage(io.EOF, "whoops"),
   215  		WithStack(io.EOF),
   216  		WithStack(nil),
   217  	}
   218  
   219  	for i := range vals {
   220  		for j := range vals {
   221  			_ = vals[i] == vals[j] // mustn't panic
   222  		}
   223  	}
   224  }