diff --git a/connmock/stub.go b/connmock/stub.go index dee9de1..ba70597 100644 --- a/connmock/stub.go +++ b/connmock/stub.go @@ -61,35 +61,35 @@ func (s *Stub) CheckRepos(err error, conf *Conf) *Stub { return s } -func (s *Stub) GetRepoNames(path string, err error, conf *Conf) *Stub { +func (s *Stub) GetRepoNames(filename string, err error, conf *Conf) *Stub { s.t.Helper() configure( s.Conn. EXPECT(). GetRepoNames(). - Return(s.readFile("gh", "repo", path), err), + Return(s.readFile("gh", "repo", filename), err), conf, ) return s } -func (s *Stub) GetBranchNames(name string, err error, conf *Conf) *Stub { +func (s *Stub) GetBranchNames(filename string, err error, conf *Conf) *Stub { s.t.Helper() configure( s.Conn.EXPECT(). GetBranchNames(). - Return(s.readFile("git", "branch", name), err), + Return(s.readFile("git", "branch", filename), err), conf, ) return s } -func (s *Stub) GetAssociatedBranchNames(stubs []AssociatedBranchNamesStub, err error, conf *Conf) *Stub { +func (s *Stub) GetAssociatedRefNames(stubs []AssociatedBranchNamesStub, err error, conf *Conf) *Stub { s.t.Helper() for _, stub := range stubs { configure( s.Conn.EXPECT(). - GetAssociatedBranchNames(stub.Oid). + GetAssociatedRefNames(stub.Oid). Return(s.readFile("git", "abranch", stub.Filename), err), conf, ) @@ -110,13 +110,37 @@ func (s *Stub) GetLog(stubs []LogStub, err error, conf *Conf) *Stub { return s } -func (s *Stub) GetPullRequests(path string, err error, conf *Conf) *Stub { +func (s *Stub) GetPullRequests(filename string, err error, conf *Conf) *Stub { s.t.Helper() configure( s.Conn. EXPECT(). GetPullRequests(gomock.Any(), gomock.Any(), gomock.Any()). - Return(s.readFile("gh", "pr", path), err), + Return(s.readFile("gh", "pr", filename), err), + conf, + ) + return s +} + +func (s *Stub) GetUncommittedChanges(uncommittedChanges string, err error, conf *Conf) *Stub { + s.t.Helper() + configure( + s.Conn. + EXPECT(). + GetUncommittedChanges(). + Return(uncommittedChanges, err), + conf, + ) + return s +} + +func (s *Stub) CheckoutBranch(err error, conf *Conf) *Stub { + s.t.Helper() + configure( + s.Conn. + EXPECT(). + CheckoutBranch(gomock.Any()). + Return("", err), conf, ) return s diff --git a/fixtures/git/abranch_issue1.txt b/fixtures/git/abranch_issue1.txt index 147a92b..64dff49 100644 --- a/fixtures/git/abranch_issue1.txt +++ b/fixtures/git/abranch_issue1.txt @@ -1 +1 @@ -issue1 \ No newline at end of file +refs/heads/issue1 \ No newline at end of file diff --git a/fixtures/git/abranch_issue1_origin-main.txt b/fixtures/git/abranch_issue1_origin-main.txt new file mode 100644 index 0000000..3f196fd --- /dev/null +++ b/fixtures/git/abranch_issue1_origin-main.txt @@ -0,0 +1,2 @@ +refs/heads/issue1 +refs/remotes/origin/main \ No newline at end of file diff --git a/fixtures/git/abranch_main.txt b/fixtures/git/abranch_main.txt index 88d050b..e607e0d 100644 --- a/fixtures/git/abranch_main.txt +++ b/fixtures/git/abranch_main.txt @@ -1 +1 @@ -main \ No newline at end of file +refs/heads/main \ No newline at end of file diff --git a/fixtures/git/abranch_main_issue1.txt b/fixtures/git/abranch_main_issue1.txt index 8178107..fb8cb2e 100644 --- a/fixtures/git/abranch_main_issue1.txt +++ b/fixtures/git/abranch_main_issue1.txt @@ -1,2 +1,2 @@ -issue1 -main \ No newline at end of file +refs/heads/issue1 +refs/heads/main \ No newline at end of file diff --git a/fixtures/git/branch_@issue1.txt b/fixtures/git/branch_@issue1.txt new file mode 100644 index 0000000..68fdf59 --- /dev/null +++ b/fixtures/git/branch_@issue1.txt @@ -0,0 +1 @@ +*,issue1,356a192b7913b04c54574d18c28d46e6395428ab diff --git a/main.go b/main.go index 232a9e3..6c2165f 100644 --- a/main.go +++ b/main.go @@ -39,7 +39,7 @@ func runMain(check bool) { sp.Start() var fetchingErr error - branches, fetchingErr := GetBranches(conn) + branches, fetchingErr := GetBranches(conn, check) sp.Stop() diff --git a/mocks/poi_mock.go b/mocks/poi_mock.go index 5a127c6..764fa09 100644 --- a/mocks/poi_mock.go +++ b/mocks/poi_mock.go @@ -47,6 +47,21 @@ func (mr *MockConnectionMockRecorder) CheckRepos(hostname, repoNames interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckRepos", reflect.TypeOf((*MockConnection)(nil).CheckRepos), hostname, repoNames) } +// CheckoutBranch mocks base method. +func (m *MockConnection) CheckoutBranch(branchName string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckoutBranch", branchName) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CheckoutBranch indicates an expected call of CheckoutBranch. +func (mr *MockConnectionMockRecorder) CheckoutBranch(branchName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckoutBranch", reflect.TypeOf((*MockConnection)(nil).CheckoutBranch), branchName) +} + // DeleteBranches mocks base method. func (m *MockConnection) DeleteBranches(branchNames []string) (string, error) { m.ctrl.T.Helper() @@ -62,19 +77,19 @@ func (mr *MockConnectionMockRecorder) DeleteBranches(branchNames interface{}) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBranches", reflect.TypeOf((*MockConnection)(nil).DeleteBranches), branchNames) } -// GetAssociatedBranchNames mocks base method. -func (m *MockConnection) GetAssociatedBranchNames(arg0 string) (string, error) { +// GetAssociatedRefNames mocks base method. +func (m *MockConnection) GetAssociatedRefNames(oid string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAssociatedBranchNames", arg0) + ret := m.ctrl.Call(m, "GetAssociatedRefNames", oid) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAssociatedBranchNames indicates an expected call of GetAssociatedBranchNames. -func (mr *MockConnectionMockRecorder) GetAssociatedBranchNames(arg0 interface{}) *gomock.Call { +// GetAssociatedRefNames indicates an expected call of GetAssociatedRefNames. +func (mr *MockConnectionMockRecorder) GetAssociatedRefNames(oid interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAssociatedBranchNames", reflect.TypeOf((*MockConnection)(nil).GetAssociatedBranchNames), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAssociatedRefNames", reflect.TypeOf((*MockConnection)(nil).GetAssociatedRefNames), oid) } // GetBranchNames mocks base method. @@ -93,18 +108,18 @@ func (mr *MockConnectionMockRecorder) GetBranchNames() *gomock.Call { } // GetLog mocks base method. -func (m *MockConnection) GetLog(arg0 string) (string, error) { +func (m *MockConnection) GetLog(branchName string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLog", arg0) + ret := m.ctrl.Call(m, "GetLog", branchName) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // GetLog indicates an expected call of GetLog. -func (mr *MockConnectionMockRecorder) GetLog(arg0 interface{}) *gomock.Call { +func (mr *MockConnectionMockRecorder) GetLog(branchName interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLog", reflect.TypeOf((*MockConnection)(nil).GetLog), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLog", reflect.TypeOf((*MockConnection)(nil).GetLog), branchName) } // GetPullRequests mocks base method. @@ -136,3 +151,18 @@ func (mr *MockConnectionMockRecorder) GetRepoNames() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRepoNames", reflect.TypeOf((*MockConnection)(nil).GetRepoNames)) } + +// GetUncommittedChanges mocks base method. +func (m *MockConnection) GetUncommittedChanges() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUncommittedChanges") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUncommittedChanges indicates an expected call of GetUncommittedChanges. +func (mr *MockConnectionMockRecorder) GetUncommittedChanges() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUncommittedChanges", reflect.TypeOf((*MockConnection)(nil).GetUncommittedChanges)) +} diff --git a/poi.go b/poi.go index eff67fc..f752699 100644 --- a/poi.go +++ b/poi.go @@ -18,9 +18,11 @@ type ( CheckRepos(hostname string, repoNames []string) error GetRepoNames() (string, error) GetBranchNames() (string, error) - GetLog(string) (string, error) - GetAssociatedBranchNames(string) (string, error) + GetLog(branchName string) (string, error) + GetAssociatedRefNames(oid string) (string, error) GetPullRequests(hostname string, repoNames []string, queryHashes string) (string, error) + GetUncommittedChanges() (string, error) + CheckoutBranch(branchName string) (string, error) DeleteBranches(branchNames []string) (string, error) } @@ -70,7 +72,7 @@ const ( var ErrNotFound = errors.New("not found") -func GetBranches(conn Connection) ([]Branch, error) { +func GetBranches(conn Connection, check bool) ([]Branch, error) { var hostname string var repoNames []string var defaultBranchName string @@ -109,7 +111,55 @@ func GetBranches(conn Connection) ([]Branch, error) { } branches = applyPullRequest(branches, prs) - branches = checkDeletion(branches) + + uncommittedChanges, err := conn.GetUncommittedChanges() + if err != nil { + return nil, err + } + + branches = checkDeletion(branches, uncommittedChanges) + + needsCheckout := false + for _, branch := range branches { + if branch.Head && branch.State == Deletable { + needsCheckout = true + break + } + } + + if needsCheckout { + result := []Branch{} + + if !check { + _, err := conn.CheckoutBranch(defaultBranchName) + if err != nil { + return nil, err + } + } + + if !branchNameExists(defaultBranchName, branches) { + result = append(result, Branch{ + true, defaultBranchName, + []string{}, + []PullRequest{}, + NotDeletable, + }) + } + + for _, branch := range branches { + if branch.Name == defaultBranchName { + branch.Head = true + } else { + branch.Head = false + } + result = append(result, branch) + } + + branches = result + } + + sort.Slice(branches, func(i, j int) bool { return branches[i].Name < branches[j].Name }) + return branches, nil } @@ -144,11 +194,11 @@ func trimBranch(oids []string, branchName string, conn Connection) ([]string, er childNames := []string{} for i, oid := range oids { - namesResult, err := conn.GetAssociatedBranchNames(oid) + refNames, err := conn.GetAssociatedRefNames(oid) if err != nil { return nil, err } - names := splitLines(namesResult) + names := extractBranchNames(splitLines(refNames)) if i == 0 { for _, name := range names { @@ -179,6 +229,15 @@ func trimBranch(oids []string, branchName string, conn Connection) ([]string, er return results, nil } +func extractBranchNames(refNames []string) []string { + result := []string{} + r := regexp.MustCompile(`^refs/(?:heads|remotes/.+?)/`) + for _, name := range refNames { + result = append(result, r.ReplaceAllString(name, "")) + } + return result +} + func applyPullRequest(branches []Branch, prs []PullRequest) []Branch { results := []Branch{} for _, branch := range branches { @@ -210,17 +269,17 @@ func findMatchedPullRequest(branchName string, prs []PullRequest) []PullRequest return results } -func checkDeletion(branches []Branch) []Branch { +func checkDeletion(branches []Branch, uncommittedChanges string) []Branch { results := []Branch{} for _, branch := range branches { - branch.State = getDeleteStatus(branch) + branch.State = getDeleteStatus(branch, uncommittedChanges) results = append(results, branch) } return results } -func getDeleteStatus(branch Branch) BranchState { - if branch.Head { +func getDeleteStatus(branch Branch, uncommittedChanges string) BranchState { + if branch.Head && len(uncommittedChanges) > 0 { return NotDeletable } @@ -482,9 +541,9 @@ func (conn *ConnectionImpl) GetLog(branchName string) (string, error) { return run("git", args) } -func (conn *ConnectionImpl) GetAssociatedBranchNames(oid string) (string, error) { +func (conn *ConnectionImpl) GetAssociatedRefNames(oid string) (string, error) { args := []string{ - "branch", "--format=%(refname:lstrip=2)", + "branch", "--all", "--format=%(refname)", "--contains", oid, } return run("git", args) @@ -525,6 +584,18 @@ func (conn *ConnectionImpl) GetPullRequests( return run("gh", args) } +func (conn *ConnectionImpl) GetUncommittedChanges() (string, error) { + args := append([]string{ + "status", "--short"}) + return run("git", args) +} + +func (conn *ConnectionImpl) CheckoutBranch(branchName string) (string, error) { + args := append([]string{ + "checkout", "--quiet", branchName}) + return run("git", args) +} + func (conn *ConnectionImpl) DeleteBranches(branchNames []string) (string, error) { args := append([]string{ "branch", "-D"}, diff --git a/poi_test.go b/poi_test.go index 40dff71..94f294f 100644 --- a/poi_test.go +++ b/poi_test.go @@ -20,13 +20,14 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithMergedPR(t *testing.T) { GetLog([]connmock.LogStub{ {"main", "main"}, {"issue1", "issue1"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, nil, nil). - GetPullRequests("issue1Merged", nil, nil) + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges("", nil, nil) - actual, _ := GetBranches(s.Conn) + actual, _ := GetBranches(s.Conn, false) assert.Equal(t, []Branch{ { @@ -65,13 +66,14 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithUpstreamMergedPR(t *testing GetLog([]connmock.LogStub{ {"main", "main"}, {"issue1", "issue1"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, nil, nil). - GetPullRequests("issue1UpMerged", nil, nil) + GetPullRequests("issue1UpMerged", nil, nil). + GetUncommittedChanges("", nil, nil) - actual, _ := GetBranches(s.Conn) + actual, _ := GetBranches(s.Conn, false) assert.Equal(t, []Branch{ { @@ -99,7 +101,7 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithUpstreamMergedPR(t *testing }, actual) } -func Test_ShouldNotDeletableWhenBranchIsCheckedOut(t *testing.T) { +func Test_ShouldBeDeletableWhenBranchIsCheckedOutWithTheCheckIsFalse(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -110,13 +112,156 @@ func Test_ShouldNotDeletableWhenBranchIsCheckedOut(t *testing.T) { GetLog([]connmock.LogStub{ {"main", "main"}, {"issue1", "issue1"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, nil, nil). - GetPullRequests("issue1Merged", nil, nil) + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges("", nil, nil). + CheckoutBranch(nil, connmock.NewConf(&connmock.Times{N: 1})) - actual, _ := GetBranches(s.Conn) + actual, _ := GetBranches(s.Conn, false) + + assert.Equal(t, []Branch{ + { + false, "issue1", + []string{ + "356a192b7913b04c54574d18c28d46e6395428ab", + }, + []PullRequest{ + { + "issue1", Merged, 1, + []string{ + "356a192b7913b04c54574d18c28d46e6395428ab", + }, + "https://github.com/owner/repo/pull/1", "owner", + }, + }, + Deletable, + }, + { + true, "main", + []string{}, + []PullRequest{}, + NotDeletable, + }, + }, actual) +} + +func Test_ShouldBeDeletableWhenBranchIsCheckedOutWithTheCheckIsTrue(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + s := connmock.Setup(ctrl). + CheckRepos(nil, nil). + GetRepoNames("origin", nil, nil). + GetBranchNames("main_@issue1", nil, nil). + GetLog([]connmock.LogStub{ + {"main", "main"}, {"issue1", "issue1"}, + }, nil, nil). + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ + {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, + {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, + }, nil, nil). + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges("", nil, nil). + CheckoutBranch(nil, connmock.NewConf(&connmock.Times{N: 0})) + + actual, _ := GetBranches(s.Conn, true) + + assert.Equal(t, []Branch{ + { + false, "issue1", + []string{ + "356a192b7913b04c54574d18c28d46e6395428ab", + }, + []PullRequest{ + { + "issue1", Merged, 1, + []string{ + "356a192b7913b04c54574d18c28d46e6395428ab", + }, + "https://github.com/owner/repo/pull/1", "owner", + }, + }, + Deletable, + }, + { + true, "main", + []string{}, + []PullRequest{}, + NotDeletable, + }, + }, actual) +} + +func Test_ShouldBeDeletableWhenBranchIsCheckedOutWithoutADefaultBranch(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + s := connmock.Setup(ctrl). + CheckRepos(nil, nil). + GetRepoNames("origin", nil, nil). + GetBranchNames("@issue1", nil, nil). + GetLog([]connmock.LogStub{ + {"issue1", "issue1"}, + }, nil, nil). + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ + {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, + {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "issue1_origin-main"}, + }, nil, nil). + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges("", nil, nil). + CheckoutBranch(nil, nil) + + actual, _ := GetBranches(s.Conn, false) + + assert.Equal(t, []Branch{ + { + false, "issue1", + []string{ + "356a192b7913b04c54574d18c28d46e6395428ab", + }, + []PullRequest{ + { + "issue1", Merged, 1, + []string{ + "356a192b7913b04c54574d18c28d46e6395428ab", + }, + "https://github.com/owner/repo/pull/1", "owner", + }, + }, + Deletable, + }, + { + true, "main", + []string{}, + []PullRequest{}, + NotDeletable, + }, + }, actual) +} + +func Test_ShouldNotDeletableWhenBranchHasUncommittedChanges(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + s := connmock.Setup(ctrl). + CheckRepos(nil, nil). + GetRepoNames("origin", nil, nil). + GetBranchNames("main_@issue1", nil, nil). + GetLog([]connmock.LogStub{ + {"main", "main"}, {"issue1", "issue1"}, + }, nil, nil). + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ + {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, + {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, + }, nil, nil). + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges(" M README.md", nil, nil). + CheckoutBranch(nil, nil) + + actual, _ := GetBranches(s.Conn, false) assert.Equal(t, []Branch{ { @@ -155,13 +300,14 @@ func Test_ShouldNotDeletableWhenBranchesAssociatedWithClosedPR(t *testing.T) { GetLog([]connmock.LogStub{ {"main", "main"}, {"issue1", "issue1"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, nil, nil). - GetPullRequests("issue1Closed", nil, nil) + GetPullRequests("issue1Closed", nil, nil). + GetUncommittedChanges("", nil, nil) - actual, _ := GetBranches(s.Conn) + actual, _ := GetBranches(s.Conn, false) assert.Equal(t, []Branch{ { @@ -200,13 +346,14 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithMergedAndClosedPRs(t *testi GetLog([]connmock.LogStub{ {"main", "main"}, {"issue1", "issue1"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, nil, nil). - GetPullRequests("issue1Merged_issue1Closed", nil, nil) + GetPullRequests("issue1Merged_issue1Closed", nil, nil). + GetUncommittedChanges("", nil, nil) - actual, _ := GetBranches(s.Conn) + actual, _ := GetBranches(s.Conn, false) assert.Equal(t, []Branch{ { @@ -252,15 +399,16 @@ func Test_ShouldNotDeletableWhenBranchesAssociatedWithNotFullyMergedPR(t *testin GetLog([]connmock.LogStub{ {"main", "main_issue1Merged"}, {"issue1", "issue1CommitAfterMerge"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"cb197ba87e4ad323b1008c611212deb7da2a4a49", "main"}, {"b8a2645298053fb62ea03e27feea6c483d3fd27e", "issue1"}, {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, nil, nil). - GetPullRequests("issue1Merged", nil, nil) + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges("", nil, nil) - actual, _ := GetBranches(s.Conn) + actual, _ := GetBranches(s.Conn, false) assert.Equal(t, []Branch{ { @@ -296,7 +444,7 @@ func Test_ReturnsAnErrorWhenGetRepoNamesFails(t *testing.T) { s := connmock.Setup(ctrl). GetRepoNames("origin", errors.New("failed to run external command: git"), nil) - _, err := GetBranches(s.Conn) + _, err := GetBranches(s.Conn, false) assert.NotNil(t, err) } @@ -309,7 +457,7 @@ func Test_ReturnsAnErrorWhenCheckReposFails(t *testing.T) { CheckRepos(errors.New("failed to run external command: gh"), nil). GetRepoNames("origin", nil, nil) - _, err := GetBranches(s.Conn) + _, err := GetBranches(s.Conn, false) assert.NotNil(t, err) } @@ -323,7 +471,7 @@ func Test_ReturnsAnErrorWhenGetBranchNamesFails(t *testing.T) { GetRepoNames("origin", nil, nil). GetBranchNames("@main_issue1", errors.New("failed to run external command: gh"), nil) - _, err := GetBranches(s.Conn) + _, err := GetBranches(s.Conn, false) assert.NotNil(t, err) } @@ -340,12 +488,12 @@ func Test_ReturnsAnErrorWhenGetLogFails(t *testing.T) { {"main", "main"}, {"issue1", "issue1"}, }, errors.New("failed to run external command: git"), nil) - _, err := GetBranches(s.Conn) + _, err := GetBranches(s.Conn, false) assert.NotNil(t, err) } -func Test_ReturnsAnErrorWhenGetAssociatedBranchNamesFails(t *testing.T) { +func Test_ReturnsAnErrorWhenGetAssociatedRefNamesFails(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -356,12 +504,12 @@ func Test_ReturnsAnErrorWhenGetAssociatedBranchNamesFails(t *testing.T) { GetLog([]connmock.LogStub{ {"main", "main"}, {"issue1", "issue1"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, errors.New("failed to run external command: git"), nil) - _, err := GetBranches(s.Conn) + _, err := GetBranches(s.Conn, false) assert.NotNil(t, err) } @@ -377,13 +525,60 @@ func Test_ReturnsAnErrorWhenGetPullRequestsFails(t *testing.T) { GetLog([]connmock.LogStub{ {"main", "main"}, {"issue1", "issue1"}, }, nil, nil). - GetAssociatedBranchNames([]connmock.AssociatedBranchNamesStub{ + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, }, nil, nil). GetPullRequests("issue1Merged", errors.New("failed to run external command: gh"), nil) - _, err := GetBranches(s.Conn) + _, err := GetBranches(s.Conn, false) + + assert.NotNil(t, err) +} + +func Test_ReturnsAnErrorWhenGetUncommittedChangesFails(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + s := connmock.Setup(ctrl). + CheckRepos(nil, nil). + GetRepoNames("origin", nil, nil). + GetBranchNames("@main_issue1", nil, nil). + GetLog([]connmock.LogStub{ + {"main", "main"}, {"issue1", "issue1"}, + }, nil, nil). + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ + {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, + {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, + }, nil, nil). + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges("", errors.New("failed to run external command: git"), nil) + + _, err := GetBranches(s.Conn, false) + + assert.NotNil(t, err) +} + +func Test_ReturnsAnErrorWhenCheckoutBranchFails(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + s := connmock.Setup(ctrl). + CheckRepos(nil, nil). + GetRepoNames("origin", nil, nil). + GetBranchNames("main_@issue1", nil, nil). + GetLog([]connmock.LogStub{ + {"main", "main"}, {"issue1", "issue1"}, + }, nil, nil). + GetAssociatedRefNames([]connmock.AssociatedBranchNamesStub{ + {"356a192b7913b04c54574d18c28d46e6395428ab", "issue1"}, + {"b6589fc6ab0dc82cf12099d1c2d40ab994e8410c", "main_issue1"}, + }, nil, nil). + GetPullRequests("issue1Merged", nil, nil). + GetUncommittedChanges("", nil, nil). + CheckoutBranch(errors.New("failed to run external command: git"), nil) + + _, err := GetBranches(s.Conn, false) assert.NotNil(t, err) }