Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ClairePhi committed Nov 3, 2024
1 parent f61a792 commit 92322e1
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 30 deletions.
4 changes: 2 additions & 2 deletions cmd/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import (
"github.com/urfave/cli/v2"
)

func MakeApp(out io.Writer, repo *core.Repo, gh func(context.Context) core.Gh, sf func(string, string) story.StoryFetcher) *cli.App {
func MakeApp(out io.Writer, in io.Reader, repo *core.Repo, gh func(context.Context) core.Gh, sf func(string, string) story.StoryFetcher) *cli.App {
return &cli.App{
Name: "opp",
Usage: "Create, update and merge Github pull requests from the command line.",
Commands: []*cli.Command{
InitCommand(repo),
CleanCommand(repo, gh),
CloseCommand(repo, gh),
PrCommand(repo, gh, sf),
PrCommand(in, repo, gh, sf),
MergeCommand(repo, gh),
StatusCommand(out, repo, gh),
RebaseCommand(repo),
Expand Down
13 changes: 7 additions & 6 deletions cmd/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"io"
"sort"
"strings"

Expand Down Expand Up @@ -52,7 +53,7 @@ whether it reached the base branch or the tip of another PR first when walking b
`)
)

func PrCommand(repo *core.Repo, gh func(context.Context) core.Gh, sf func(string, string) story.StoryFetcher) *cli.Command {
func PrCommand(in io.Reader, repo *core.Repo, gh func(context.Context) core.Gh, sf func(string, string) story.StoryFetcher) *cli.Command {
cmd := &cli.Command{
Name: "pr",
Aliases: []string{"pull-request", "new"},
Expand Down Expand Up @@ -103,7 +104,7 @@ func PrCommand(repo *core.Repo, gh func(context.Context) core.Gh, sf func(string
}
args = newArgs
}
localPr, err := pr.Create(cCtx.Context, args)
localPr, err := pr.Create(cCtx.Context, in, args)
if err != nil {
return err
}
Expand Down Expand Up @@ -311,11 +312,11 @@ func (c *create) RebasePrCommits(ctx context.Context, previousArgs *args) (*args
}, nil
}

func (c *create) Create(ctx context.Context, args *args) (*core.LocalPr, error) {
func (c *create) Create(ctx context.Context, in io.Reader, args *args) (*core.LocalPr, error) {

// The first commit is the child-most one.
lastCommit := args.Commits[0].Hash
title, body, err := c.GetBodyAndTitle(ctx, args.Commits)
title, body, err := c.GetBodyAndTitle(ctx, in, args.Commits)
if err != nil {
return nil, fmt.Errorf("could not get the pull request body and title: %w", err)
}
Expand All @@ -336,13 +337,13 @@ func (c *create) Create(ctx context.Context, args *args) (*core.LocalPr, error)
return localPr, err
}

func (c *create) GetBodyAndTitle(ctx context.Context, commits []*object.Commit) (string, string, error) {
func (c *create) GetBodyAndTitle(ctx context.Context, in io.Reader, commits []*object.Commit) (string, string, error) {
rawTitle, rawBody := c.getRawBodyAndTitle(commits)
commitMessages := make([]string, len(commits))
for i, c := range commits {
commitMessages[i] = c.Message
}
storyService := story.NewStoryService(c.StoryFetcher)
storyService := story.NewStoryService(c.StoryFetcher, in)
title, body, err := storyService.EnrichBodyAndTitle(ctx, commitMessages, rawTitle, rawBody)
if err != nil {
return "", "", fmt.Errorf("could not enrich the PR with the Story: %w", err)
Expand Down
115 changes: 108 additions & 7 deletions cmd/pr_story_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"testing"

"github.com/cupcicm/opp/core"
"github.com/cupcicm/opp/core/story"
"github.com/cupcicm/opp/core/tests"
"github.com/google/go-github/v56/github"
)

func TestPrStory(t *testing.T) {
func TestPrStoryInCommits(t *testing.T) {
remote := "cupcicm/pr/2"
base := "master"
draft := false
Expand Down Expand Up @@ -38,12 +39,6 @@ func TestPrStory(t *testing.T) {
expectedTitle: "my title [ABC-123]",
expectedBody: "- Linear [ABC-123](https://my.base.url/browse/ABC-123)\n\nmy body",
},
{
name: "no story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "empty body",
commitMessages: []string{"[ABC-123] my commit title", "a\nb"},
Expand Down Expand Up @@ -96,3 +91,109 @@ func TestPrStory(t *testing.T) {
})
}
}

func TestPrStoryFetched(t *testing.T) {
remote := "cupcicm/pr/2"
base := "master"
draft := false

testCases := []struct {
name string
commitMessages []string
fetchedStories []story.Story
errFetchStories bool
selectedStory string
expectedTitle string
expectedBody string
}{
{
name: "no story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{},
errFetchStories: false,
selectedStory: "",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "error fetching story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{},
errFetchStories: true,
selectedStory: "",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "one story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}},
errFetchStories: false,
selectedStory: "0",
expectedTitle: "[ABC-123] longest commit message",
expectedBody: "- Linear [ABC-123](https://my.base.url/browse/ABC-123)\n\nlongest commit message body",
},
{
name: "two stories - first chosen",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "0",
expectedTitle: "[ABC-123] longest commit message",
expectedBody: "- Linear [ABC-123](https://my.base.url/browse/ABC-123)\n\nlongest commit message body",
},
{
name: "two stories - second chosen",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "1",
expectedTitle: "[ABC-456] longest commit message",
expectedBody: "- Linear [ABC-456](https://my.base.url/browse/ABC-456)\n\nlongest commit message body",
},
{
name: "two stories - invalid input",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "invalid",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "two stories - no input",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
r := tests.NewTestRepo(t)

r.Repo.GitExec(context.Background(), "checkout origin/master").Run()
r.Repo.GitExec(context.Background(), "checkout -b test_branch").Run()

wt := core.Must(r.Source.Worktree())

for _, commitMessage := range tc.commitMessages {
wt.Add("README.md")
r.Commit(commitMessage)
}

prDetails := github.NewPullRequest{
Title: &tc.expectedTitle,
Head: &remote,
Base: &base,
Body: &tc.expectedBody,
Draft: &draft,
}

r.CreatePrAssertPrDetailsWithStories(t, "HEAD", 2, tc.fetchedStories, tc.errFetchStories, tc.selectedStory, prDetails)
})
}
}
31 changes: 20 additions & 11 deletions core/story/story_service.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package story

import (
"bufio"
"context"
"errors"
"fmt"
"io"
"regexp"
"strconv"
"strings"
Expand All @@ -21,7 +23,7 @@ type StoryService interface {
EnrichBodyAndTitle(ctx context.Context, commitMessages []string, rawTitle, rawBody string) (title, body string, err error)
}

func NewStoryService(storyFetcher func(string, string) StoryFetcher) StoryService {
func NewStoryService(storyFetcher func(string, string) StoryFetcher, in io.Reader) StoryService {
tool := core.GetStoryTool()
url := core.GetStoryToolUrl()
token := core.GetStoryToolToken()
Expand Down Expand Up @@ -50,6 +52,7 @@ func NewStoryService(storyFetcher func(string, string) StoryFetcher) StoryServic
tool: tool,
url: url,
storyFetcher: storyFetcher(tool, token),
in: in,
}
}

Expand All @@ -65,47 +68,48 @@ type StoryServiceEnabled struct {
tool string
url string
storyFetcher StoryFetcher
in io.Reader
}

func (s *StoryServiceEnabled) EnrichBodyAndTitle(ctx context.Context, commitMessages []string, rawTitle, rawBody string) (title, body string, err error) {
story, title := s.getStoryAndEnrichTitle(ctx, commitMessages, rawTitle)
story, title := s.getStoryAndEnrichTitle(ctx, s.in, commitMessages, rawTitle)
body, err = s.enrichBody(rawBody, story)
if err != nil {
return "", "", err
}
return title, body, nil
}

func (s *StoryServiceEnabled) getStoryAndEnrichTitle(ctx context.Context, commitMessages []string, rawTitle string) (story, title string) {
func (s *StoryServiceEnabled) getStoryAndEnrichTitle(ctx context.Context, in io.Reader, commitMessages []string, rawTitle string) (story, title string) {
story, found := s.storyFromMessageOrTitle(rawTitle)

if found {
return story, rawTitle
}

story, found = s.findStory(ctx, commitMessages)
story, found = s.findStory(ctx, in, commitMessages)
if found {
return story, strings.Join([]string{s.formatStoryInPRTitle(story), rawTitle}, " ")
}

return "", rawTitle
}

func (s *StoryServiceEnabled) findStory(ctx context.Context, commitMessages []string) (story string, found bool) {
func (s *StoryServiceEnabled) findStory(ctx context.Context, in io.Reader, commitMessages []string) (story string, found bool) {
story, found = s.extractFromCommitMessages(commitMessages)
if found {
return story, true
}

story, found = s.fetchStory(ctx)
story, found = s.fetchStory(ctx, in)
if found {
return story, true
}

return "", false
}

func (s *StoryServiceEnabled) fetchStory(ctx context.Context) (story string, found bool) {
func (s *StoryServiceEnabled) fetchStory(ctx context.Context, in io.Reader) (story string, found bool) {
stories, err := s.storyFetcher.FetchInProgressStories(ctx)
if err != nil {
fmt.Printf("could not fetch In Progress Stories: %s\n", err.Error())
Expand All @@ -117,7 +121,7 @@ func (s *StoryServiceEnabled) fetchStory(ctx context.Context) (story string, fou
return "", false
}

story, err = s.selectStory(stories)
story, err = s.selectStory(in, stories)
if err != nil {
fmt.Printf("could not select the Story: %s\n", err.Error())
return "", false
Expand All @@ -126,7 +130,7 @@ func (s *StoryServiceEnabled) fetchStory(ctx context.Context) (story string, fou
return story, true
}

func (s *StoryServiceEnabled) selectStory(stories []Story) (selectedStory string, err error) {
func (s *StoryServiceEnabled) selectStory(in io.Reader, stories []Story) (selectedStory string, err error) {
fmt.Println("In Progress stories assigned to me:")

for idx, story := range stories {
Expand All @@ -137,9 +141,14 @@ func (s *StoryServiceEnabled) selectStory(stories []Story) (selectedStory string

fmt.Println("Choose index: ")

var choosenIndex string
// Taking input from user
fmt.Scanln(&choosenIndex)
reader := bufio.NewReader(in)
choosenIndex, err := reader.ReadString('\n')
if err != nil {
return "", errors.New("the input could not be read")
}

choosenIndex = strings.TrimSuffix(choosenIndex, "\n")

index, err := strconv.Atoi(choosenIndex)
if err != nil {
Expand Down
Loading

0 comments on commit 92322e1

Please sign in to comment.