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  }