comment_test.go

  1package commands
  2
  3import (
  4	"fmt"
  5	"io/ioutil"
  6	"strings"
  7	"testing"
  8	"time"
  9
 10	"github.com/stretchr/testify/require"
 11)
 12
 13func TestComment(t *testing.T) {
 14	const golden = "testdata/comment/message-only"
 15
 16	env, bug := newTestEnvAndBug(t)
 17
 18	require.NoError(t, runComment(env.env, []string{bug}))
 19
 20	requireCommentsEqual(t, golden, env)
 21}
 22
 23const gitDateFormat = "Mon Jan 2 15:04:05 2006 -0700"
 24
 25type parsedComment struct {
 26	author  string
 27	id      string
 28	date    time.Time
 29	message string
 30}
 31
 32type parseFunc func(*parsedComment, string)
 33
 34type commentParser struct {
 35	t        *testing.T
 36	fn       parseFunc
 37	comments []parsedComment
 38}
 39
 40func parseComments(t *testing.T, env *testEnv) []parsedComment {
 41	t.Helper()
 42
 43	parser := &commentParser{
 44		t:        t,
 45		comments: []parsedComment{},
 46	}
 47
 48	comment := &parsedComment{}
 49	parser.fn = parser.parseAuthor
 50
 51	for _, line := range strings.Split(env.out.String(), "\n") {
 52		parser.fn(comment, line)
 53	}
 54
 55	parser.comments = append(parser.comments, *comment)
 56
 57	return parser.comments
 58}
 59
 60func (p *commentParser) parseAuthor(comment *parsedComment, line string) {
 61	p.t.Helper()
 62
 63	tkns := strings.Split(line, ": ")
 64	require.Len(p.t, tkns, 2)
 65	require.Equal(p.t, "Author", tkns[0])
 66
 67	comment.author = tkns[1]
 68	p.fn = p.parseID
 69}
 70
 71func (p *commentParser) parseID(comment *parsedComment, line string) {
 72	p.t.Helper()
 73
 74	tkns := strings.Split(line, ": ")
 75	require.Len(p.t, tkns, 2)
 76	require.Equal(p.t, "Id", tkns[0])
 77
 78	comment.id = tkns[1]
 79	p.fn = p.parseDate
 80}
 81
 82func (p *commentParser) parseDate(comment *parsedComment, line string) {
 83	p.t.Helper()
 84
 85	tkns := strings.Split(line, ": ")
 86	require.Len(p.t, tkns, 2)
 87	require.Equal(p.t, "Date", tkns[0])
 88
 89	date, err := time.Parse(gitDateFormat, tkns[1])
 90	require.NoError(p.t, err)
 91
 92	comment.date = date
 93	p.fn = p.parseMessage
 94}
 95
 96func (p *commentParser) parseMessage(comment *parsedComment, line string) {
 97	p.t.Helper()
 98
 99	if strings.HasPrefix(line, "Author: ") {
100		p.comments = append(p.comments, *comment)
101		comment = &parsedComment{}
102		p.parseAuthor(comment, line)
103
104		return
105	}
106
107	require.True(p.t, line == "" || strings.HasPrefix(line, "    "))
108
109	comment.message = strings.Join([]string{comment.message, line}, "\n")
110}
111
112func normalizeParsedComments(t *testing.T, comments []parsedComment) []parsedComment {
113	t.Helper()
114
115	prefix := 0x1234567
116	date, err := time.Parse(gitDateFormat, "Fri Aug 19 07:00:00 2022 +1900")
117	require.NoError(t, err)
118
119	out := []parsedComment{}
120
121	for i, comment := range comments {
122		comment.id = fmt.Sprintf("%7x", prefix+i)
123		comment.date = date.Add(time.Duration(i) * time.Minute)
124		out = append(out, comment)
125	}
126
127	return out
128}
129
130func requireCommentsEqual(t *testing.T, golden string, env *testEnv) {
131	t.Helper()
132
133	const goldenFilePatter = "%s-%d-golden.txt"
134
135	comments := parseComments(t, env)
136	comments = normalizeParsedComments(t, comments)
137
138	if *update {
139		t.Log("Got here")
140		for i, comment := range comments {
141			fileName := fmt.Sprintf(goldenFilePatter, golden, i)
142			require.NoError(t, ioutil.WriteFile(fileName, []byte(comment.message), 0644))
143		}
144	}
145
146	prefix := 0x1234567
147	date, err := time.Parse(gitDateFormat, "Fri Aug 19 07:00:00 2022 +1900")
148	require.NoError(t, err)
149
150	for i, comment := range comments {
151		require.Equal(t, "John Doe", comment.author)
152		require.Equal(t, fmt.Sprintf("%7x", prefix+i), comment.id)
153		require.Equal(t, date.Add(time.Duration(i)*time.Minute), comment.date)
154
155		fileName := fmt.Sprintf(goldenFilePatter, golden, i)
156		exp, err := ioutil.ReadFile(fileName)
157		require.NoError(t, err)
158		require.Equal(t, string(exp), comment.message)
159	}
160}