github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/bobgit/status_test.go (about) 1 package bobgit 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "github.com/Benchkram/bob/bobgit/status" 10 "github.com/Benchkram/bob/pkg/cmdutil" 11 "github.com/google/go-cmp/cmp" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 var update = false 16 var debug = false 17 18 // createTestDirs structure without runnign tests. 19 // Usful to debug the created repo structure. 20 var createTestDirs = false 21 22 func TestStatus(t *testing.T) { 23 24 type input struct { 25 // environment holds a function creating 26 // the testing folder structure. 27 environment func(dir string) 28 } 29 30 type test struct { 31 // name of the test and also used 32 // for storing expected output 33 name string 34 input input 35 // execdir determines the dir in which `bob git status` is executed 36 // relative to the repo root. 37 // reporoot is used when empty. 38 execdir string 39 } 40 41 tests := []test{ 42 { 43 "status_untracked", 44 input{ 45 func(dir string) { 46 err := cmdutil.RunGit(dir, "init") 47 assert.Nil(t, err) 48 49 assert.Nil(t, os.MkdirAll(dir, 0775)) 50 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 51 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 52 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 53 54 repo := filepath.Join(dir, "repo") 55 assert.Nil(t, os.MkdirAll(repo, 0775)) 56 assert.Nil(t, cmdutil.RunGit(repo, "init")) 57 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 58 }, 59 }, 60 "", 61 }, 62 // validate output when a repo is placed in a subfolder instead of the repo root 63 { 64 "status_subfolder", 65 input{ 66 func(dir string) { 67 err := cmdutil.RunGit(dir, "init") 68 assert.Nil(t, err) 69 70 assert.Nil(t, os.MkdirAll(dir, 0775)) 71 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 72 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 73 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 74 75 repo := filepath.Join(dir, "subfolder", "repo") 76 assert.Nil(t, os.MkdirAll(repo, 0775)) 77 assert.Nil(t, cmdutil.RunGit(repo, "init")) 78 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 79 }, 80 }, 81 "", 82 }, 83 // validate vorrect display of paths in root repo (../). 84 { 85 "status_exec_from_subfolder", 86 input{ 87 func(dir string) { 88 err := cmdutil.RunGit(dir, "init") 89 assert.Nil(t, err) 90 91 assert.Nil(t, os.MkdirAll(dir, 0775)) 92 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 93 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 94 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 95 96 repo := filepath.Join(dir, "subfolder", "repo") 97 assert.Nil(t, os.MkdirAll(repo, 0775)) 98 assert.Nil(t, cmdutil.RunGit(repo, "init")) 99 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 100 }, 101 }, 102 "subfolder", 103 }, 104 { 105 "status_added", 106 input{ 107 func(dir string) { 108 err := cmdutil.RunGit(dir, "init") 109 assert.Nil(t, err) 110 111 assert.Nil(t, os.MkdirAll(dir, 0775)) 112 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 113 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 114 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 115 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 116 117 repo := filepath.Join(dir, "repo") 118 assert.Nil(t, os.MkdirAll(repo, 0775)) 119 assert.Nil(t, cmdutil.RunGit(repo, "init")) 120 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 121 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 122 }, 123 }, 124 "", 125 }, 126 { 127 "status_comitted", 128 input{ 129 func(dir string) { 130 err := cmdutil.RunGit(dir, "init") 131 assert.Nil(t, err) 132 133 assert.Nil(t, os.MkdirAll(dir, 0775)) 134 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 135 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 136 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 137 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 138 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 139 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("changedfilecontent"), 0664)) 140 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 141 142 repo := filepath.Join(dir, "repo") 143 assert.Nil(t, os.MkdirAll(repo, 0775)) 144 assert.Nil(t, cmdutil.RunGit(repo, "init")) 145 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 146 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 147 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "initialcommit")) 148 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("changedfilecontent"), 0664)) 149 }, 150 }, 151 "", 152 }, 153 { 154 "status_conflict", 155 input{ 156 func(dir string) { 157 err := cmdutil.RunGit(dir, "init") 158 assert.Nil(t, err) 159 160 assert.Nil(t, os.MkdirAll(dir, 0775)) 161 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 162 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 163 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 164 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 165 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 166 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("changedfilecontent"), 0664)) 167 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 168 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Updated content")) 169 170 assertMergeConflict(t, dir) 171 }, 172 }, 173 "", 174 }, 175 { 176 "status_conflict_multirepo", 177 input{ 178 func(dir string) { 179 err := cmdutil.RunGit(dir, "init") 180 assert.Nil(t, err) 181 182 assert.Nil(t, os.MkdirAll(dir, 0775)) 183 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 184 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 185 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 186 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 187 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 188 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("changedfilecontent"), 0664)) 189 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 190 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Updated content")) 191 192 assertMergeConflict(t, dir) 193 194 repo := filepath.Join(dir, "repo") 195 assert.Nil(t, os.MkdirAll(repo, 0775)) 196 assert.Nil(t, cmdutil.RunGit(repo, "init")) 197 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 198 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 199 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "initialcommit")) 200 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("changedfilecontent"), 0664)) 201 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 202 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "Updated content")) 203 204 assertMergeConflict(t, repo) 205 }, 206 }, 207 "", 208 }, 209 { 210 "status_conflict_delete", 211 input{ 212 func(dir string) { 213 err := cmdutil.RunGit(dir, "init") 214 assert.Nil(t, err) 215 216 assert.Nil(t, os.MkdirAll(dir, 0775)) 217 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 218 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 219 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 220 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 221 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 222 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("changedfilecontent"), 0664)) 223 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 224 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Updated content")) 225 226 assertMergeDeleteConflict(t, dir, false) 227 }, 228 }, 229 "", 230 }, 231 { 232 "status_conflict_delete_main", 233 input{ 234 func(dir string) { 235 err := cmdutil.RunGit(dir, "init") 236 assert.Nil(t, err) 237 238 assert.Nil(t, os.MkdirAll(dir, 0775)) 239 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 240 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 241 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 242 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 243 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 244 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("changedfilecontent"), 0664)) 245 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 246 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Updated content")) 247 248 assertMergeDeleteConflict(t, dir, true) 249 }, 250 }, 251 "", 252 }, 253 { 254 "status_conflict_delete_multirepo", 255 input{ 256 func(dir string) { 257 err := cmdutil.RunGit(dir, "init") 258 assert.Nil(t, err) 259 260 assert.Nil(t, os.MkdirAll(dir, 0775)) 261 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 262 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 263 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 264 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 265 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 266 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("changedfilecontent"), 0664)) 267 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 268 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Updated content")) 269 assertMergeDeleteConflict(t, dir, false) 270 271 repo := filepath.Join(dir, "repo") 272 assert.Nil(t, os.MkdirAll(repo, 0775)) 273 assert.Nil(t, cmdutil.RunGit(repo, "init")) 274 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 275 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 276 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "initialcommit")) 277 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("changedfilecontent"), 0664)) 278 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 279 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "Updated content")) 280 assertMergeDeleteConflict(t, repo, true) 281 }, 282 }, 283 "", 284 }, 285 { 286 "status_conflict_added_multirepo", 287 input{ 288 func(dir string) { 289 err := cmdutil.RunGit(dir, "init") 290 assert.Nil(t, err) 291 292 assert.Nil(t, os.MkdirAll(dir, 0775)) 293 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 294 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 295 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 296 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 297 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 298 assert.Nil(t, os.WriteFile(filepath.Join(dir, "new"), []byte("added some text to new from main"), 0664)) 299 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 300 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "new file added")) 301 assertMergeAddedConflict(t, dir) 302 303 repo := filepath.Join(dir, "repo") 304 assert.Nil(t, os.MkdirAll(repo, 0775)) 305 assert.Nil(t, cmdutil.RunGit(repo, "init")) 306 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 307 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 308 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "initialcommit")) 309 assert.Nil(t, os.WriteFile(filepath.Join(repo, "new"), []byte("added some text to new from main"), 0664)) 310 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 311 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "new file added")) 312 assertMergeAddedConflict(t, repo) 313 }, 314 }, 315 "", 316 }, 317 { 318 "status_conflict_added_by_both", 319 input{ 320 func(dir string) { 321 err := cmdutil.RunGit(dir, "init") 322 assert.Nil(t, err) 323 324 assert.Nil(t, os.MkdirAll(dir, 0775)) 325 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664)) 326 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664)) 327 assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664)) 328 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 329 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "initialcommit")) 330 assertMergeAddedByBothConflict(t, dir) 331 332 repo := filepath.Join(dir, "repo") 333 assert.Nil(t, os.MkdirAll(repo, 0775)) 334 assert.Nil(t, cmdutil.RunGit(repo, "init")) 335 assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664)) 336 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 337 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "initialcommit")) 338 assert.Nil(t, os.WriteFile(filepath.Join(repo, "new"), []byte("added some text to new from main"), 0664)) 339 assert.Nil(t, cmdutil.RunGit(repo, "add", "--all")) 340 assert.Nil(t, cmdutil.RunGit(repo, "commit", "-m", "new file added")) 341 assertMergeAddedByBothConflict(t, repo) 342 }, 343 }, 344 "", 345 }, 346 } 347 348 for _, test := range tests { 349 dir, err := ioutil.TempDir("", test.name+"-*") 350 assert.Nil(t, err) 351 352 // Don't cleanup in testdir mode 353 if !createTestDirs { 354 defer os.RemoveAll(dir) 355 } 356 357 if debug || createTestDirs { 358 println("Using test dir " + dir) 359 } 360 361 test.input.environment(dir) 362 363 if createTestDirs { 364 continue 365 } 366 367 status, err := getStatus(filepath.Join(dir, test.execdir)) 368 assert.Nil(t, err) 369 370 if update { 371 err = os.RemoveAll(filepath.Join("testdata", test.name)) 372 assert.Nil(t, err) 373 err = os.MkdirAll("testdata", 0775) 374 assert.Nil(t, err) 375 err = os.WriteFile(filepath.Join("testdata", test.name), []byte(status.String()), 0664) 376 assert.Nil(t, err) 377 continue 378 } 379 380 expect, err := os.ReadFile(filepath.Join("testdata", test.name)) 381 assert.Nil(t, err, test.name) 382 383 diff := cmp.Diff(status.String(), string(expect)) 384 assert.Equal(t, "", diff, test.name) 385 } 386 387 if createTestDirs || update { 388 t.FailNow() 389 } 390 } 391 392 // getStatus changes the current working dir before 393 // executing retireving the status. 394 func getStatus(dir string) (s *status.S, err error) { 395 wd, err := os.Getwd() 396 if err != nil { 397 return nil, err 398 } 399 err = os.Chdir(dir) 400 if err != nil { 401 return nil, err 402 } 403 defer func() { _ = os.Chdir(wd) }() 404 405 return Status() 406 } 407 408 func assertMergeConflict(t *testing.T, dir string) { 409 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "-b", "target_branch")) 410 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file content changed in target branch"), 0664)) 411 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 412 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Updated content from target branch")) 413 414 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "master")) 415 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file content changed in main branch"), 0664)) 416 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 417 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Updated content from master branch")) 418 assert.NotNil(t, cmdutil.RunGit(dir, "merge", "target_branch")) 419 } 420 421 func assertMergeDeleteConflict(t *testing.T, dir string, deletedInMain bool) { 422 commitMssg := "deleted file from target branch" 423 if deletedInMain { 424 commitMssg = "Updated content from target branch" 425 } 426 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "-b", "target_branch")) 427 if !deletedInMain { 428 assert.Nil(t, os.Remove(filepath.Join(dir, "file"))) 429 } else { 430 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file content changed in target branch"), 0664)) 431 } 432 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 433 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", commitMssg)) 434 435 commitMssg = "deleted file from master branch" 436 if deletedInMain { 437 commitMssg = "Updated content from master branch" 438 } 439 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "master")) 440 if deletedInMain { 441 assert.Nil(t, os.Remove(filepath.Join(dir, "file"))) 442 } else { 443 assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file content changed in master branch"), 0664)) 444 } 445 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 446 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", commitMssg)) 447 assert.NotNil(t, cmdutil.RunGit(dir, "merge", "target_branch")) 448 } 449 450 func assertMergeAddedConflict(t *testing.T, dir string) { 451 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "-b", "target_branch")) 452 assert.Nil(t, os.Rename(filepath.Join(dir, "new"), filepath.Join(dir, "new1"))) 453 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 454 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Renamed file from target branch")) 455 456 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "master")) 457 assert.Nil(t, os.Rename(filepath.Join(dir, "new"), filepath.Join(dir, "new2"))) 458 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 459 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "File content updated in master branch")) 460 assert.NotNil(t, cmdutil.RunGit(dir, "merge", "target_branch")) 461 } 462 463 func assertMergeAddedByBothConflict(t *testing.T, dir string) { 464 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "-b", "target_branch")) 465 assert.Nil(t, os.WriteFile(filepath.Join(dir, "new1.txt"), []byte("New file created by target branch"), 0664)) 466 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 467 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "Renamed file from target branch")) 468 469 assert.Nil(t, cmdutil.RunGit(dir, "checkout", "master")) 470 assert.Nil(t, os.WriteFile(filepath.Join(dir, "new1.txt"), []byte("New file created by master branch"), 0664)) 471 assert.Nil(t, cmdutil.RunGit(dir, "add", "--all")) 472 assert.Nil(t, cmdutil.RunGit(dir, "commit", "-m", "File content updated in master branch")) 473 assert.NotNil(t, cmdutil.RunGit(dir, "merge", "target_branch")) 474 }