refactor: remove NO_COLOR env option

This commit is contained in:
2026-03-25 19:49:10 +00:00
parent be4c143b9d
commit 952211ef93
6 changed files with 37 additions and 59 deletions
+4 -8
View File
@@ -4,6 +4,8 @@ import (
"bytes" "bytes"
"strings" "strings"
"testing" "testing"
"mire/internal/testutil"
) )
func TestFirstMismatchingLineReturnsFirstChangedLine(t *testing.T) { func TestFirstMismatchingLineReturnsFirstChangedLine(t *testing.T) {
@@ -110,8 +112,6 @@ func TestCompareOutputDoesNotIgnoreMissingLine(t *testing.T) {
} }
func TestWriteScenarioMismatchPrintsOnlyFirstMismatch(t *testing.T) { func TestWriteScenarioMismatchPrintsOnlyFirstMismatch(t *testing.T) {
t.Setenv("NO_COLOR", "1")
var buf bytes.Buffer var buf bytes.Buffer
writeScenarioMismatch(&buf, &testMismatchError{ writeScenarioMismatch(&buf, &testMismatchError{
expected: []byte("$ echo x\nx\n$ \nexit\n"), expected: []byte("$ echo x\nx\n$ \nexit\n"),
@@ -123,7 +123,7 @@ func TestWriteScenarioMismatchPrintsOnlyFirstMismatch(t *testing.T) {
}, },
}) })
got := buf.String() got := testutil.StripANSI(buf.String())
for _, want := range []string{ for _, want := range []string{
"Expected\n", "Expected\n",
"$ echo x\n", "$ echo x\n",
@@ -146,8 +146,6 @@ func TestWriteScenarioMismatchPrintsOnlyFirstMismatch(t *testing.T) {
} }
func TestWriteScenarioMismatchFormatsMissingLine(t *testing.T) { func TestWriteScenarioMismatchFormatsMissingLine(t *testing.T) {
t.Setenv("NO_COLOR", "1")
var buf bytes.Buffer var buf bytes.Buffer
writeScenarioMismatch(&buf, &testMismatchError{ writeScenarioMismatch(&buf, &testMismatchError{
expected: []byte("alpha\nbeta\n"), expected: []byte("alpha\nbeta\n"),
@@ -159,7 +157,7 @@ func TestWriteScenarioMismatchFormatsMissingLine(t *testing.T) {
}, },
}) })
got := buf.String() got := testutil.StripANSI(buf.String())
if !strings.Contains(got, "beta\n") { if !strings.Contains(got, "beta\n") {
t.Fatalf("writeScenarioMismatch() output = %q, want expected mismatching line", got) t.Fatalf("writeScenarioMismatch() output = %q, want expected mismatching line", got)
} }
@@ -169,8 +167,6 @@ func TestWriteScenarioMismatchFormatsMissingLine(t *testing.T) {
} }
func TestWriteScenarioMismatchItalicizesLabels(t *testing.T) { func TestWriteScenarioMismatchItalicizesLabels(t *testing.T) {
t.Setenv("NO_COLOR", "")
var buf bytes.Buffer var buf bytes.Buffer
writeScenarioMismatch(&buf, &testMismatchError{ writeScenarioMismatch(&buf, &testMismatchError{
expected: []byte("alpha\n"), expected: []byte("alpha\n"),
+3 -2
View File
@@ -70,13 +70,14 @@ func TestRewriteContinuesAfterFailureAndReturnsError(t *testing.T) {
if !strings.Contains(err.Error(), "1 scenario(s) failed to rewrite") { if !strings.Contains(err.Error(), "1 scenario(s) failed to rewrite") {
t.Fatalf("rewrite() error = %q, want failed rewrite summary", err.Error()) t.Fatalf("rewrite() error = %q, want failed rewrite summary", err.Error())
} }
normalizedStdout := testutil.StripANSI(stdout.String())
for _, want := range []string{ for _, want := range []string{
"FAIL bad (", "FAIL bad (",
"PASS ok (", "PASS ok (",
"Summary: total=2 passed=1 failed=1", "Summary: total=2 passed=1 failed=1",
} { } {
if !strings.Contains(stdout.String(), want) { if !strings.Contains(normalizedStdout, want) {
t.Fatalf("stdout = %q, want substring %q", stdout.String(), want) t.Fatalf("stdout = %q, want substring %q", normalizedStdout, want)
} }
} }
if got := testutil.ReadFile(t, filepath.Join(testDir, "bad", "out")); got != "stale bad\n" { if got := testutil.ReadFile(t, filepath.Join(testDir, "bad", "out")); got != "stale bad\n" {
-4
View File
@@ -52,10 +52,6 @@ func Label(text string, color Color) string {
return label(text, color) return label(text, color)
} }
func noColor() bool {
return os.Getenv("NO_COLOR") != ""
}
func prefix() string { func prefix() string {
chevron := NewStyle().FG(palette.chevronTeal).Bold().Italic().Apply("") chevron := NewStyle().FG(palette.chevronTeal).Bold().Italic().Apply("")
return NewStyle().FG(palette.mireGreen).Bold().Italic().Apply("mire") + " " + chevron + " " return NewStyle().FG(palette.mireGreen).Bold().Italic().Apply("mire") + " " + chevron + " "
+20 -40
View File
@@ -1,14 +1,11 @@
package output package output
import ( import (
"os"
"strings" "strings"
"testing" "testing"
) )
func TestFormatIncludesANSIByDefault(t *testing.T) { func TestFormatIncludesANSI(t *testing.T) {
t.Setenv("NO_COLOR", "")
got := Format("hello\n") got := Format("hello\n")
if !strings.Contains(got, "\x1b[") { if !strings.Contains(got, "\x1b[") {
t.Fatalf("Format() = %q, want ANSI styling", got) t.Fatalf("Format() = %q, want ANSI styling", got)
@@ -18,41 +15,24 @@ func TestFormatIncludesANSIByDefault(t *testing.T) {
} }
} }
func TestFormatPlainWhenNoColorSet(t *testing.T) { func TestLabelIncludesANSI(t *testing.T) {
t.Setenv("NO_COLOR", "1") for _, tc := range []struct {
name string
if got := Format("hello\n"); got != "mire hello\n" { text string
t.Fatalf("Format() = %q, want %q", got, "mire hello\n") color Color
} }{
} {name: "info", text: "RUN", color: Info},
{name: "pass", text: "PASS", color: Pass},
func TestLabelsPlainWhenNoColorSet(t *testing.T) { {name: "fail", text: "FAIL", color: Fail},
t.Setenv("NO_COLOR", "1") } {
t.Run(tc.name, func(t *testing.T) {
if got := Label("RUN", Info); got != "RUN" { got := Label(tc.text, tc.color)
t.Fatalf("Label() = %q, want %q", got, "RUN") if !strings.Contains(got, "\x1b[") {
} t.Fatalf("Label() = %q, want ANSI styling", got)
if got := Label("PASS", Pass); got != "PASS" { }
t.Fatalf("Label() = %q, want %q", got, "PASS") if !strings.Contains(got, tc.text) {
} t.Fatalf("Label() = %q, want text %q", got, tc.text)
if got := Label("FAIL", Fail); got != "FAIL" { }
t.Fatalf("Label() = %q, want %q", got, "FAIL") })
}
}
func TestFormatReadsNoColorAtRuntime(t *testing.T) {
t.Setenv("NO_COLOR", "")
styled := Format("hello\n")
if err := os.Setenv("NO_COLOR", "1"); err != nil {
t.Fatalf("Setenv() error = %v", err)
}
plain := Format("hello\n")
if !strings.Contains(styled, "\x1b[") {
t.Fatalf("styled Format() = %q, want ANSI styling", styled)
}
if plain != "mire hello\n" {
t.Fatalf("plain Format() = %q, want %q", plain, "mire hello\n")
} }
} }
+1 -1
View File
@@ -40,7 +40,7 @@ func (s Style) BG(rgb uint32) Style {
} }
func (s Style) Apply(text string) string { func (s Style) Apply(text string) string {
if noColor() || (!s.bold && !s.italic && s.fg == nil && s.bg == nil) { if !s.bold && !s.italic && s.fg == nil && s.bg == nil {
return text return text
} }
+9 -4
View File
@@ -6,14 +6,16 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
"sync" "sync"
"testing" "testing"
) )
var ansiRegexp = regexp.MustCompile(`\x1b\[[0-9;]*[A-Za-z]`)
func CaptureOutput(t *testing.T, fn func()) (string, string) { func CaptureOutput(t *testing.T, fn func()) (string, string) {
t.Helper() t.Helper()
t.Setenv("NO_COLOR", "1")
stdoutReader, stdoutWriter, err := os.Pipe() stdoutReader, stdoutWriter, err := os.Pipe()
if err != nil { if err != nil {
@@ -52,12 +54,11 @@ func CaptureOutput(t *testing.T, fn func()) (string, string) {
t.Fatalf("stderr copy error = %v", err) t.Fatalf("stderr copy error = %v", err)
} }
return stdoutBuf.String(), stderrBuf.String() return StripANSI(stdoutBuf.String()), StripANSI(stderrBuf.String())
} }
func CapturePromptedOutput(t *testing.T, sessionInput, promptMarker, promptInput string, fn func()) (string, string) { func CapturePromptedOutput(t *testing.T, sessionInput, promptMarker, promptInput string, fn func()) (string, string) {
t.Helper() t.Helper()
t.Setenv("NO_COLOR", "1")
stdinReader, stdinWriter, err := os.Pipe() stdinReader, stdinWriter, err := os.Pipe()
if err != nil { if err != nil {
@@ -159,7 +160,11 @@ func CapturePromptedOutput(t *testing.T, sessionInput, promptMarker, promptInput
t.Fatalf("stderr copy error = %v", err) t.Fatalf("stderr copy error = %v", err)
} }
return stdoutBuf.String(), stderrBuf.String() return StripANSI(stdoutBuf.String()), StripANSI(stderrBuf.String())
}
func StripANSI(text string) string {
return ansiRegexp.ReplaceAllString(text, "")
} }
func WriteFile(t *testing.T, path, content string) { func WriteFile(t *testing.T, path, content string) {