github.com/pachyderm/pachyderm@v1.13.4/src/client/pkg/errors/testing/errors_test.go (about)

     1  package testing
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/pachyderm/pachyderm/src/client/pkg/errors"
     8  	"github.com/pachyderm/pachyderm/src/client/pkg/require"
     9  )
    10  
    11  // FooErr is an error with a normal receiver for fulfilling the error interface
    12  type FooErr struct {
    13  	val int
    14  }
    15  
    16  func (err FooErr) Error() string {
    17  	return fmt.Sprintf("foo-%d", err.val)
    18  }
    19  
    20  // PtrFooErr is an error with a pointer receiver for fulfilling the error interface
    21  type PtrFooErr struct {
    22  	val int
    23  }
    24  
    25  func (err *PtrFooErr) Error() string {
    26  	return fmt.Sprintf("fooptr-%d", err.val)
    27  }
    28  
    29  // IntErr is an interface that also fulfills the error interface
    30  type IntErr interface {
    31  	Int() int
    32  	Error() string
    33  }
    34  
    35  // ConcreteIntErr is an implementation of the IntErr interface using a normal receiver
    36  type ConcreteIntErr struct {
    37  	val int
    38  }
    39  
    40  func (err ConcreteIntErr) Int() int {
    41  	return err.val
    42  }
    43  
    44  func (err ConcreteIntErr) Error() string {
    45  	return fmt.Sprintf("int-%d", err.Int())
    46  }
    47  
    48  // ConcreteIntErr is an implementation of the IntErr interface using a pointer receiver
    49  type ConcretePtrIntErr struct {
    50  	val int
    51  }
    52  
    53  func (err *ConcretePtrIntErr) Int() int {
    54  	return err.val
    55  }
    56  
    57  func (err *ConcretePtrIntErr) Error() string {
    58  	return fmt.Sprintf("intptr-%d", err.Int())
    59  }
    60  
    61  // OtherErr is a different error type to be used for failed casting
    62  type OtherErr struct{}
    63  
    64  func (err OtherErr) Error() string {
    65  	return "other"
    66  }
    67  
    68  func TestAsFooErr(t *testing.T) {
    69  	var err error
    70  	fooerr := &FooErr{}
    71  	otherErr := &OtherErr{}
    72  
    73  	err = FooErr{1}
    74  	require.True(t, errors.As(err, &FooErr{}))
    75  	require.False(t, errors.As(err, &OtherErr{}))
    76  
    77  	err = FooErr{2}
    78  	require.True(t, errors.As(err, fooerr))
    79  	require.False(t, errors.As(err, otherErr))
    80  	require.Equal(t, fooerr, &FooErr{2})
    81  
    82  	err = FooErr{3}
    83  	require.True(t, errors.As(err, &fooerr))
    84  	require.False(t, errors.As(err, &otherErr))
    85  	require.Equal(t, fooerr, &FooErr{3})
    86  
    87  	err = &FooErr{4}
    88  	require.True(t, errors.As(err, &FooErr{}))
    89  	require.False(t, errors.As(err, &OtherErr{}))
    90  
    91  	err = &FooErr{5}
    92  	require.True(t, errors.As(err, fooerr))
    93  	require.False(t, errors.As(err, otherErr))
    94  	require.Equal(t, fooerr, &FooErr{5})
    95  
    96  	err = &FooErr{6}
    97  	require.True(t, errors.As(err, &fooerr))
    98  	require.False(t, errors.As(err, &otherErr))
    99  	require.Equal(t, fooerr, &FooErr{6})
   100  }
   101  
   102  func TestAsPtrFooErr(t *testing.T) {
   103  	var err error
   104  	fooptrerr := &PtrFooErr{}
   105  	otherErr := &OtherErr{}
   106  
   107  	// these don't compile - fooptrerr can't be used as an error unless it's a pointer
   108  	// err = PtrFooErr{1}
   109  	// require.True(t, errors.As(err, &PtrFooErr{}))
   110  	// require.False(t, errors.As(err, &OtherErr{}))
   111  
   112  	// err = PtrFooErr{2}
   113  	// require.True(t, errors.As(err, fooptrerr))
   114  	// require.False(t, errors.As(err, otherErr))
   115  	// require.Equal(t, fooptrerr, &PtrFooErr{2})
   116  
   117  	// err = PtrFooErr{3}
   118  	// require.True(t, errors.As(err, &fooptrerr))
   119  	// require.False(t, errors.As(err, &otherErr))
   120  	// require.Equal(t, fooptrerr, &PtrFooErr{3})
   121  
   122  	err = &PtrFooErr{4}
   123  	require.True(t, errors.As(err, &PtrFooErr{}))
   124  	require.False(t, errors.As(err, &OtherErr{}))
   125  
   126  	err = &PtrFooErr{5}
   127  	require.True(t, errors.As(err, fooptrerr))
   128  	require.False(t, errors.As(err, otherErr))
   129  	require.Equal(t, fooptrerr, &PtrFooErr{5})
   130  
   131  	err = &PtrFooErr{6}
   132  	require.True(t, errors.As(err, &fooptrerr))
   133  	require.False(t, errors.As(err, &otherErr))
   134  	require.Equal(t, fooptrerr, &PtrFooErr{6})
   135  }
   136  
   137  func TestAsConcreteIntErr(t *testing.T) {
   138  	var err error
   139  	var interrFace IntErr
   140  	var interr IntErr = &ConcreteIntErr{}
   141  	otherErr := &OtherErr{}
   142  
   143  	err = ConcreteIntErr{1}
   144  	// this doesn't compile - can't construct an IntErr{} as it's an interface
   145  	// require.True(t, errors.As(err, &IntErr{}))
   146  	require.False(t, errors.As(err, &OtherErr{}))
   147  
   148  	err = ConcreteIntErr{2}
   149  	require.True(t, errors.As(err, interr))
   150  	require.False(t, errors.As(err, otherErr))
   151  	require.Equal(t, &ConcreteIntErr{2}, interr)
   152  
   153  	err = ConcreteIntErr{3}
   154  	require.True(t, errors.As(err, &interr))
   155  	require.True(t, errors.As(err, &interrFace))
   156  	require.False(t, errors.As(err, &otherErr))
   157  	require.Equal(t, ConcreteIntErr{3}, interr)
   158  	require.Equal(t, ConcreteIntErr{3}, interrFace)
   159  
   160  	err = &ConcreteIntErr{4}
   161  	// this doesn't compile - can't construct an IntErr{} as it's an interface
   162  	// require.True(t, errors.As(err, &IntErr{}))
   163  	require.False(t, errors.As(err, &OtherErr{}))
   164  
   165  	err = &ConcreteIntErr{5}
   166  	interr = &ConcreteIntErr{}
   167  	require.True(t, errors.As(err, interr))
   168  	require.False(t, errors.As(err, otherErr))
   169  	require.Equal(t, &ConcreteIntErr{5}, interr)
   170  
   171  	interrFace = nil
   172  	err = &ConcreteIntErr{6}
   173  	require.True(t, errors.As(err, &interr))
   174  	require.True(t, errors.As(err, &interrFace))
   175  	require.False(t, errors.As(err, &otherErr))
   176  	require.Equal(t, &ConcreteIntErr{6}, interr)
   177  	require.Equal(t, &ConcreteIntErr{6}, interrFace)
   178  }
   179  
   180  func TestAsConcretePtrIntErr(t *testing.T) {
   181  	var err error
   182  	var interrFace IntErr
   183  	var interr IntErr = &ConcretePtrIntErr{}
   184  	otherErr := &OtherErr{}
   185  
   186  	// these don't compile - ConcretePtrIntErr can't be used as an error unless it's a pointer
   187  	// err = ConcretePtrIntErr{1}
   188  	// require.True(t, errors.As(err, &IntErr{}))
   189  	// require.False(t, errors.As(err, &OtherErr{}))
   190  
   191  	// err = ConcretePtrIntErr{2}
   192  	// require.True(t, errors.As(err, interr))
   193  	// require.False(t, errors.As(err, otherErr))
   194  	// require.Equal(t, &ConcretePtrIntErr{2}, interr)
   195  
   196  	// err = ConcretePtrIntErr{3}
   197  	// require.True(t, errors.As(err, &interr))
   198  	// require.False(t, errors.As(err, &otherErr))
   199  	// require.Equal(t, &ConcretePtrIntErr{3}, interr)
   200  
   201  	err = &ConcretePtrIntErr{4}
   202  	// this doesn't compile - can't construct an IntErr{} as it's an interface
   203  	// require.True(t, errors.As(err, &IntErr{}))
   204  	require.False(t, errors.As(err, &OtherErr{}))
   205  
   206  	err = &ConcretePtrIntErr{5}
   207  	require.True(t, errors.As(err, interr))
   208  	require.False(t, errors.As(err, otherErr))
   209  	require.Equal(t, &ConcretePtrIntErr{5}, interr)
   210  
   211  	interrFace = nil
   212  	err = &ConcretePtrIntErr{6}
   213  	require.True(t, errors.As(err, &interr))
   214  	require.True(t, errors.As(err, &interrFace))
   215  	require.False(t, errors.As(err, &otherErr))
   216  	require.Equal(t, &ConcretePtrIntErr{6}, interr)
   217  	require.Equal(t, &ConcretePtrIntErr{6}, interrFace)
   218  }