gitlab.com/zaquestion/lab@v0.14.0/cmd/root_test.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "log" 8 "math/rand" 9 "os" 10 "os/exec" 11 "path" 12 "path/filepath" 13 "strconv" 14 "strings" 15 "testing" 16 "time" 17 18 "github.com/spf13/viper" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 "github.com/zaquestion/lab/internal/git" 22 lab "github.com/zaquestion/lab/internal/gitlab" 23 ) 24 25 func TestMain(m *testing.M) { 26 wd, err := git.WorkingDir() 27 if err != nil { 28 log.Fatal(err) 29 } 30 os.Chdir(wd) 31 err = exec.Command("go", "test", "-c", "-coverpkg", "./...", "-covermode", "count", "-o", "lab_bin").Run() 32 if err != nil { 33 log.Fatal(err) 34 } 35 rand.Seed(time.Now().UnixNano()) 36 37 // Load config for non-testbinary based tests 38 os.Chdir(path.Join(wd, "testdata")) 39 viper.SetConfigName("lab") 40 viper.SetConfigType("hcl") 41 viper.AddConfigPath(".") 42 err = viper.ReadInConfig() 43 if err != nil { 44 log.Fatal(err) 45 } 46 c := viper.AllSettings()["core"] 47 config := c.([]map[string]interface{})[0] 48 lab.Init( 49 config["host"].(string), 50 config["user"].(string), 51 config["token"].(string)) 52 53 code := m.Run() 54 os.Chdir(wd) 55 os.Remove("lab_bin") 56 testdirs, err := filepath.Glob("testdata-*") 57 if err != nil { 58 log.Fatal(err) 59 } 60 for _, dir := range testdirs { 61 err := os.RemoveAll(dir) 62 if err != nil { 63 log.Fatal(err) 64 } 65 } 66 67 os.Exit(code) 68 } 69 70 func copyTestRepo(t *testing.T) string { 71 dir := "../testdata-" + strconv.Itoa(int(rand.Uint64())) 72 t.Log(dir) 73 err := exec.Command("cp", "-r", "../testdata", dir).Run() 74 if err != nil { 75 t.Fatal(err) 76 } 77 wd, err := os.Getwd() 78 if err != nil { 79 t.Fatal(err) 80 } 81 dir = path.Join(wd, dir) 82 return dir 83 } 84 85 func TestRootCloneNoArg(t *testing.T) { 86 cmd := exec.Command("../lab_bin", "clone") 87 b, _ := cmd.CombinedOutput() 88 require.Contains(t, string(b), "You must specify a repository to clone.") 89 } 90 91 func TestRootGitCmd(t *testing.T) { 92 cmd := exec.Command("../lab_bin", "log", "-n", "1") 93 b, _ := cmd.CombinedOutput() 94 require.Contains(t, string(b), `commit 09b519cba018b707c98fc56e37df15806d89d866 95 Author: Zaq? Wiedmann <zaquestion@gmail.com> 96 Date: Sun Apr 1 19:40:47 2018 -0700 97 98 (ci) jobs with interleaved sleeps and prints`) 99 } 100 101 func TestRootNoArg(t *testing.T) { 102 cmd := exec.Command("../lab_bin") 103 b, _ := cmd.CombinedOutput() 104 assert.Contains(t, string(b), "usage: git [--version] [--help] [-C <path>]") 105 assert.Contains(t, string(b), `These GitLab commands are provided by lab: 106 107 ci Work with GitLab CI pipelines and jobs`) 108 } 109 110 func TestRootVersion(t *testing.T) { 111 old := os.Stdout // keep backup of the real stdout 112 r, w, _ := os.Pipe() 113 os.Stdout = w 114 115 RootCmd.Flag("version").Value.Set("true") 116 RootCmd.Run(RootCmd, nil) 117 118 outC := make(chan string) 119 // copy the output in a separate goroutine so printing can't block indefinitely 120 go func() { 121 var buf bytes.Buffer 122 io.Copy(&buf, r) 123 outC <- buf.String() 124 }() 125 126 // back to normal state 127 w.Close() 128 os.Stdout = old // restoring the real stdout 129 out := <-outC 130 131 assert.Contains(t, out, "git version") 132 assert.Contains(t, out, fmt.Sprintf("lab version %s", Version)) 133 } 134 135 func TestGitHelp(t *testing.T) { 136 cmd := exec.Command("../lab_bin") 137 b, _ := cmd.CombinedOutput() 138 expected := string(b) 139 expected = expected[:strings.LastIndex(strings.TrimSpace(expected), "\n")] 140 141 tests := []struct { 142 desc string 143 Cmds []string 144 }{ 145 { 146 desc: "help arg", 147 Cmds: []string{"help"}, 148 }, 149 { 150 desc: "no arg", 151 Cmds: []string{}, 152 }, 153 } 154 155 for _, test := range tests { 156 t.Run(test.desc, func(t *testing.T) { 157 cmd := exec.Command("../lab_bin") 158 if len(test.Cmds) >= 1 { 159 cmd = exec.Command("../lab_bin", test.Cmds...) 160 } 161 b, _ := cmd.CombinedOutput() 162 res := string(b) 163 res = res[:strings.LastIndex(strings.TrimSpace(res), "\n")] 164 t.Log(expected) 165 t.Log(res) 166 assert.Equal(t, expected, res) 167 assert.Contains(t, res, "usage: git [--version] [--help] [-C <path>]") 168 assert.Contains(t, res, `These GitLab commands are provided by lab: 169 170 ci Work with GitLab CI pipelines and jobs`) 171 }) 172 } 173 } 174 175 func Test_parseArgsStr(t *testing.T) { 176 tests := []struct { 177 Name string 178 Args []string 179 ExpectedString string 180 ExpectedInt int64 181 ExpectedErr string 182 }{ 183 { 184 Name: "No Args", 185 Args: nil, 186 ExpectedString: "", 187 ExpectedInt: 0, 188 ExpectedErr: "", 189 }, 190 { 191 Name: "1 arg remote", 192 Args: []string{"origin"}, 193 ExpectedString: "origin", 194 ExpectedInt: 0, 195 ExpectedErr: "", 196 }, 197 { 198 Name: "1 arg non remote", 199 Args: []string{"foo"}, 200 ExpectedString: "foo", 201 ExpectedInt: 0, 202 ExpectedErr: "", 203 }, 204 { 205 Name: "1 arg page", 206 Args: []string{"100"}, 207 ExpectedString: "", 208 ExpectedInt: 100, 209 ExpectedErr: "", 210 }, 211 { 212 Name: "1 arg invalid page", 213 Args: []string{"asdf100"}, 214 ExpectedString: "asdf100", 215 ExpectedInt: 0, 216 ExpectedErr: "", 217 }, 218 { 219 Name: "2 arg str page", 220 Args: []string{"origin", "100"}, 221 ExpectedString: "origin", 222 ExpectedInt: 100, 223 ExpectedErr: "", 224 }, 225 { 226 Name: "2 arg valid str valid page", 227 Args: []string{"foo", "100"}, 228 ExpectedString: "foo", 229 ExpectedInt: 100, 230 ExpectedErr: "", 231 }, 232 { 233 Name: "2 arg valid str invalid page", 234 Args: []string{"foo", "asdf100"}, 235 ExpectedString: "foo", 236 ExpectedInt: 0, 237 ExpectedErr: "strconv.ParseInt: parsing \"asdf100\": invalid syntax", 238 }, 239 } 240 for _, test := range tests { 241 t.Run(test.Name, func(t *testing.T) { 242 test := test 243 t.Parallel() 244 s, i, err := parseArgsStr(test.Args) 245 if err != nil { 246 assert.EqualError(t, err, test.ExpectedErr) 247 } 248 assert.Equal(t, test.ExpectedString, s) 249 assert.Equal(t, test.ExpectedInt, i) 250 }) 251 } 252 } 253 254 func Test_parseArgs(t *testing.T) { 255 tests := []struct { 256 Name string 257 Args []string 258 ExpectedString string 259 ExpectedInt int64 260 ExpectedErr string 261 }{ 262 { 263 Name: "No Args", 264 Args: nil, 265 ExpectedString: "zaquestion/test", 266 ExpectedInt: 0, 267 ExpectedErr: "", 268 }, 269 { 270 Name: "1 arg remote", 271 Args: []string{"lab-testing"}, 272 ExpectedString: "lab-testing/test", 273 ExpectedInt: 0, 274 ExpectedErr: "", 275 }, 276 { 277 Name: "1 arg non remote", 278 Args: []string{"foo"}, 279 ExpectedString: "", 280 ExpectedInt: 0, 281 ExpectedErr: "foo is not a valid remote or number", 282 }, 283 { 284 Name: "1 arg page", 285 Args: []string{"100"}, 286 ExpectedString: "zaquestion/test", 287 ExpectedInt: 100, 288 ExpectedErr: "", 289 }, 290 { 291 Name: "1 arg invalid page", 292 Args: []string{"asdf100"}, 293 ExpectedString: "", 294 ExpectedInt: 0, 295 ExpectedErr: "asdf100 is not a valid remote or number", 296 }, 297 { 298 Name: "2 arg remote page", 299 Args: []string{"origin", "100"}, 300 ExpectedString: "zaquestion/test", 301 ExpectedInt: 100, 302 ExpectedErr: "", 303 }, 304 { 305 Name: "2 arg invalid remote valid page", 306 Args: []string{"foo", "100"}, 307 ExpectedString: "", 308 ExpectedInt: 0, 309 ExpectedErr: "foo is not a valid remote", 310 }, 311 { 312 Name: "2 arg invalid remote invalid page", 313 Args: []string{"foo", "asdf100"}, 314 ExpectedString: "", 315 ExpectedInt: 0, 316 ExpectedErr: "strconv.ParseInt: parsing \"asdf100\": invalid syntax", 317 }, 318 } 319 for _, test := range tests { 320 t.Run(test.Name, func(t *testing.T) { 321 test := test 322 t.Parallel() 323 s, i, err := parseArgs(test.Args) 324 if err != nil { 325 assert.EqualError(t, err, test.ExpectedErr) 326 } 327 assert.Equal(t, test.ExpectedString, s) 328 assert.Equal(t, test.ExpectedInt, i) 329 }) 330 } 331 }