github.com/zaquestion/lab@v0.25.1/internal/git/git_test.go (about) 1 package git 2 3 import ( 4 "math/rand" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "regexp" 9 "strconv" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/otiai10/copy" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestMain(m *testing.M) { 20 rand.Seed(time.Now().UnixNano()) 21 repo := copyTestRepo() 22 if err := os.Chdir(repo); err != nil { 23 log.Fatal(err) 24 } 25 26 code := m.Run() 27 28 if err := os.Chdir("../"); err != nil { 29 log.Fatalf("Error chdir to ../: %s", err) 30 } 31 if err := os.RemoveAll(repo); err != nil { 32 log.Fatalf("Error removing %s: %s", repo, err) 33 } 34 os.Exit(code) 35 } 36 37 func TestGitDir(t *testing.T) { 38 wd, err := os.Getwd() 39 if err != nil { 40 t.Fatal(err) 41 } 42 dir, err := Dir() 43 if err != nil { 44 t.Fatal(err) 45 } 46 require.Equal(t, filepath.Clean(wd+"/.git"), filepath.Clean(dir)) 47 } 48 49 func TestWorkingDir(t *testing.T) { 50 wd, err := os.Getwd() 51 if err != nil { 52 t.Fatal(err) 53 } 54 dir, err := WorkingDir() 55 if err != nil { 56 t.Fatal(err) 57 } 58 require.Equal(t, filepath.Clean(wd), filepath.Clean(dir)) 59 } 60 61 func TestCommentChar(t *testing.T) { 62 require.Equal(t, "#", CommentChar()) 63 } 64 65 func TestLastCommitMessage(t *testing.T) { 66 lcm, err := LastCommitMessage("HEAD") 67 if err != nil { 68 t.Fatal(err) 69 } 70 expectedLCM := "(ci) jobs with interleaved sleeps and prints" 71 require.Equal(t, expectedLCM, lcm) 72 } 73 74 func TestLog(t *testing.T) { 75 log, err := Log("HEAD~1", "HEAD") 76 if err != nil { 77 t.Fatal(err) 78 } 79 count := NumberCommits("HEAD~1", "HEAD") 80 expectedSHA := "09b519c" 81 expectedAuthor := "Zaq? Wiedmann" 82 expectedMessage := "(ci) jobs with interleaved sleeps and prints" 83 assert.Contains(t, log, expectedSHA) 84 assert.Contains(t, log, expectedAuthor) 85 assert.Contains(t, log, expectedMessage) 86 assert.Equal(t, 1, count) 87 } 88 89 func TestCurrentBranch(t *testing.T) { 90 branch, err := CurrentBranch() 91 if err != nil { 92 t.Fatal(err) 93 } 94 expectedBranch := "master" 95 require.Equal(t, expectedBranch, branch) 96 } 97 98 func TestPathWithNamespace(t *testing.T) { 99 tests := []struct { 100 desc string 101 remote string 102 expected string 103 expectedErr string 104 }{ 105 { 106 desc: "ssh", 107 remote: "origin", 108 expected: "zaquestion/test", 109 expectedErr: "", 110 }, 111 { 112 desc: "http", 113 remote: "origin-http", 114 expected: "zaquestion/test", 115 expectedErr: "", 116 }, 117 { 118 desc: "https", 119 remote: "origin-https", 120 expected: "zaquestion/test", 121 expectedErr: "", 122 }, 123 { 124 desc: "pushurl", 125 remote: "origin-pushurl", 126 expected: "zaquestion/test", 127 expectedErr: "", 128 }, 129 { 130 desc: "empty-pushurl", 131 remote: "origin-empty-pushurl", 132 expected: "zaquestion/test", 133 expectedErr: "", 134 }, 135 { 136 desc: "https://token@gitlab.com/org/repo", 137 remote: "origin-https-token", 138 expected: "zaquestion/test", 139 expectedErr: "", 140 }, 141 { 142 desc: "git://", 143 remote: "origin-git", 144 expected: "zaquestion/test", 145 expectedErr: "", 146 }, 147 { 148 desc: "ssh://", 149 remote: "origin-ssh-alt", 150 expected: "zaquestion/test", 151 expectedErr: "", 152 }, 153 { 154 desc: "no .git suffix", 155 remote: "origin-no_dot_git", 156 expected: "zaquestion/test", 157 expectedErr: "", 158 }, 159 { 160 desc: "subdfolders-ssh", 161 remote: "origin-subfolder-ssh", 162 expected: "zaquestion/sub/folder/test", 163 expectedErr: "", 164 }, 165 { 166 desc: "subdfolders-git", 167 remote: "origin-subfolder-git", 168 expected: "zaquestion/sub/folder/test", 169 expectedErr: "", 170 }, 171 { 172 desc: "ssh-custom-port", 173 remote: "origin-custom-port", 174 expected: "zaquestion/test", 175 expectedErr: "", 176 }, 177 { 178 desc: "ssh-subfolder-custom-port", 179 remote: "origin-subfolder-custom-port", 180 expected: "zaquestion/sub/folder/test", 181 expectedErr: "", 182 }, 183 { 184 desc: "remote doesn't exist", 185 remote: "phoney", 186 expected: "", 187 expectedErr: "the key `remote.phoney.url` is not found", 188 }, 189 { 190 desc: "invalid remote URL", 191 remote: "garbage", 192 expected: "", 193 expectedErr: "invalid remote URL format for garbage", 194 }, 195 } 196 197 for _, test := range tests { 198 test := test 199 t.Run(test.desc, func(t *testing.T) { 200 t.Parallel() 201 path, err := PathWithNamespace(test.remote) 202 if test.expectedErr != "" { 203 assert.EqualError(t, err, test.expectedErr) 204 } else { 205 assert.Nil(t, err) 206 } 207 assert.Equal(t, test.expected, path) 208 }) 209 } 210 } 211 212 func TestRepoName(t *testing.T) { 213 repo, err := RepoName() 214 if err != nil { 215 t.Fatal(err) 216 } 217 expectedRepo := "test" 218 require.Equal(t, expectedRepo, repo) 219 } 220 221 func TestIsRemote(t *testing.T) { 222 res, err := IsRemote("origin") 223 if err != nil { 224 t.Fatal(err) 225 } 226 require.True(t, res) 227 } 228 229 func TestInsideGitRepo(t *testing.T) { 230 require.True(t, InsideGitRepo()) 231 } 232 233 func TestRemotes(t *testing.T) { 234 res, err := Remotes() 235 if err != nil { 236 t.Fatal(err) 237 } 238 require.Contains(t, res, "origin", "remotes should contain 'origin' [%v]", res) 239 } 240 241 func TestRemoteBranches(t *testing.T) { 242 res, err := RemoteBranches("origin") 243 if err != nil { 244 t.Fatal(err) 245 } 246 require.Contains(t, res, "master", "remote branches should contain 'master' [%v]", res) 247 } 248 249 // Make sure the git command follow the expected behavior. 250 func TestGetLocalRemotesFromFile(t *testing.T) { 251 repo := copyTestRepo() 252 gitconfig := repo + "/.git/config" 253 254 // First get the remotes directly from file 255 cmd := exec.Command("grep", "^\\[remote.*", gitconfig) 256 cmd.Dir = repo 257 grep, err := cmd.Output() 258 if err != nil { 259 t.Log(string(grep)) 260 t.Error(err) 261 } 262 // And get the remote names 263 re := regexp.MustCompile(`\[remote\s+"(.*)".*`) 264 reMatches := re.FindAllStringSubmatch(string(grep), -1) 265 266 // Second, get result from local function 267 res, err := GetLocalRemotesFromFile() 268 if err != nil { 269 t.Log(string(res)) 270 t.Error(err) 271 } 272 remotesList := strings.Split(string(res), "\n") 273 274 // Create an array (the ordering matters) to place all unique 275 // remote names 276 var remoteNames []string 277 for _, remote := range remotesList { 278 if len(remote) == 0 { 279 continue 280 } 281 282 name := strings.Split(remote, ".")[1] 283 // Check if name is unique 284 var found bool 285 for _, placedName := range remoteNames { 286 if name == placedName { 287 found = true 288 break 289 } 290 } 291 if found { 292 continue 293 } 294 remoteNames = append(remoteNames, name) 295 } 296 297 // Check if remote exists and is in order 298 for i, match := range reMatches { 299 require.Equal(t, match[1], remoteNames[i]) 300 } 301 } 302 303 // copyTestRepo creates a copy of the testdata directory (contains a Git repo) in 304 // the project root with a random dir name. It returns the absolute path of the 305 // new testdata dir. 306 // Note: testdata-* must be in the .gitignore or the copies will create write 307 // errors as Git attempts to add the Git repo to the the project repo's index. 308 func copyTestRepo() string { 309 dst, err := filepath.Abs(os.ExpandEnv("$GOPATH/src/github.com/zaquestion/lab/testdata-" + strconv.Itoa(int(rand.Uint64())))) 310 if err != nil { 311 log.Fatal(err) 312 } 313 src, err := filepath.Abs(os.ExpandEnv("$GOPATH/src/github.com/zaquestion/lab/testdata")) 314 if err != nil { 315 log.Fatal(err) 316 } 317 if err := copy.Copy(src, dst); err != nil { 318 log.Fatal(err) 319 } 320 // Move the test.git dir into the expected path at .git 321 if err := copy.Copy(dst+"/test.git", dst+"/.git"); err != nil { 322 log.Fatal(err) 323 } 324 return dst 325 }