diff --git a/commands/common_utils_test.go b/commands/common_utils_test.go new file mode 100644 index 0000000..706c5c5 --- /dev/null +++ b/commands/common_utils_test.go @@ -0,0 +1,138 @@ +package commands + +import ( + "fmt" + "os" + + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/osfs" + "github.com/go-git/go-git/v5" + gitcfg "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing/cache" + "github.com/go-git/go-git/v5/storage/filesystem" + "gitlab.com/revalus/grm/config" +) + +type TestDir struct { + rootFS billy.Filesystem + baseRepository struct { + fileSystem billy.Filesystem + repo *git.Repository + } +} + +func checkErrorDuringPreparation(err error) { + if err != nil { + fmt.Printf("Cannot prepare a temporary directory for testing! %v ", err.Error()) + os.Exit(2) + } +} + +func createTmpDir() string { + + baseForTMPDir := fmt.Sprintf("%v/grmTest", os.TempDir()) + if _, ok := os.Stat(baseForTMPDir); ok != nil { + err := os.Mkdir(baseForTMPDir, 0777) + checkErrorDuringPreparation(err) + } + + tempDir, err := os.MkdirTemp(baseForTMPDir, "*") + checkErrorDuringPreparation(err) + + return tempDir +} + +func getTestDirForTests() TestDir { + + tmpDir := createTmpDir() + + baseFileSystem := osfs.New(tmpDir) + + initRepositoryFileSystem, err := baseFileSystem.Chroot("worktree") + checkErrorDuringPreparation(err) + + directoryForGitMetadata, err := initRepositoryFileSystem.Chroot(".git") + checkErrorDuringPreparation(err) + + repository, err := git.Init(filesystem.NewStorage(directoryForGitMetadata, cache.NewObjectLRUDefault()), initRepositoryFileSystem) + checkErrorDuringPreparation(err) + + fileForFirstCommit, err := initRepositoryFileSystem.Create("TestFile.txt") + checkErrorDuringPreparation(err) + + _, err = fileForFirstCommit.Write([]byte("foo-conent")) + checkErrorDuringPreparation(err) + + repositoryWorkTree, err := repository.Worktree() + checkErrorDuringPreparation(err) + + repositoryWorkTree.Add(fileForFirstCommit.Name()) + _, err = repositoryWorkTree.Commit("First commit", &git.CommitOptions{}) + + checkErrorDuringPreparation(err) + + return TestDir{ + baseRepository: struct { + fileSystem billy.Filesystem + repo *git.Repository + }{ + fileSystem: initRepositoryFileSystem, + repo: repository, + }, + rootFS: baseFileSystem, + } + +} + +func makeCommit(wk *git.Worktree, commitMessage string) { + + _, err := wk.Commit(commitMessage, &git.CommitOptions{}) + checkErrorDuringPreparation(err) + +} + +func getFSForLocalRepo(dirName string, baseFileSystem billy.Filesystem) (billy.Filesystem, *filesystem.Storage) { + fsForLocalRepo, err := baseFileSystem.Chroot(dirName) + checkErrorDuringPreparation(err) + fsForMetadata, err := fsForLocalRepo.Chroot(".git") + checkErrorDuringPreparation(err) + storageForTestRepo := filesystem.NewStorage(fsForMetadata, cache.NewObjectLRUDefault()) + return fsForLocalRepo, storageForTestRepo +} + +func getBaseForTestingSyncCommand() (StatusChecker, *git.Repository, config.RepositoryConfig, TestDir) { + tmpDirWithInitialRepository := getTestDirForTests() + dirNameForLocalRepository := "testRepo" + fsForLocalRepo, storageForTestRepo := getFSForLocalRepo(dirNameForLocalRepository, tmpDirWithInitialRepository.rootFS) + + fakeLocalRepository, err := git.Clone(storageForTestRepo, fsForLocalRepo, &git.CloneOptions{ + URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), + }) + checkErrorDuringPreparation(err) + + sc := StatusChecker{ + workspace: tmpDirWithInitialRepository.rootFS.Root(), + } + + repoCfg := config.RepositoryConfig{ + Name: "test", + Src: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), + Dest: dirNameForLocalRepository, + } + + return sc, fakeLocalRepository, repoCfg, tmpDirWithInitialRepository +} + +func getBaseForTestingSyncMultipleRemote() (StatusChecker, *git.Repository, config.RepositoryConfig) { + sc, fakeLocalRepository, repoCfg, tmpDirWithInitialRepository := getBaseForTestingSyncCommand() + + fakeLocalRepository.CreateRemote(&gitcfg.RemoteConfig{ + Name: "subremote", + URLs: []string{tmpDirWithInitialRepository.baseRepository.fileSystem.Root()}, + }) + + fakeLocalRepository.Fetch(&git.FetchOptions{ + RemoteName: "subremote", + }) + return sc, fakeLocalRepository, repoCfg +} diff --git a/commands/status_cmd_test.go b/commands/status_cmd_test.go index c362014..746f5bf 100644 --- a/commands/status_cmd_test.go +++ b/commands/status_cmd_test.go @@ -2,119 +2,37 @@ package commands import ( "fmt" - "os" "testing" - "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/memfs" - "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5" - gitcfg "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/cache" - "github.com/go-git/go-git/v5/storage/filesystem" "github.com/go-git/go-git/v5/storage/memory" "gitlab.com/revalus/grm/config" ) -type TestDir struct { - rootFS billy.Filesystem - baseRepository struct { - fileSystem billy.Filesystem - repo *git.Repository - } -} - -func getTestDirForTests() TestDir { - - checkError := func(err error) { - if err != nil { - fmt.Printf("During preparing repositories, an error occurred: %v\n", err) - os.Exit(4) - } - } - - baseTMPPath := fmt.Sprintf("%v/grmTest", os.TempDir()) - if _, ok := os.Stat(baseTMPPath); ok != nil { - err := os.Mkdir(baseTMPPath, 0777) - checkError(err) - } - - tmpDir, err := os.MkdirTemp(baseTMPPath, "*") - checkError(err) - - baseFileSystem := osfs.New(tmpDir) - - initRepositoryFileSystem, err := baseFileSystem.Chroot("worktree") - checkError(err) - - directoryForGitMetadata, err := initRepositoryFileSystem.Chroot(".git") - checkError(err) - - repository, err := git.Init(filesystem.NewStorage(directoryForGitMetadata, cache.NewObjectLRUDefault()), initRepositoryFileSystem) - checkError(err) - - fileForFirstCommit, err := initRepositoryFileSystem.Create("TestFile.txt") - checkError(err) - - _, err = fileForFirstCommit.Write([]byte("foo-conent")) - checkError(err) - - repositoryWorkTree, err := repository.Worktree() - checkError(err) - - repositoryWorkTree.Add(fileForFirstCommit.Name()) - _, err = repositoryWorkTree.Commit("First commit", &git.CommitOptions{}) - - checkError(err) - - return TestDir{ - baseRepository: struct { - fileSystem billy.Filesystem - repo *git.Repository - }{ - fileSystem: initRepositoryFileSystem, - repo: repository, - }, - rootFS: baseFileSystem, - } - -} - -func unexpectedError(err error, t *testing.T) { - if err != nil { - t.Errorf("Unexpected error %v", err) - } -} - -func makeCommit(wk *git.Worktree, commitMessage string, fileName string) error { - - wk.Commit(commitMessage, &git.CommitOptions{}) - return nil -} - func TestIfBranchesAreEqual(t *testing.T) { tmpDirWithInitialRepository := getTestDirForTests() fakeLocalRepo, err := git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{ URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), }) - unexpectedError(err, t) + checkErrorDuringPreparation(err) currentReference, err := fakeLocalRepo.Head() - unexpectedError(err, t) + checkErrorDuringPreparation(err) remote, err := fakeLocalRepo.Remote("origin") - unexpectedError(err, t) + checkErrorDuringPreparation(err) remoteRevision, err := fakeLocalRepo.ResolveRevision(plumbing.Revision(fmt.Sprintf("%v/%v", remote.Config().Name, currentReference.Name().Short()))) - unexpectedError(err, t) + checkErrorDuringPreparation(err) currentBranchCommit, err := fakeLocalRepo.CommitObject(currentReference.Hash()) - unexpectedError(err, t) + checkErrorDuringPreparation(err) remoteBranchCommit, err := fakeLocalRepo.CommitObject(*remoteRevision) - unexpectedError(err, t) + checkErrorDuringPreparation(err) result := findNumberOfCommitDiffs(currentBranchCommit, remoteBranchCommit) if result != 0 { @@ -122,35 +40,33 @@ func TestIfBranchesAreEqual(t *testing.T) { } } -func TestIfCurrentBranchIsAbove(t *testing.T) { +func TestIfCurrentBranchIsDifferent(t *testing.T) { tmpDirWithInitialRepository := getTestDirForTests() - tmpFileSystemForLocalRepository := memfs.New() - fakeLocalRepo, err := git.Clone(memory.NewStorage(), tmpFileSystemForLocalRepository, &git.CloneOptions{ + fakeLocalRepo, err := git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{ URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), }) - unexpectedError(err, t) + checkErrorDuringPreparation(err) localWorktree, err := fakeLocalRepo.Worktree() - unexpectedError(err, t) + checkErrorDuringPreparation(err) - err = makeCommit(localWorktree, "commit 1", "Commit1") - unexpectedError(err, t) + makeCommit(localWorktree, "commit 1") localReference, err := fakeLocalRepo.Head() - unexpectedError(err, t) + checkErrorDuringPreparation(err) remoteConnection, err := fakeLocalRepo.Remote("origin") - unexpectedError(err, t) + checkErrorDuringPreparation(err) remoteRevision, err := fakeLocalRepo.ResolveRevision(plumbing.Revision(fmt.Sprintf("%v/%v", remoteConnection.Config().Name, localReference.Name().Short()))) - unexpectedError(err, t) + checkErrorDuringPreparation(err) currentBranchCommit, err := fakeLocalRepo.CommitObject(localReference.Hash()) - unexpectedError(err, t) + checkErrorDuringPreparation(err) remoteBranchCommit, err := fakeLocalRepo.CommitObject(*remoteRevision) - unexpectedError(err, t) + checkErrorDuringPreparation(err) result := findNumberOfCommitDiffs(currentBranchCommit, remoteBranchCommit) if result != 1 { @@ -158,15 +74,14 @@ func TestIfCurrentBranchIsAbove(t *testing.T) { } for i := 1; i < 15; i++ { - err = makeCommit(localWorktree, fmt.Sprintf("Commit +%v", i), fmt.Sprintf("Commit%v", i)) - unexpectedError(err, t) + makeCommit(localWorktree, fmt.Sprintf("Commit +%v", i)) } localReference, err = fakeLocalRepo.Head() - unexpectedError(err, t) + checkErrorDuringPreparation(err) currentBranchCommit, err = fakeLocalRepo.CommitObject(localReference.Hash()) - unexpectedError(err, t) + checkErrorDuringPreparation(err) result = findNumberOfCommitDiffs(currentBranchCommit, remoteBranchCommit) if result != 15 { @@ -177,18 +92,12 @@ func TestIfCurrentBranchIsAbove(t *testing.T) { func TestCommandRepositoryDoesNotExists(t *testing.T) { tmpDirWithInitialRepository := getTestDirForTests() + fsForLocalRepo, storageForTestRepo := getFSForLocalRepo("noMatterValue", tmpDirWithInitialRepository.rootFS) - fileSystemForLocalRepo, err := tmpDirWithInitialRepository.rootFS.Chroot("NotMatterValue") - unexpectedError(err, t) - - directoryForLocalRepoMetadata, err := fileSystemForLocalRepo.Chroot(".git") - unexpectedError(err, t) - - storageForTestRepo := filesystem.NewStorage(directoryForLocalRepoMetadata, cache.NewObjectLRUDefault()) - _, err = git.Clone(storageForTestRepo, fileSystemForLocalRepo, &git.CloneOptions{ + _, err := git.Clone(storageForTestRepo, fsForLocalRepo, &git.CloneOptions{ URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), }) - unexpectedError(err, t) + checkErrorDuringPreparation(err) sc := StatusChecker{ workspace: tmpDirWithInitialRepository.rootFS.Root(), @@ -220,20 +129,15 @@ func TestCommandRepositoryNoRemoteBranch(t *testing.T) { tmpDirWithInitialRepository := getTestDirForTests() dirNameForLocalRepository := "testRepo" - fileSystemForLocalRepo, err := tmpDirWithInitialRepository.rootFS.Chroot(dirNameForLocalRepository) - unexpectedError(err, t) + fsForLocalRepo, storageForTestRepo := getFSForLocalRepo(dirNameForLocalRepository, tmpDirWithInitialRepository.rootFS) - directoryForLocalRepoMetadata, err := fileSystemForLocalRepo.Chroot(".git") - unexpectedError(err, t) - - storageForTestRepo := filesystem.NewStorage(directoryForLocalRepoMetadata, cache.NewObjectLRUDefault()) - fakeLocalRepository, err := git.Clone(storageForTestRepo, fileSystemForLocalRepo, &git.CloneOptions{ + fakeLocalRepository, err := git.Clone(storageForTestRepo, fsForLocalRepo, &git.CloneOptions{ URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), }) - unexpectedError(err, t) + checkErrorDuringPreparation(err) err = fakeLocalRepository.DeleteRemote("origin") - unexpectedError(err, t) + checkErrorDuringPreparation(err) sc := StatusChecker{ workspace: tmpDirWithInitialRepository.rootFS.Root(), @@ -246,6 +150,7 @@ func TestCommandRepositoryNoRemoteBranch(t *testing.T) { } ch := make(chan CommandStatus) + go sc.Command(repoCfg, ch) repoStatus := <-ch expectedMessage := "cannot find remote branches" @@ -262,33 +167,11 @@ func TestCommandRepositoryNoRemoteBranch(t *testing.T) { } } -func TestCommandAllCorrect(t *testing.T) { +func TestCommandAllCorrectWithoutChanges(t *testing.T) { - tmpDirWithInitialRepository := getTestDirForTests() - dirNameForLocalRepository := "testRepo" - fileSystemForLocalRepo, err := tmpDirWithInitialRepository.rootFS.Chroot(dirNameForLocalRepository) - unexpectedError(err, t) - - directoryForLocalRepoMetadata, err := fileSystemForLocalRepo.Chroot(".git") - unexpectedError(err, t) - - storageForTestRepo := filesystem.NewStorage(directoryForLocalRepoMetadata, cache.NewObjectLRUDefault()) - fakeLocalRepository, err := git.Clone(storageForTestRepo, fileSystemForLocalRepo, &git.CloneOptions{ - URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), - }) - unexpectedError(err, t) - - sc := StatusChecker{ - workspace: tmpDirWithInitialRepository.rootFS.Root(), - } - repoCfg := config.RepositoryConfig{ - Name: "test", - Src: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), - Dest: dirNameForLocalRepository, - } + sc, _, repoCfg, _ := getBaseForTestingSyncCommand() ch := make(chan CommandStatus) - go sc.Command(repoCfg, ch) repoStatus := <-ch expectedMessage := "branch master - ( | origin | \u21910 \u21930 )" @@ -303,16 +186,21 @@ func TestCommandAllCorrect(t *testing.T) { if repoStatus.Message != expectedMessage { t.Errorf("Expected to get \"%v\", instead of this got \"%v\"", expectedMessage, repoStatus.Message) } +} +func TestCommandAllCorrectWithOneChange(t *testing.T) { + + sc, fakeLocalRepository, repoCfg, _ := getBaseForTestingSyncCommand() + + ch := make(chan CommandStatus) fakeLocalWorkTree, err := fakeLocalRepository.Worktree() - unexpectedError(err, t) + checkErrorDuringPreparation(err) - err = makeCommit(fakeLocalWorkTree, "commit 1", "Commit1") - unexpectedError(err, t) + makeCommit(fakeLocalWorkTree, "commit 1") go sc.Command(repoCfg, ch) - repoStatus = <-ch - expectedMessage = "branch master - ( | origin | \u21911 \u21930 )" + repoStatus := <-ch + expectedMessage := "branch master - ( | origin | \u21911 \u21930 )" if repoStatus.Message != expectedMessage { t.Errorf("Expected to get \"%v\", instead of this got \"%v\"", expectedMessage, repoStatus.Message) @@ -329,42 +217,10 @@ func TestCommandAllCorrect(t *testing.T) { } } -func TestCommandMultiRemote(t *testing.T) { - - tmpDirWithInitialRepository := getTestDirForTests() - dirNameForLocalRepository := "testRepo" - fileSystemForLocalRepo, err := tmpDirWithInitialRepository.rootFS.Chroot(dirNameForLocalRepository) - unexpectedError(err, t) - - directoryForLocalRepoMetadata, err := fileSystemForLocalRepo.Chroot(".git") - unexpectedError(err, t) - - storageForTestRepo := filesystem.NewStorage(directoryForLocalRepoMetadata, cache.NewObjectLRUDefault()) - fakeLocalRepository, err := git.Clone(storageForTestRepo, fileSystemForLocalRepo, &git.CloneOptions{ - URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), - }) - unexpectedError(err, t) - - fakeLocalRepository.CreateRemote(&gitcfg.RemoteConfig{ - Name: "subremote", - URLs: []string{tmpDirWithInitialRepository.baseRepository.fileSystem.Root()}, - }) - - fakeLocalRepository.Fetch(&git.FetchOptions{ - RemoteName: "subremote", - }) - - sc := StatusChecker{ - workspace: tmpDirWithInitialRepository.rootFS.Root(), - } - repoCfg := config.RepositoryConfig{ - Name: "test", - Src: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), - Dest: dirNameForLocalRepository, - } +func TestCommandMultiRemoteNoChanges(t *testing.T) { + sc, _, repoCfg := getBaseForTestingSyncMultipleRemote() ch := make(chan CommandStatus) - go sc.Command(repoCfg, ch) repoStatus := <-ch expectedMessage := "branch master - ( | origin | \u21910 \u21930 ) - ( | subremote | \u21910 \u21930 )" @@ -379,16 +235,21 @@ func TestCommandMultiRemote(t *testing.T) { if repoStatus.Message != expectedMessage { t.Errorf("Expected to get \"%v\", instead of this got \"%v\"", expectedMessage, repoStatus.Message) } +} + +func TestCommandMultiRemoteWithOneChange(t *testing.T) { + sc, fakeLocalRepository, repoCfg := getBaseForTestingSyncMultipleRemote() fakeLocalWorkTree, err := fakeLocalRepository.Worktree() - unexpectedError(err, t) + checkErrorDuringPreparation(err) - err = makeCommit(fakeLocalWorkTree, "commit 1", "Commit1") - unexpectedError(err, t) + makeCommit(fakeLocalWorkTree, "commit 1") + checkErrorDuringPreparation(err) + ch := make(chan CommandStatus) go sc.Command(repoCfg, ch) - repoStatus = <-ch - expectedMessage = "branch master - ( | origin | \u21911 \u21930 ) - ( | subremote | \u21911 \u21930 )" + repoStatus := <-ch + expectedMessage := "branch master - ( | origin | \u21911 \u21930 ) - ( | subremote | \u21911 \u21930 )" if repoStatus.Error { t.Errorf("Unexpected error") diff --git a/commands/sync_cmd_test.go b/commands/sync_cmd_test.go index 6d2f280..bed4eaf 100644 --- a/commands/sync_cmd_test.go +++ b/commands/sync_cmd_test.go @@ -8,25 +8,6 @@ import ( "gitlab.com/revalus/grm/config" ) -func createTempDir() string { - checkErrorDuringPreparation := func(err error) { - if err != nil { - fmt.Printf("Cannot prepare a temporary directory for testing! %v ", err.Error()) - os.Exit(2) - } - } - - baseTmp := fmt.Sprintf("%v/grmTest", os.TempDir()) - if _, ok := os.Stat(baseTmp); ok != nil { - err := os.Mkdir(baseTmp, 0777) - checkErrorDuringPreparation(err) - } - tempDir, err := os.MkdirTemp(baseTmp, "*") - checkErrorDuringPreparation(err) - - return tempDir -} - func TestSyncInit(t *testing.T) { sync := NewSynchronizer("test") if sync.workspace != "test" { @@ -36,10 +17,7 @@ func TestSyncInit(t *testing.T) { func TestSyncCommand(t *testing.T) { - workdir := createTempDir() - defer func() { - os.RemoveAll(workdir) - }() + workdir := createTmpDir() sync := Synchronizer{ workspace: workdir,