1// +build go1.13 2 3package errors 4 5import ( 6 stderrors "errors" 7 "fmt" 8 "reflect" 9 "testing" 10) 11 12func TestErrorChainCompat(t *testing.T) { 13 err := stderrors.New("error that gets wrapped") 14 wrapped := Wrap(err, "wrapped up") 15 if !stderrors.Is(wrapped, err) { 16 t.Errorf("Wrap does not support Go 1.13 error chains") 17 } 18} 19 20func TestIs(t *testing.T) { 21 err := New("test") 22 23 type args struct { 24 err error 25 target error 26 } 27 tests := []struct { 28 name string 29 args args 30 want bool 31 }{ 32 { 33 name: "with stack", 34 args: args{ 35 err: WithStack(err), 36 target: err, 37 }, 38 want: true, 39 }, 40 { 41 name: "with message", 42 args: args{ 43 err: WithMessage(err, "test"), 44 target: err, 45 }, 46 want: true, 47 }, 48 { 49 name: "with message format", 50 args: args{ 51 err: WithMessagef(err, "%s", "test"), 52 target: err, 53 }, 54 want: true, 55 }, 56 { 57 name: "std errors compatibility", 58 args: args{ 59 err: fmt.Errorf("wrap it: %w", err), 60 target: err, 61 }, 62 want: true, 63 }, 64 } 65 for _, tt := range tests { 66 t.Run(tt.name, func(t *testing.T) { 67 if got := Is(tt.args.err, tt.args.target); got != tt.want { 68 t.Errorf("Is() = %v, want %v", got, tt.want) 69 } 70 }) 71 } 72} 73 74type customErr struct { 75 msg string 76} 77 78func (c customErr) Error() string { return c.msg } 79 80func TestAs(t *testing.T) { 81 var err = customErr{msg: "test message"} 82 83 type args struct { 84 err error 85 target interface{} 86 } 87 tests := []struct { 88 name string 89 args args 90 want bool 91 }{ 92 { 93 name: "with stack", 94 args: args{ 95 err: WithStack(err), 96 target: new(customErr), 97 }, 98 want: true, 99 }, 100 { 101 name: "with message", 102 args: args{ 103 err: WithMessage(err, "test"), 104 target: new(customErr), 105 }, 106 want: true, 107 }, 108 { 109 name: "with message format", 110 args: args{ 111 err: WithMessagef(err, "%s", "test"), 112 target: new(customErr), 113 }, 114 want: true, 115 }, 116 { 117 name: "std errors compatibility", 118 args: args{ 119 err: fmt.Errorf("wrap it: %w", err), 120 target: new(customErr), 121 }, 122 want: true, 123 }, 124 } 125 for _, tt := range tests { 126 t.Run(tt.name, func(t *testing.T) { 127 if got := As(tt.args.err, tt.args.target); got != tt.want { 128 t.Errorf("As() = %v, want %v", got, tt.want) 129 } 130 131 ce := tt.args.target.(*customErr) 132 if !reflect.DeepEqual(err, *ce) { 133 t.Errorf("set target error failed, target error is %v", *ce) 134 } 135 }) 136 } 137} 138 139func TestUnwrap(t *testing.T) { 140 err := New("test") 141 142 type args struct { 143 err error 144 } 145 tests := []struct { 146 name string 147 args args 148 want error 149 }{ 150 { 151 name: "with stack", 152 args: args{err: WithStack(err)}, 153 want: err, 154 }, 155 { 156 name: "with message", 157 args: args{err: WithMessage(err, "test")}, 158 want: err, 159 }, 160 { 161 name: "with message format", 162 args: args{err: WithMessagef(err, "%s", "test")}, 163 want: err, 164 }, 165 { 166 name: "std errors compatibility", 167 args: args{err: fmt.Errorf("wrap: %w", err)}, 168 want: err, 169 }, 170 } 171 for _, tt := range tests { 172 t.Run(tt.name, func(t *testing.T) { 173 if err := Unwrap(tt.args.err); !reflect.DeepEqual(err, tt.want) { 174 t.Errorf("Unwrap() error = %v, want %v", err, tt.want) 175 } 176 }) 177 } 178} 179