src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/external_cmd_unix_internal_test.go (about) 1 //go:build unix 2 3 package eval 4 5 import ( 6 "os" 7 "reflect" 8 "syscall" 9 "testing" 10 11 "src.elv.sh/pkg/env" 12 "src.elv.sh/pkg/parse" 13 "src.elv.sh/pkg/testutil" 14 ) 15 16 func TestExec_Argv0Argv(t *testing.T) { 17 dir := testutil.InTempDir(t) 18 testutil.ApplyDir(testutil.Dir{ 19 "bin": testutil.Dir{ 20 "elvish": testutil.File{Perm: 0755}, 21 "cat": testutil.File{Perm: 0755}, 22 }, 23 }) 24 25 testutil.Setenv(t, "PATH", dir+"/bin") 26 testutil.Setenv(t, env.SHLVL, "1") 27 28 var tests = []struct { 29 name string 30 code string 31 wantArgv0 string 32 wantArgv []string 33 wantError bool 34 }{ 35 { 36 name: "absolute path command", 37 code: "exec /bin/sh foo bar", 38 wantArgv0: "/bin/sh", 39 wantArgv: []string{"/bin/sh", "foo", "bar"}, 40 }, 41 { 42 name: "relative path command", 43 code: "exec cat foo bar", 44 wantArgv0: dir + "/bin/cat", 45 wantArgv: []string{dir + "/bin/cat", "foo", "bar"}, 46 }, 47 { 48 name: "no command", 49 code: "exec", 50 wantArgv0: dir + "/bin/elvish", 51 wantArgv: []string{dir + "/bin/elvish"}, 52 }, 53 { 54 name: "bad command", 55 code: "exec bad", 56 wantError: true, 57 }, 58 } 59 60 for _, test := range tests { 61 t.Run(test.name, func(t *testing.T) { 62 t.Helper() 63 var ( 64 gotArgv0 string 65 gotArgv []string 66 ) 67 syscallExec = func(argv0 string, argv []string, envv []string) error { 68 gotArgv0 = argv0 69 gotArgv = argv 70 return nil 71 } 72 defer func() { syscallExec = syscall.Exec }() 73 74 ev := NewEvaler() 75 err := ev.Eval(parse.Source{Name: "[test]", Code: test.code}, EvalCfg{}) 76 77 if gotArgv0 != test.wantArgv0 { 78 t.Errorf("got argv0 %q, want %q", gotArgv0, test.wantArgv0) 79 } 80 if !reflect.DeepEqual(gotArgv, test.wantArgv) { 81 t.Errorf("got argv %q, want %q", gotArgv, test.wantArgv) 82 } 83 hasError := err != nil 84 if hasError != test.wantError { 85 t.Errorf("has error %v, want %v", hasError, test.wantError) 86 } 87 }) 88 } 89 } 90 91 func TestDecSHLVL(t *testing.T) { 92 // Valid integers are decremented, regardless of sign 93 testDecSHLVL(t, "-2", "-3") 94 testDecSHLVL(t, "-1", "-2") 95 testDecSHLVL(t, "0", "-1") 96 testDecSHLVL(t, "1", "0") 97 testDecSHLVL(t, "2", "1") 98 testDecSHLVL(t, "3", "2") 99 100 // Non-integers are kept unchanged 101 testDecSHLVL(t, "", "") 102 testDecSHLVL(t, "x", "x") 103 } 104 105 func testDecSHLVL(t *testing.T, oldValue, newValue string) { 106 t.Helper() 107 testutil.Setenv(t, env.SHLVL, oldValue) 108 109 decSHLVL() 110 if gotValue := os.Getenv(env.SHLVL); gotValue != newValue { 111 t.Errorf("got new value %q, want %q", gotValue, newValue) 112 } 113 }