Skip to content

Commit

Permalink
add mocks for testing generator
Browse files Browse the repository at this point in the history
  • Loading branch information
HandOfGod94 committed Jul 22, 2023
1 parent 5280c1a commit 32a91ed
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 49 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ setup-tools:
go install github.com/uudashr/gocognit/cmd/gocognit@latest
go install honnef.co/go/tools/cmd/staticcheck@latest
go install github.com/mcubik/goverreport@latest
go install github.com/vektra/mockery/v2@v2.32.0

sync-docs:
mdsh
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
Expand Down
51 changes: 51 additions & 0 deletions mocks/Client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions pkg/jira_changelog/changelog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func TestRender(t *testing.T) {
changelog: jira_changelog.Changelog{
Changes: map[string][]jira.Issue{
"TestEpic": {
jira.NewIssue("TEST-1", "foobar is new", "done"),
jira.NewIssue("TEST-2", "fizzbuzz is something else", "done"),
jira.NewIssue("TEST-1", "foobar is new", "done", "TestEpic"),
jira.NewIssue("TEST-2", "fizzbuzz is something else", "done", "TestEpic"),
},
},
},
Expand All @@ -37,9 +37,9 @@ func TestRender(t *testing.T) {
changelog: jira_changelog.Changelog{
Changes: map[string][]jira.Issue{
"TestEpic": {
jira.NewIssue("TEST-1", "foobar is new", "done"),
jira.NewIssue("TEST-2", "fizzbuzz is something else", "in progress"),
jira.NewIssue("TEST-3", "fizzbuzz is something else", "done"),
jira.NewIssue("TEST-1", "foobar is new", "done", "TestEpic"),
jira.NewIssue("TEST-2", "fizzbuzz is something else", "in progress", "TestEpic"),
jira.NewIssue("TEST-3", "fizzbuzz is something else", "done", "TestEpic"),
},
},
},
Expand All @@ -56,14 +56,14 @@ func TestRender(t *testing.T) {
changelog: jira_changelog.Changelog{
Changes: map[string][]jira.Issue{
"TestEpic1": {
jira.NewIssue("TEST-1", "foobar is new", "done"),
jira.NewIssue("TEST-2", "fizzbuzz is something else", "in progress"),
jira.NewIssue("TEST-3", "fizzbuzz is something else", "done"),
jira.NewIssue("TEST-1", "foobar is new", "done", "TestEpic1"),
jira.NewIssue("TEST-2", "fizzbuzz is something else", "in progress", "TestEpic1"),
jira.NewIssue("TEST-3", "fizzbuzz is something else", "done", "TestEpic1"),
},
"TestEpic2": {
jira.NewIssue("TEST-4", "foobar is new", "done"),
jira.NewIssue("TEST-5", "fizzbuzz is something else", "done"),
jira.NewIssue("TEST-6", "fizzbuzz is something else", "done"),
jira.NewIssue("TEST-4", "foobar is new", "done", "TestEpic2"),
jira.NewIssue("TEST-5", "fizzbuzz is something else", "done", "TestEpic2"),
jira.NewIssue("TEST-6", "fizzbuzz is something else", "done", "TestEpic2"),
},
},
},
Expand Down
25 changes: 14 additions & 11 deletions pkg/jira_changelog/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package jira_changelog

import (
"context"
"fmt"

"github.com/handofgod94/gh-jira-changelog/pkg/jira_changelog/git"
"github.com/handofgod94/gh-jira-changelog/pkg/jira_changelog/jira"
Expand All @@ -13,22 +14,27 @@ type Generator struct {
JiraConfig jira.Config
fromRef string
toRef string
client *jira.Client
client jira.Client
}

func checkErr(err error) {
func panicIfErr(err error, args ...interface{}) {
slog.Error(err.Error(), args...)
if err != nil {
panic(err)
}
}

func (c Generator) Generate(ctx context.Context) *Changelog {
gitOutput, err := git.ExecGitLog(ctx, c.fromRef, c.toRef)
checkErr(err)
panicIfErr(fmt.Errorf("failed to execute git command. %w", err))

commits, err := gitOutput.Commits()
checkErr(err)
panicIfErr(fmt.Errorf("failed to parse git output. %w", err))

return c.changelogFromCommits(commits)
}

func (c Generator) changelogFromCommits(commits []git.Commit) *Changelog {
slog.Debug("Total commit messages", "count", len(commits))

jiraIssueIds := lo.Map(commits, func(commit git.Commit, index int) jira.JiraIssueId {
Expand All @@ -40,17 +46,14 @@ func (c Generator) Generate(ctx context.Context) *Changelog {

issues := lo.Map(jiraIssueIds, func(jiraIssueId jira.JiraIssueId, index int) jira.Issue {
issue, err := c.client.FetchIssue(string(jiraIssueId))
if err != nil {
slog.Error("Error fetching issue", "issue", jiraIssueId, "error", err)
panic(err)
}
slog.Debug("Fetched issue", "issue", issue)
return *issue
panicIfErr(fmt.Errorf("failed to fetch issue. %w", err), "issue", jiraIssueId)

slog.Debug("fetched issue", "issue", issue)
return issue
})
slog.Debug("Total issues", "count", len(issues))

issuesByEpic := lo.GroupBy(issues, func(issue jira.Issue) string { return issue.Epic() })
slog.Debug("Issues grouped by epic", "issues", issuesByEpic)
return &Changelog{Changes: issuesByEpic}
}

Expand Down
51 changes: 51 additions & 0 deletions pkg/jira_changelog/generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package jira_changelog

import (
"testing"
"time"

"github.com/handofgod94/gh-jira-changelog/mocks"
"github.com/handofgod94/gh-jira-changelog/pkg/jira_changelog/git"
"github.com/handofgod94/gh-jira-changelog/pkg/jira_changelog/jira"
"github.com/stretchr/testify/assert"
)

func TestChangelogFromCommits(t *testing.T) {
commits := []git.Commit{
{Time: time.Now(), Message: "[TEST-1234] commit message1", Sha: "3245vw"},
{Time: time.Now(), Message: "[TEST-4546] commit message sample1", Sha: "3245vw"},
{Time: time.Now(), Message: "[TEST-1234] commit message2", Sha: "3245vw"},
{Time: time.Now(), Message: "[TEST-4546] commit message sample2", Sha: "3245vw"},
{Time: time.Now(), Message: "[TEST-12345] commit message from same epic", Sha: "3245vw"},
{Time: time.Now(), Message: "[NO-CARD] commit message random", Sha: "3245vw"},
{Time: time.Now(), Message: "foobar commit message random", Sha: "3245vw"},
}

expected := &Changelog{
Changes: map[string][]jira.Issue{
"Epic1": {
jira.NewIssue("TEST-1234", "Ticket description", "done", "Epic1"),
jira.NewIssue("TEST-12345", "Ticket description of another from same epic", "done", "Epic1"),
},
"Epic2": {
jira.NewIssue("TEST-4546", "Ticket description for 4546 issue", "done", "Epic2"),
},
"Misc": {
jira.NewIssue("NO-CARD", "Ticket description for no card issue", "done", ""),
jira.NewIssue("", "foobar commit message random", "", ""),
},
},
}

mockedClient := mocks.NewClient(t)
mockedClient.On("FetchIssue", "TEST-1234").Return(jira.NewIssue("TEST-1234", "Ticket description", "done", "Epic1"), nil).Times(2)
mockedClient.On("FetchIssue", "TEST-4546").Return(jira.NewIssue("TEST-4546", "Ticket description", "done", "Epic2"), nil).Times(2)
mockedClient.On("FetchIssue", "TEST-12345").Return(jira.NewIssue("TEST-12345", "Ticket description", "done", "Epic1"), nil)
mockedClient.On("FetchIssue", "NO-CARD").Return(jira.NewIssue("", "", "", ""), nil)
generator := Generator{JiraConfig: jira.Config{ProjectName: "TEST"}}
generator.client = mockedClient

result := generator.changelogFromCommits(commits)

assert.Equal(t, expected, result)
}
25 changes: 21 additions & 4 deletions pkg/jira_changelog/git/commits.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ import (
type Commit struct {
Message string
Time time.Time
Sha string
}

type GitOutput string

var gitoutputPattern = regexp.MustCompile(`^\((\d+)\)\s+(.*)`)
var gitoutputPattern = regexp.MustCompile(`^\((\d+)\)\s+\{(\w+)\}\s*(.*)`)

func ExecGitLog(ctx context.Context, fromRef, toRef string) (GitOutput, error) {
cmd := exec.CommandContext(ctx, "git", "log", "--decorate-refs-exclude=refs/tags", "--pretty=(%ct) %d %s", "--no-merges", fromRef+".."+toRef)
cmd := exec.CommandContext(ctx, "git", "log", "--decorate-refs-exclude=refs/tags", "--pretty=(%ct) {%h} %d %s", "--no-merges", fromRef+".."+toRef)
stdout, err := cmd.Output()
if err != nil {
return "", fmt.Errorf("failed to execute git command: %v", err)
Expand All @@ -48,9 +49,16 @@ func (gt GitOutput) Commits() ([]Commit, error) {
return []Commit{}, fmt.Errorf("failed to extract timestamp. %w", err)
}

sha, err := extractSha(line)
if err != nil {
slog.Error("failed to extract sha", "gitlogLine", line)
return []Commit{}, fmt.Errorf("failed to extract sha. %w", err)
}

commits = append(commits, Commit{
Message: message,
Time: commitTime,
Sha: sha,
})
}
return commits, nil
Expand All @@ -59,11 +67,11 @@ func (gt GitOutput) Commits() ([]Commit, error) {
func extractCommitMessage(gitlogLine string) (string, error) {
gitlogLine = strings.TrimSpace(gitlogLine)
result := gitoutputPattern.FindStringSubmatch(gitlogLine)
if len(result) < 3 {
if len(result) < 4 {
return "", fmt.Errorf("couldn't find commit message in git log. %v", gitlogLine)
}

return result[2], nil
return result[3], nil
}

func extractTime(gitlogLine string) (time.Time, error) {
Expand All @@ -78,3 +86,12 @@ func extractTime(gitlogLine string) (time.Time, error) {
}
return time.Unix(int64(timestamp), 0), nil
}

func extractSha(gitlogLine string) (string, error) {
result := gitoutputPattern.FindStringSubmatch(gitlogLine)
if len(result) < 3 {
return "", fmt.Errorf("couldn't find sha in commit message. %v", gitlogLine)
}

return result[2], nil
}
13 changes: 8 additions & 5 deletions pkg/jira_changelog/git/commits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,34 @@ func TestCommits(t *testing.T) {
{
desc: "returns commits when gitoutput is valid",
gitOutput: git.GitOutput(`
(1687839814) use extra space while generating template
(1688059937) [JIRA-123] refactor: extract out structs from jira/types
(1687799347) add warning emoji for changelog lineitem
(1687839814) {3cefgdr} use extra space while generating template
(1688059937) {4567uge} [JIRA-123] refactor: extract out structs from jira/types
(1687799347) {3456cdw} add warning emoji for changelog lineitem
`),
want: []git.Commit{
{
Message: "use extra space while generating template",
Time: time.Unix(1687839814, 0),
Sha: "3cefgdr",
},
{
Message: "[JIRA-123] refactor: extract out structs from jira/types",
Time: time.Unix(1688059937, 0),
Sha: "4567uge",
},
{
Message: "add warning emoji for changelog lineitem",
Time: time.Unix(1687799347, 0),
Sha: "3456cdw",
},
},
},
{
desc: "returns single commit if gitoutput has single line",
gitOutput: git.GitOutput(`
(1688059937) refactor: extract out structs from jira/types
(1688059937) {3456cdw} refactor: extract out structs from jira/types
`),
want: []git.Commit{{Message: "refactor: extract out structs from jira/types", Time: time.Unix(1688059937, 0)}},
want: []git.Commit{{Message: "refactor: extract out structs from jira/types", Time: time.Unix(1688059937, 0), Sha: "3456cdw"}},
},
{
desc: "returns error when output is not in correct format",
Expand Down
Loading

0 comments on commit 32a91ed

Please sign in to comment.