codeberg.org/gruf/go-errors/v2@v2.3.1/standard_test.go (about)

     1  package errors_test
     2  
     3  import (
     4  	"crypto/x509"
     5  	"fmt"
     6  	"io/fs"
     7  	"os"
     8  	"testing"
     9  
    10  	"codeberg.org/gruf/go-errors/v2"
    11  )
    12  
    13  func TestAs(t *testing.T) {
    14  	var errT errorT
    15  	var errP *fs.PathError
    16  	var p *poser
    17  	_, errF := os.Open("non-existing")
    18  	poserErr := &poser{"oh no", nil}
    19  	testCases := []struct {
    20  		err    error
    21  		target error
    22  		check  func(err, target error) bool
    23  		match  bool
    24  	}{{
    25  		nil,
    26  		errP,
    27  		func(err, target error) bool {
    28  			check := errors.AsV2[*fs.PathError](err)
    29  			return check != nil
    30  		},
    31  		false,
    32  	}, {
    33  		wrapped{"pitied the fool", errorT{"T"}},
    34  		errT,
    35  		func(err, target error) bool {
    36  			check := errors.AsV2[errorT](err)
    37  			return check != errorT{}
    38  		},
    39  		true,
    40  	}, {
    41  		errF,
    42  		errP,
    43  		func(err, target error) bool {
    44  			check := errors.AsV2[*fs.PathError](err)
    45  			return check != nil
    46  		},
    47  		true,
    48  	}, {
    49  		errorT{},
    50  		errP,
    51  		func(err, target error) bool {
    52  			check := errors.AsV2[*fs.PathError](err)
    53  			return check != nil
    54  		},
    55  		false,
    56  	}, {
    57  		wrapped{"wrapped", nil},
    58  		&errT,
    59  		func(err, target error) bool {
    60  			check := errors.AsV2[*errorT](err)
    61  			return check != nil
    62  		},
    63  		false,
    64  	}, {
    65  		&poser{"error", nil},
    66  		&errT,
    67  		func(err, target error) bool {
    68  			check := errors.AsV2[errorT](err)
    69  			return check != errorT{}
    70  		},
    71  		true,
    72  	}, {
    73  		poserErr,
    74  		p,
    75  		func(err, target error) bool {
    76  			check := errors.AsV2[*poser](err)
    77  			return check != nil
    78  		},
    79  		true,
    80  	}, {
    81  		fmt.Errorf("text: %w", &x509.UnknownAuthorityError{}),
    82  		(*x509.UnknownAuthorityError)(nil),
    83  		func(err, target error) bool {
    84  			check := errors.AsV2[*x509.UnknownAuthorityError](err)
    85  			return check != nil
    86  		},
    87  		true,
    88  	}, {
    89  		fmt.Errorf("text: %w", &x509.CertificateInvalidError{}),
    90  		(*x509.UnknownAuthorityError)(nil),
    91  		func(err, target error) bool {
    92  			check := errors.AsV2[*x509.UnknownAuthorityError](err)
    93  			return check != nil
    94  		},
    95  		false,
    96  	}}
    97  	for i, tc := range testCases {
    98  		name := fmt.Sprintf("%d:(As(Errorf(..., %v)) == %#v)", i, tc.err, tc.target)
    99  		// Clear the target pointer, in case it was set in a previous test.
   100  		t.Run(name, func(t *testing.T) {
   101  			if tc.check(tc.err, tc.target) != tc.match {
   102  				t.Fail()
   103  			}
   104  		})
   105  	}
   106  }
   107  
   108  type poser struct {
   109  	msg string
   110  
   111  	f func(error) bool
   112  }
   113  
   114  var poserPathErr = &fs.PathError{Op: "poser"}
   115  
   116  func (p *poser) Error() string { return p.msg }
   117  
   118  func (p *poser) Is(err error) bool { return p.f != nil && p.f(err) }
   119  
   120  func (p *poser) As(err interface{}) bool {
   121  	switch x := err.(type) {
   122  	case **poser:
   123  		*x = p
   124  
   125  	case *errorT:
   126  		*x = errorT{"poser"}
   127  
   128  	case **fs.PathError:
   129  		*x = poserPathErr
   130  
   131  	default:
   132  		return false
   133  	}
   134  
   135  	return true
   136  }
   137  
   138  type errorT struct{ s string }
   139  
   140  func (e errorT) Error() string { return fmt.Sprintf("errorT(%s)", e.s) }
   141  
   142  type wrapped struct {
   143  	msg string
   144  
   145  	err error
   146  }
   147  
   148  func (e wrapped) Error() string { return e.msg }
   149  
   150  func (e wrapped) Unwrap() error { return e.err }
   151  
   152  type errorUncomparable struct {
   153  	f []string
   154  }
   155  
   156  func (errorUncomparable) Error() string {
   157  	return "uncomparable error"
   158  }
   159  
   160  func (errorUncomparable) Is(target error) bool {
   161  	_, ok := target.(errorUncomparable)
   162  
   163  	return ok
   164  }