feat(06-01): add Formatter interface, Registry, and TTY color detection

- pkg/output/formatter.go: Formatter interface, Options, Registry with
  Register/Get/Names, ErrUnknownFormat sentinel
- pkg/output/colors.go: IsTTY + ColorsEnabled honoring NO_COLOR
- Promote github.com/mattn/go-isatty to direct dependency
- Unit tests cover registry round-trip, unknown lookup, sorted Names,
  non-TTY buffer, NO_COLOR override

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
salvacybersec
2026-04-05 18:41:23 +03:00
parent ce37ee2bc5
commit 291c97ed0b
5 changed files with 205 additions and 1 deletions

37
pkg/output/colors_test.go Normal file
View File

@@ -0,0 +1,37 @@
package output
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
)
func TestColorsEnabled_BufferIsNotTTY(t *testing.T) {
t.Setenv("NO_COLOR", "")
// Explicitly unset NO_COLOR so the non-TTY branch is exercised.
t.Setenv("NO_COLOR", "")
assert.False(t, ColorsEnabled(&bytes.Buffer{}), "bytes.Buffer must never be considered a TTY")
}
func TestColorsEnabled_NoColorEnvForcesOff(t *testing.T) {
t.Setenv("NO_COLOR", "1")
assert.False(t, ColorsEnabled(&bytes.Buffer{}))
}
func TestColorsEnabled_NilWriterSafe(t *testing.T) {
t.Setenv("NO_COLOR", "")
// A nil *os.File should return false, not panic.
var f *nilWriter
assert.False(t, ColorsEnabled(f))
}
// nilWriter is a typed-nil io.Writer used to verify ColorsEnabled does not
// panic when passed a non-*os.File writer.
type nilWriter struct{}
func (*nilWriter) Write(p []byte) (int, error) { return len(p), nil }
func TestIsTTY_NilFile(t *testing.T) {
assert.False(t, IsTTY(nil))
}