github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/eval/exception_test.go (about) 1 package eval_test 2 3 import ( 4 "errors" 5 "reflect" 6 "runtime" 7 "testing" 8 "unsafe" 9 10 "github.com/markusbkk/elvish/pkg/diag" 11 . "github.com/markusbkk/elvish/pkg/eval" 12 13 . "github.com/markusbkk/elvish/pkg/eval/evaltest" 14 "github.com/markusbkk/elvish/pkg/eval/vals" 15 "github.com/markusbkk/elvish/pkg/persistent/hash" 16 "github.com/markusbkk/elvish/pkg/tt" 17 ) 18 19 func TestReason(t *testing.T) { 20 err := errors.New("ordinary error") 21 tt.Test(t, tt.Fn("Reason", Reason), tt.Table{ 22 tt.Args(err).Rets(err), 23 tt.Args(makeException(err)).Rets(err), 24 }) 25 } 26 27 func TestException(t *testing.T) { 28 err := FailError{"error"} 29 exc := makeException(err) 30 vals.TestValue(t, exc). 31 Kind("exception"). 32 Bool(false). 33 Hash(hash.Pointer(unsafe.Pointer(reflect.ValueOf(exc).Pointer()))). 34 Equal(exc). 35 NotEqual(makeException(errors.New("error"))). 36 AllKeys("reason"). 37 Index("reason", err). 38 IndexError("stack", vals.NoSuchKey("stack")). 39 Repr("[&reason=[&content=error &type=fail]]") 40 41 vals.TestValue(t, OK). 42 Kind("exception"). 43 Bool(true). 44 Repr("$ok") 45 } 46 47 func makeException(cause error, entries ...*diag.Context) Exception { 48 return NewException(cause, makeStackTrace(entries...)) 49 } 50 51 // Creates a new StackTrace, using the first entry as the head. 52 func makeStackTrace(entries ...*diag.Context) *StackTrace { 53 var s *StackTrace 54 for i := len(entries) - 1; i >= 0; i-- { 55 s = &StackTrace{Head: entries[i], Next: s} 56 } 57 return s 58 } 59 60 func TestFlow_Fields(t *testing.T) { 61 Test(t, 62 That("put ?(return)[reason][type name]").Puts("flow", "return"), 63 ) 64 } 65 66 func TestExternalCmdExit_Fields(t *testing.T) { 67 badCmd := "false" 68 if runtime.GOOS == "windows" { 69 badCmd = "cmd /c exit 1" 70 } 71 Test(t, 72 That("put ?("+badCmd+")[reason][type exit-status]"). 73 Puts("external-cmd/exited", "1"), 74 // TODO: Test killed and stopped commands 75 ) 76 } 77 78 func TestPipelineError_Fields(t *testing.T) { 79 Test(t, 80 That("put ?(fail 1 | fail 2)[reason][type]").Puts("pipeline"), 81 That("count ?(fail 1 | fail 2)[reason][exceptions]").Puts(2), 82 That("put ?(fail 1 | fail 2)[reason][exceptions][0][reason][type]"). 83 Puts("fail"), 84 ) 85 } 86 87 func TestErrorMethods(t *testing.T) { 88 tt.Test(t, tt.Fn("Error", error.Error), tt.Table{ 89 tt.Args(makeException(errors.New("err"))).Rets("err"), 90 91 tt.Args(MakePipelineError([]Exception{ 92 makeException(errors.New("err1")), 93 makeException(errors.New("err2"))})).Rets("(err1 | err2)"), 94 95 tt.Args(Return).Rets("return"), 96 tt.Args(Break).Rets("break"), 97 tt.Args(Continue).Rets("continue"), 98 tt.Args(Flow(1000)).Rets("!(BAD FLOW: 1000)"), 99 }) 100 }