aboutsummaryrefslogblamecommitdiffstats
path: root/commands/bug/bug_comment_test.go
blob: e54cdab1c6c2675ad890b35063521777f80aa53b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
              


             
            




                                             
 


                                                         

 
                                   

                                                      
                                               
 
                                                                     




















                                                     
                                                                    









                                            
                                                                    


































































                                                                                      
                               









                                                                       
                                                                          

                  
                                                    



                                                       
                            
                                                  
                                                                             
                                                                                                 











                                                                                      
                                                                     
                                                 
                                       
                                                                                                                          

         
package bugcmd

import (
	"fmt"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/git-bug/git-bug/commands/bug/testenv"
	"github.com/git-bug/git-bug/commands/cmdtest"
	"github.com/git-bug/git-bug/commands/execenv"
)

func TestBugComment(t *testing.T) {
	const golden = "testdata/comment/message-only"

	env, bug := testenv.NewTestEnvAndBug(t)

	require.NoError(t, runBugComment(env, []string{bug.Human()}))

	requireCommentsEqual(t, golden, env)
}

const gitDateFormat = "Mon Jan 2 15:04:05 2006 -0700"

type parsedComment struct {
	author  string
	id      string
	date    time.Time
	message string
}

type parseFunc func(*parsedComment, string)

type commentParser struct {
	t        *testing.T
	fn       parseFunc
	comments []parsedComment
}

func parseComments(t *testing.T, env *execenv.Env) []parsedComment {
	t.Helper()

	parser := &commentParser{
		t:        t,
		comments: []parsedComment{},
	}

	comment := &parsedComment{}
	parser.fn = parser.parseAuthor

	for _, line := range strings.Split(env.Out.String(), "\n") {
		parser.fn(comment, line)
	}

	parser.comments = append(parser.comments, *comment)

	return parser.comments
}

func (p *commentParser) parseAuthor(comment *parsedComment, line string) {
	p.t.Helper()

	tkns := strings.Split(line, ": ")
	require.Len(p.t, tkns, 2)
	require.Equal(p.t, "Author", tkns[0])

	comment.author = tkns[1]
	p.fn = p.parseID
}

func (p *commentParser) parseID(comment *parsedComment, line string) {
	p.t.Helper()

	tkns := strings.Split(line, ": ")
	require.Len(p.t, tkns, 2)
	require.Equal(p.t, "Id", tkns[0])

	comment.id = tkns[1]
	p.fn = p.parseDate
}

func (p *commentParser) parseDate(comment *parsedComment, line string) {
	p.t.Helper()

	tkns := strings.Split(line, ": ")
	require.Len(p.t, tkns, 2)
	require.Equal(p.t, "Date", tkns[0])

	date, err := time.Parse(gitDateFormat, tkns[1])
	require.NoError(p.t, err)

	comment.date = date
	p.fn = p.parseMessage
}

func (p *commentParser) parseMessage(comment *parsedComment, line string) {
	p.t.Helper()

	if strings.HasPrefix(line, "Author: ") {
		p.comments = append(p.comments, *comment)
		comment = &parsedComment{}
		p.parseAuthor(comment, line)

		return
	}

	require.True(p.t, line == "" || strings.HasPrefix(line, "    "))

	comment.message = strings.Join([]string{comment.message, line}, "\n")
}

func normalizeParsedComments(t *testing.T, comments []parsedComment) []parsedComment {
	t.Helper()

	prefix := 0x1234567
	date, err := time.Parse(gitDateFormat, "Fri Aug 19 07:00:00 2022 +1900")
	require.NoError(t, err)

	var out []parsedComment

	for i, comment := range comments {
		comment.id = fmt.Sprintf("%7x", prefix+i)
		comment.date = date.Add(time.Duration(i) * time.Minute)
		out = append(out, comment)
	}

	return out
}

func requireCommentsEqual(t *testing.T, golden string, env *execenv.Env) {
	t.Helper()

	const goldenFilePattern = "%s-%d-golden.txt"

	comments := parseComments(t, env)
	comments = normalizeParsedComments(t, comments)

	if *cmdtest.Update {
		for i, comment := range comments {
			fileName := fmt.Sprintf(goldenFilePattern, golden, i)
			require.NoError(t, os.WriteFile(fileName, []byte(comment.message), 0644))
		}
	}

	prefix := 0x1234567
	date, err := time.Parse(gitDateFormat, "Fri Aug 19 07:00:00 2022 +1900")
	require.NoError(t, err)

	for i, comment := range comments {
		require.Equal(t, "John Doe", comment.author)
		require.Equal(t, fmt.Sprintf("%7x", prefix+i), comment.id)
		require.Equal(t, date.Add(time.Duration(i)*time.Minute), comment.date)

		fileName := fmt.Sprintf(goldenFilePattern, golden, i)
		exp, err := os.ReadFile(fileName)
		require.NoError(t, err)
		require.Equal(t, strings.ReplaceAll(string(exp), "\r", ""), strings.ReplaceAll(comment.message, "\r", ""))
	}
}