Skip to content

Commit b1122d4

Browse files
Colorize the status of test packages in the progress output (#147)
1 parent a2c29b8 commit b1122d4

File tree

7 files changed

+55
-57
lines changed

7 files changed

+55
-57
lines changed

internal/app/app.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,14 @@ func Run(option Options) (int, error) {
6868
defer option.FollowOutputWriter.Close()
6969
}
7070

71+
progressWriter := newConsoleWriter(option.Output, option.Format, option.DisableColor)
7172
summary, err := parse.Process(
7273
reader,
7374
parse.WithFollowOutput(option.FollowOutput),
7475
parse.WithFollowVersboseOutput(option.FollowOutputVerbose),
7576
parse.WithWriter(option.FollowOutputWriter),
7677
parse.WithProgress(option.Progress),
77-
parse.WithProgressOutput(option.ProgressOutput),
78+
parse.WithProgressOutput(progressWriter),
7879
)
7980
if err != nil {
8081
return 1, err

internal/app/console_writer.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package app
22

33
import (
44
"io"
5+
"strings"
56

67
"github.com/charmbracelet/lipgloss"
78
"github.com/muesli/termenv"
9+
10+
"github.com/mfridman/tparse/parse"
811
)
912

1013
type OutputFormat int
@@ -19,8 +22,8 @@ const (
1922
)
2023

2124
type consoleWriter struct {
25+
io.Writer
2226
format OutputFormat
23-
w io.Writer
2427

2528
red colorOptionFunc
2629
green colorOptionFunc
@@ -52,7 +55,7 @@ func newConsoleWriter(w io.Writer, format OutputFormat, disableColor bool) *cons
5255
format = OutputFormatBasic
5356
}
5457
cw := &consoleWriter{
55-
w: w,
58+
Writer: w,
5659
format: format,
5760
}
5861
cw.red = noColor()
@@ -81,3 +84,17 @@ func newConsoleWriter(w io.Writer, format OutputFormat, disableColor bool) *cons
8184
}
8285
return cw
8386
}
87+
88+
func (w *consoleWriter) FormatAction(action parse.Action) string {
89+
s := strings.ToUpper(action.String())
90+
switch action {
91+
case parse.ActionPass:
92+
return w.green(s)
93+
case parse.ActionSkip:
94+
return w.yellow(s)
95+
case parse.ActionFail:
96+
return w.red(s)
97+
default:
98+
return s
99+
}
100+
}

internal/app/table_failed.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (c *consoleWriter) printFailed(packages []*parse.Package) {
2929
// TODO(mf): document why panics are handled separately. A panic may or may
3030
// not be associated with tests, so we print it at the package level.
3131
output := c.prepareStyledPanic(pkg.Summary.Package, pkg.Summary.Test, pkg.PanicEvents, width)
32-
fmt.Fprintln(c.w, output)
32+
fmt.Fprintln(c, output)
3333
continue
3434
}
3535
failedTests := pkg.TestsByAction(parse.ActionFail)
@@ -40,8 +40,8 @@ func (c *consoleWriter) printFailed(packages []*parse.Package) {
4040
pkg.Summary.Action.String(),
4141
pkg.Summary.Package,
4242
)
43-
fmt.Fprintln(c.w, styledPackageHeader)
44-
fmt.Fprintln(c.w)
43+
fmt.Fprintln(c, styledPackageHeader)
44+
fmt.Fprintln(c)
4545
/*
4646
Failed tests are all the individual tests, where the subtests are not separated.
4747
@@ -75,20 +75,20 @@ func (c *consoleWriter) printFailed(packages []*parse.Package) {
7575
*/
7676

7777
if c.format == OutputFormatMarkdown {
78-
fmt.Fprintln(c.w, fencedCodeBlock)
78+
fmt.Fprintln(c, fencedCodeBlock)
7979
}
8080
var key string
8181
for i, t := range failedTests {
8282
// Add top divider to all tests except first one.
8383
base, _, _ := cut(t.Name, "/")
8484
if i > 0 && key != base {
85-
fmt.Fprintln(c.w, divider.String())
85+
fmt.Fprintln(c, divider.String())
8686
}
8787
key = base
88-
fmt.Fprintln(c.w, c.prepareStyledTest(t))
88+
fmt.Fprintln(c, c.prepareStyledTest(t))
8989
}
9090
if c.format == OutputFormatMarkdown {
91-
fmt.Fprint(c.w, fencedCodeBlock+"\n\n")
91+
fmt.Fprint(c, fencedCodeBlock+"\n\n")
9292
}
9393
}
9494
}

internal/app/table_summary.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,7 @@ func (c *consoleWriter) summaryTable(
167167
}
168168
}
169169

170-
status := strings.ToUpper(pkg.Summary.Action.String())
171-
switch pkg.Summary.Action {
172-
case parse.ActionPass:
173-
status = c.green(status)
174-
case parse.ActionSkip:
175-
status = c.yellow(status)
176-
case parse.ActionFail:
177-
status = c.red(status)
178-
}
170+
status := c.FormatAction(pkg.Summary.Action)
179171

180172
// Skip packages with no coverage to mimic nocoverageredesign behavior (changed in github.com/golang/go/issues/24570)
181173
totalTests := len(pkg.TestsByAction(parse.ActionPass)) + len(pkg.TestsByAction(parse.ActionFail)) + len(pkg.TestsByAction(parse.ActionSkip))
@@ -212,7 +204,7 @@ func (c *consoleWriter) summaryTable(
212204
}
213205
}
214206

215-
fmt.Fprintln(c.w, tbl.Data(data).Render())
207+
fmt.Fprintln(c, tbl.Data(data).Render())
216208
}
217209

218210
type summaryRow struct {

internal/app/table_tests.go

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,7 @@ func (c *consoleWriter) testsTable(packages []*parse.Package, option TestTableOp
9090

9191
testName := shortenTestName(t.Name, option.Trim, 32)
9292

93-
status := strings.ToUpper(t.Status().String())
94-
switch t.Status() {
95-
case parse.ActionPass:
96-
status = c.green(status)
97-
case parse.ActionSkip:
98-
status = c.yellow(status)
99-
case parse.ActionFail:
100-
status = c.red(status)
101-
}
102-
93+
status := c.FormatAction(t.Status())
10394
packageName := shortenPackageName(t.Package, packagePrefix, 16, option.Trim, option.TrimPath)
10495

10596
row := testRow{
@@ -117,7 +108,7 @@ func (c *consoleWriter) testsTable(packages []*parse.Package, option TestTableOp
117108
}
118109

119110
if data.Rows() > 0 {
120-
fmt.Fprintln(c.w, tbl.Data(data).Render())
111+
fmt.Fprintln(c, tbl.Data(data).Render())
121112
}
122113
}
123114

@@ -159,24 +150,16 @@ func (c *consoleWriter) testsTableMarkdown(packages []*parse.Package, option Tes
159150

160151
testName := shortenTestName(t.Name, option.Trim, 32)
161152

162-
status := strings.ToUpper(t.Status().String())
163-
switch t.Status() {
164-
case parse.ActionPass:
165-
status = c.green(status)
166-
case parse.ActionSkip:
167-
status = c.yellow(status)
168-
case parse.ActionFail:
169-
status = c.red(status)
170-
}
153+
status := c.FormatAction(t.Status())
171154
data.Append([]string{
172155
status,
173156
strconv.FormatFloat(t.Elapsed(), 'f', 2, 64),
174157
testName,
175158
})
176159
}
177160
if data.Rows() > 0 {
178-
fmt.Fprintf(c.w, "## 📦 Package **`%s`**\n", pkg.Summary.Package)
179-
fmt.Fprintln(c.w)
161+
fmt.Fprintf(c, "## 📦 Package **`%s`**\n", pkg.Summary.Package)
162+
fmt.Fprintln(c)
180163

181164
msg := fmt.Sprintf("Tests: ✓ %d passed | %d skipped | %d failed\n",
182165
pkgTests.passedCount,
@@ -189,18 +172,18 @@ func (c *consoleWriter) testsTableMarkdown(packages []*parse.Package, option Tes
189172
pkgTests.passedCount,
190173
)
191174
}
192-
fmt.Fprint(c.w, msg)
193-
194-
fmt.Fprintln(c.w)
195-
fmt.Fprintln(c.w, "<details>")
196-
fmt.Fprintln(c.w)
197-
fmt.Fprintln(c.w, "<summary>Click for test summary</summary>")
198-
fmt.Fprintln(c.w)
199-
fmt.Fprintln(c.w, tbl.Data(data).Render())
200-
fmt.Fprintln(c.w, "</details>")
201-
fmt.Fprintln(c.w)
175+
fmt.Fprint(c, msg)
176+
177+
fmt.Fprintln(c)
178+
fmt.Fprintln(c, "<details>")
179+
fmt.Fprintln(c)
180+
fmt.Fprintln(c, "<summary>Click for test summary</summary>")
181+
fmt.Fprintln(c)
182+
fmt.Fprintln(c, tbl.Data(data).Render())
183+
fmt.Fprintln(c, "</details>")
184+
fmt.Fprintln(c)
202185
}
203-
fmt.Fprintln(c.w)
186+
fmt.Fprintln(c)
204187
}
205188
}
206189

parse/process.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ func Process(r io.Reader, optionsFunc ...OptionsFunc) (*GoTestSummary, error) {
142142

143143
// printProgress prints a single summary line for each PASS or FAIL package.
144144
// This is useful for long-running test suites.
145-
func printProgress(w io.Writer, e *Event, summary map[string]*Package) {
145+
func printProgress(w progressWriter, e *Event, summary map[string]*Package) {
146146
if !e.LastLine() {
147147
return
148148
}
@@ -174,7 +174,7 @@ func printProgress(w io.Writer, e *Event, summary map[string]*Package) {
174174
//
175175
// We modify this output slightly so it's more consistent and easier to parse.
176176
fmt.Fprintf(w, "[%s]\t%10s\t%s%s\n",
177-
strings.ToUpper(action.String()),
177+
w.FormatAction(action),
178178
strconv.FormatFloat(e.Elapsed, 'f', 2, 64)+"s",
179179
e.Package,
180180
suffix,

parse/process_options.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import (
44
"io"
55
)
66

7+
type progressWriter interface {
8+
io.Writer
9+
FormatAction(Action) string
10+
}
11+
712
type options struct {
813
w io.Writer
914
follow bool
1015
followVerbose bool
1116
debug bool
1217

1318
progress bool
14-
progressOutput io.Writer
19+
progressOutput progressWriter
1520
}
1621

1722
type OptionsFunc func(o *options)
@@ -36,6 +41,6 @@ func WithProgress(b bool) OptionsFunc {
3641
return func(o *options) { o.progress = b }
3742
}
3843

39-
func WithProgressOutput(w io.Writer) OptionsFunc {
44+
func WithProgressOutput(w progressWriter) OptionsFunc {
4045
return func(o *options) { o.progressOutput = w }
4146
}

0 commit comments

Comments
 (0)