github.com/secman-team/gh-api@v1.8.2/pkg/cmd/alias/set/set_test.go (about)

     1  package set
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"testing"
     7  
     8  	"github.com/MakeNowJust/heredoc"
     9  	"github.com/secman-team/gh-api/core/config"
    10  	"github.com/secman-team/gh-api/pkg/cmdutil"
    11  	"github.com/secman-team/gh-api/pkg/iostreams"
    12  	"github.com/secman-team/gh-api/test"
    13  	"github.com/google/shlex"
    14  	"github.com/spf13/cobra"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func runCommand(cfg config.Config, isTTY bool, cli string) (*test.CmdOut, error) {
    20  	io, _, stdout, stderr := iostreams.Test()
    21  	io.SetStdoutTTY(isTTY)
    22  	io.SetStdinTTY(isTTY)
    23  	io.SetStderrTTY(isTTY)
    24  
    25  	factory := &cmdutil.Factory{
    26  		IOStreams: io,
    27  		Config: func() (config.Config, error) {
    28  			return cfg, nil
    29  		},
    30  	}
    31  
    32  	cmd := NewCmdSet(factory, nil)
    33  
    34  	// fake command nesting structure needed for validCommand
    35  	rootCmd := &cobra.Command{}
    36  	rootCmd.AddCommand(cmd)
    37  	prCmd := &cobra.Command{Use: "pr"}
    38  	prCmd.AddCommand(&cobra.Command{Use: "checkout"})
    39  	prCmd.AddCommand(&cobra.Command{Use: "status"})
    40  	rootCmd.AddCommand(prCmd)
    41  	issueCmd := &cobra.Command{Use: "issue"}
    42  	issueCmd.AddCommand(&cobra.Command{Use: "list"})
    43  	rootCmd.AddCommand(issueCmd)
    44  
    45  	argv, err := shlex.Split("set " + cli)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	rootCmd.SetArgs(argv)
    50  
    51  	rootCmd.SetIn(&bytes.Buffer{})
    52  	rootCmd.SetOut(ioutil.Discard)
    53  	rootCmd.SetErr(ioutil.Discard)
    54  
    55  	_, err = rootCmd.ExecuteC()
    56  	return &test.CmdOut{
    57  		OutBuf: stdout,
    58  		ErrBuf: stderr,
    59  	}, err
    60  }
    61  
    62  func TestAliasSet_gh_command(t *testing.T) {
    63  	defer config.StubWriteConfig(ioutil.Discard, ioutil.Discard)()
    64  
    65  	cfg := config.NewFromString(``)
    66  
    67  	_, err := runCommand(cfg, true, "pr 'pr status'")
    68  	assert.EqualError(t, err, `could not create alias: "pr" is already a gh command`)
    69  }
    70  
    71  func TestAliasSet_empty_aliases(t *testing.T) {
    72  	mainBuf := bytes.Buffer{}
    73  	defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
    74  
    75  	cfg := config.NewFromString(heredoc.Doc(`
    76  		aliases:
    77  		editor: vim
    78  	`))
    79  
    80  	output, err := runCommand(cfg, true, "co 'pr checkout'")
    81  
    82  	if err != nil {
    83  		t.Fatalf("unexpected error: %s", err)
    84  	}
    85  
    86  	//nolint:staticcheck // prefer exact matchers over ExpectLines
    87  	test.ExpectLines(t, output.Stderr(), "Added alias")
    88  	//nolint:staticcheck // prefer exact matchers over ExpectLines
    89  	test.ExpectLines(t, output.String(), "")
    90  
    91  	expected := `aliases:
    92      co: pr checkout
    93  editor: vim
    94  `
    95  	assert.Equal(t, expected, mainBuf.String())
    96  }
    97  
    98  func TestAliasSet_existing_alias(t *testing.T) {
    99  	mainBuf := bytes.Buffer{}
   100  	defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
   101  
   102  	cfg := config.NewFromString(heredoc.Doc(`
   103  		aliases:
   104  		  co: pr checkout
   105  	`))
   106  
   107  	output, err := runCommand(cfg, true, "co 'pr checkout -Rcool/repo'")
   108  	require.NoError(t, err)
   109  
   110  	//nolint:staticcheck // prefer exact matchers over ExpectLines
   111  	test.ExpectLines(t, output.Stderr(), "Changed alias.*co.*from.*pr checkout.*to.*pr checkout -Rcool/repo")
   112  }
   113  
   114  func TestAliasSet_space_args(t *testing.T) {
   115  	mainBuf := bytes.Buffer{}
   116  	defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
   117  
   118  	cfg := config.NewFromString(``)
   119  
   120  	output, err := runCommand(cfg, true, `il 'issue list -l "cool story"'`)
   121  	require.NoError(t, err)
   122  
   123  	//nolint:staticcheck // prefer exact matchers over ExpectLines
   124  	test.ExpectLines(t, output.Stderr(), `Adding alias for.*il.*issue list -l "cool story"`)
   125  
   126  	//nolint:staticcheck // prefer exact matchers over ExpectLines
   127  	test.ExpectLines(t, mainBuf.String(), `il: issue list -l "cool story"`)
   128  }
   129  
   130  func TestAliasSet_arg_processing(t *testing.T) {
   131  	cases := []struct {
   132  		Cmd                string
   133  		ExpectedOutputLine string
   134  		ExpectedConfigLine string
   135  	}{
   136  		{`il "issue list"`, "- Adding alias for.*il.*issue list", "il: issue list"},
   137  
   138  		{`iz 'issue list'`, "- Adding alias for.*iz.*issue list", "iz: issue list"},
   139  
   140  		{`ii 'issue list --author="$1" --label="$2"'`,
   141  			`- Adding alias for.*ii.*issue list --author="\$1" --label="\$2"`,
   142  			`ii: issue list --author="\$1" --label="\$2"`},
   143  
   144  		{`ix "issue list --author='\$1' --label='\$2'"`,
   145  			`- Adding alias for.*ix.*issue list --author='\$1' --label='\$2'`,
   146  			`ix: issue list --author='\$1' --label='\$2'`},
   147  	}
   148  
   149  	for _, c := range cases {
   150  		t.Run(c.Cmd, func(t *testing.T) {
   151  			mainBuf := bytes.Buffer{}
   152  			defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
   153  
   154  			cfg := config.NewFromString(``)
   155  
   156  			output, err := runCommand(cfg, true, c.Cmd)
   157  			if err != nil {
   158  				t.Fatalf("got unexpected error running %s: %s", c.Cmd, err)
   159  			}
   160  
   161  			//nolint:staticcheck // prefer exact matchers over ExpectLines
   162  			test.ExpectLines(t, output.Stderr(), c.ExpectedOutputLine)
   163  			//nolint:staticcheck // prefer exact matchers over ExpectLines
   164  			test.ExpectLines(t, mainBuf.String(), c.ExpectedConfigLine)
   165  		})
   166  	}
   167  }
   168  
   169  func TestAliasSet_init_alias_cfg(t *testing.T) {
   170  	mainBuf := bytes.Buffer{}
   171  	defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
   172  
   173  	cfg := config.NewFromString(heredoc.Doc(`
   174  		editor: vim
   175  	`))
   176  
   177  	output, err := runCommand(cfg, true, "diff 'pr diff'")
   178  	require.NoError(t, err)
   179  
   180  	expected := `editor: vim
   181  aliases:
   182      diff: pr diff
   183  `
   184  
   185  	//nolint:staticcheck // prefer exact matchers over ExpectLines
   186  	test.ExpectLines(t, output.Stderr(), "Adding alias for.*diff.*pr diff", "Added alias.")
   187  	assert.Equal(t, expected, mainBuf.String())
   188  }
   189  
   190  func TestAliasSet_existing_aliases(t *testing.T) {
   191  	mainBuf := bytes.Buffer{}
   192  	defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
   193  
   194  	cfg := config.NewFromString(heredoc.Doc(`
   195  		aliases:
   196  		  foo: bar
   197  	`))
   198  
   199  	output, err := runCommand(cfg, true, "view 'pr view'")
   200  	require.NoError(t, err)
   201  
   202  	expected := `aliases:
   203      foo: bar
   204      view: pr view
   205  `
   206  
   207  	//nolint:staticcheck // prefer exact matchers over ExpectLines
   208  	test.ExpectLines(t, output.Stderr(), "Adding alias for.*view.*pr view", "Added alias.")
   209  	assert.Equal(t, expected, mainBuf.String())
   210  
   211  }
   212  
   213  func TestAliasSet_invalid_command(t *testing.T) {
   214  	defer config.StubWriteConfig(ioutil.Discard, ioutil.Discard)()
   215  
   216  	cfg := config.NewFromString(``)
   217  
   218  	_, err := runCommand(cfg, true, "co 'pe checkout'")
   219  	assert.EqualError(t, err, "could not create alias: pe checkout does not correspond to a gh command")
   220  }
   221  
   222  func TestShellAlias_flag(t *testing.T) {
   223  	mainBuf := bytes.Buffer{}
   224  	defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
   225  
   226  	cfg := config.NewFromString(``)
   227  
   228  	output, err := runCommand(cfg, true, "--shell igrep 'gh issue list | grep'")
   229  	if err != nil {
   230  		t.Fatalf("unexpected error: %s", err)
   231  	}
   232  
   233  	//nolint:staticcheck // prefer exact matchers over ExpectLines
   234  	test.ExpectLines(t, output.Stderr(), "Adding alias for.*igrep")
   235  
   236  	expected := `aliases:
   237      igrep: '!gh issue list | grep'
   238  `
   239  	assert.Equal(t, expected, mainBuf.String())
   240  }
   241  
   242  func TestShellAlias_bang(t *testing.T) {
   243  	mainBuf := bytes.Buffer{}
   244  	defer config.StubWriteConfig(&mainBuf, ioutil.Discard)()
   245  
   246  	cfg := config.NewFromString(``)
   247  
   248  	output, err := runCommand(cfg, true, "igrep '!gh issue list | grep'")
   249  	require.NoError(t, err)
   250  
   251  	//nolint:staticcheck // prefer exact matchers over ExpectLines
   252  	test.ExpectLines(t, output.Stderr(), "Adding alias for.*igrep")
   253  
   254  	expected := `aliases:
   255      igrep: '!gh issue list | grep'
   256  `
   257  	assert.Equal(t, expected, mainBuf.String())
   258  }