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 }