github.com/cilki/sh@v2.6.4+incompatible/shell/expand_test.go (about) 1 // Copyright (c) 2018, Daniel Martà <mvdan@mvdan.cc> 2 // See LICENSE for licensing information 3 4 package shell 5 6 import ( 7 "fmt" 8 "os" 9 "reflect" 10 "strings" 11 "testing" 12 ) 13 14 func strEnviron(pairs ...string) func(string) string { 15 return func(name string) string { 16 prefix := name + "=" 17 for _, pair := range pairs { 18 if val := strings.TrimPrefix(pair, prefix); val != pair { 19 return val 20 } 21 } 22 return "" 23 } 24 } 25 26 var expandTests = []struct { 27 in string 28 env func(name string) string 29 want string 30 }{ 31 {"foo", nil, "foo"}, 32 {"\nfoo\n", nil, "\nfoo\n"}, 33 {"a-$b-c", nil, "a--c"}, 34 {"${INTERP_GLOBAL:+hasOsEnv}", nil, "hasOsEnv"}, 35 {"a-$b-c", strEnviron(), "a--c"}, 36 {"a-$b-c", strEnviron("b=b_val"), "a-b_val-c"}, 37 {"${x//o/a}", strEnviron("x=foo"), "faa"}, 38 {"*.go", nil, "*.go"}, 39 {"~", nil, "~"}, 40 } 41 42 func TestExpand(t *testing.T) { 43 os.Setenv("INTERP_GLOBAL", "value") 44 for i := range expandTests { 45 t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) { 46 tc := expandTests[i] 47 t.Parallel() 48 got, err := Expand(tc.in, tc.env) 49 if err != nil { 50 t.Fatal(err) 51 } 52 if got != tc.want { 53 t.Fatalf("\nwant: %q\ngot: %q", tc.want, got) 54 } 55 }) 56 } 57 } 58 59 func TestUnexpectedCmdSubst(t *testing.T) { 60 t.Parallel() 61 want := "unexpected command substitution at 1:6" 62 for _, fn := range []func() error{ 63 func() error { 64 _, err := Expand("echo $(uname -a)", nil) 65 return err 66 }, 67 func() error { 68 _, err := Fields("echo $(uname -a)", nil) 69 return err 70 }, 71 } { 72 got := fmt.Sprint(fn()) 73 if !strings.Contains(got, want) { 74 t.Fatalf("wanted error %q, got: %s", want, got) 75 } 76 } 77 } 78 79 var fieldsTests = []struct { 80 in string 81 env func(name string) string 82 want []string 83 }{ 84 {"foo", nil, []string{"foo"}}, 85 {"\nfoo\n", nil, []string{"foo"}}, 86 {"foo bar", nil, []string{"foo", "bar"}}, 87 {"foo 'bar baz'", nil, []string{"foo", "bar baz"}}, 88 {"$x", strEnviron("x=foo bar"), []string{"foo", "bar"}}, 89 {`"$x"`, strEnviron("x=foo bar"), []string{"foo bar"}}, 90 {"~", strEnviron("HOME=/my/home"), []string{"/my/home"}}, 91 {"~/foo/bar", strEnviron("HOME=/my/home"), []string{"/my/home/foo/bar"}}, 92 {"~foo/file", strEnviron("HOME foo=/bar"), []string{"/bar/file"}}, 93 {"*.go", nil, []string{"*.go"}}, 94 } 95 96 func TestFields(t *testing.T) { 97 os.Setenv("INTERP_GLOBAL", "value") 98 for i := range fieldsTests { 99 t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) { 100 tc := fieldsTests[i] 101 t.Parallel() 102 got, err := Fields(tc.in, tc.env) 103 if err != nil { 104 t.Fatal(err) 105 } 106 if !reflect.DeepEqual(got, tc.want) { 107 t.Fatalf("\nwant: %q\ngot: %q", tc.want, got) 108 } 109 }) 110 } 111 }