src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/diag/error_test.go (about) 1 package diag 2 3 import ( 4 "errors" 5 "reflect" 6 "testing" 7 8 "github.com/google/go-cmp/cmp" 9 ) 10 11 type fooErrorTag struct{} 12 13 func (fooErrorTag) ErrorTag() string { return "foo error" } 14 15 func TestError(t *testing.T) { 16 setContextBodyMarkers(t, "<", ">") 17 setMessageMarkers(t, "{", "}") 18 19 err := &Error[fooErrorTag]{ 20 Message: "bad list", 21 Context: *contextInParen("[test]", "echo (x)"), 22 } 23 24 wantErrorString := "foo error: [test]:1:6-8: bad list" 25 if gotErrorString := err.Error(); gotErrorString != wantErrorString { 26 t.Errorf("Error() -> %q, want %q", gotErrorString, wantErrorString) 27 } 28 29 wantRanging := Ranging{From: 5, To: 8} 30 if gotRanging := err.Range(); gotRanging != wantRanging { 31 t.Errorf("Range() -> %v, want %v", gotRanging, wantRanging) 32 } 33 34 // Title() is used for Show 35 wantShow := dedent(` 36 Foo error: {bad list} 37 [test]:1:6-8: echo <(x)>`) 38 if gotShow := err.Show(""); gotShow != wantShow { 39 t.Errorf("Show() -> %q, want %q", gotShow, wantShow) 40 } 41 } 42 43 var ( 44 err1 = &Error[fooErrorTag]{ 45 Message: "bad 1", 46 Context: *contextInParen("a.elv", "echo (1)"), 47 } 48 err2 = &Error[fooErrorTag]{ 49 Message: "bad 2", 50 Context: *contextInParen("b.elv", "echo (2\n0)"), 51 } 52 ) 53 54 var multiErrorsTests = []struct { 55 name string 56 errs []*Error[fooErrorTag] 57 wantErr error 58 }{ 59 { 60 name: "no error", 61 errs: nil, 62 wantErr: nil, 63 }, 64 { 65 name: "one error", 66 errs: []*Error[fooErrorTag]{err1}, 67 wantErr: err1, 68 }, 69 { 70 name: "multiple errors", 71 errs: []*Error[fooErrorTag]{err1, err2}, 72 wantErr: multiError[fooErrorTag]{err1, err2}, 73 }, 74 } 75 76 func TestPackAndUnpackErrors(t *testing.T) { 77 for _, tc := range multiErrorsTests { 78 t.Run(tc.name, func(t *testing.T) { 79 err := PackErrors(tc.errs) 80 if !reflect.DeepEqual(err, tc.wantErr) { 81 t.Errorf("got packed error %#v, want %#v", err, tc.wantErr) 82 } 83 unpacked := UnpackErrors[fooErrorTag](err) 84 if !reflect.DeepEqual(unpacked, tc.errs) { 85 t.Errorf("Unpacked: (-want +got):\n%s", cmp.Diff(tc.errs, unpacked)) 86 } 87 }) 88 } 89 } 90 91 func TestUnpackErrors_CalledWithOtherErrorType(t *testing.T) { 92 unpacked := UnpackErrors[fooErrorTag](errors.New("foo")) 93 if unpacked != nil { 94 t.Errorf("want nil, got %v", unpacked) 95 } 96 } 97 98 func TestMultiError_ErrorAndShow(t *testing.T) { 99 setContextBodyMarkers(t, "<", ">") 100 setMessageMarkers(t, "{", "}") 101 err := PackErrors([]*Error[fooErrorTag]{err1, err2}) 102 wantError := "multiple foo errors: a.elv:1:6-8: bad 1; b.elv:1:6-2:2: bad 2" 103 if s := err.Error(); s != wantError { 104 t.Errorf(".Error() returns unexpected result (-want +got):\n%s", 105 cmp.Diff(wantError, s)) 106 } 107 wantShow := dedent(` 108 Multiple foo errors: 109 {bad 1} 110 a.elv:1:6-8: echo <(1)> 111 {bad 2} 112 b.elv:1:6-2:2: 113 echo <(2> 114 <0)>`) 115 if show := err.(Shower).Show(""); show != wantShow { 116 t.Errorf(".Show(\"\") returns unexpected result (-want +got):\n%s", 117 cmp.Diff(wantShow, show)) 118 } 119 }