refactor(output): reorganize table formatter and improve test robustness

- Move empty slice check before table writer creation for early exit
- Fix error message typo: "ascii w" → "table"
- Enhance boolean test to dynamically locate data rows instead of hardcoded indices
This commit is contained in:
Andras Bacsai
2026-03-20 18:14:04 +01:00
parent 333ff3c504
commit ea4bec7492
2 changed files with 35 additions and 23 deletions
+17 -6
View File
@@ -210,12 +210,23 @@ func TestTableFormatter_BooleanValues(t *testing.T) {
output := buf.String()
// Check boolean formatting
lines := strings.Split(output, "\n")
assert.Contains(t, lines[3], "true")
assert.Contains(t, lines[3], "false")
assert.Contains(t, lines[4], "false")
assert.Contains(t, lines[4], "true")
// Check boolean formatting - verify both rows contain expected values
// Row 1: test1, true, false
assert.Contains(t, output, "test1")
assert.Contains(t, output, "test2")
// Find lines containing test data (not headers/borders)
var dataLines []string
for _, line := range strings.Split(output, "\n") {
if strings.Contains(line, "test1") || strings.Contains(line, "test2") {
dataLines = append(dataLines, line)
}
}
require.Len(t, dataLines, 2, "expected exactly 2 data rows")
assert.Contains(t, dataLines[0], "true")
assert.Contains(t, dataLines[0], "false")
assert.Contains(t, dataLines[1], "true")
assert.Contains(t, dataLines[1], "false")
}
func TestTableFormatter_NilPointer(t *testing.T) {
+18 -17
View File
@@ -20,16 +20,6 @@ func NewTableFormatter(opts Options) *TableFormatter {
}
func (f *TableFormatter) Format(data any) (err error) {
w := tablewriter.NewWriter(f.opts.Writer)
defer func() {
if renderErr := w.Render(); renderErr != nil && err == nil {
err = fmt.Errorf("failed to render ascii w: %w", renderErr)
}
}()
// disable ALL CAPS for column headers
w.Options(tablewriter.WithHeaderAutoFormat(tw.Off))
// Handle different data types
val := reflect.ValueOf(data)
@@ -38,6 +28,24 @@ func (f *TableFormatter) Format(data any) (err error) {
val = val.Elem()
}
// Check for empty slice/array before creating the table writer
if (val.Kind() == reflect.Slice || val.Kind() == reflect.Array) && val.Len() == 0 {
if _, writeErr := fmt.Fprintln(f.opts.Writer, "No data"); writeErr != nil {
return fmt.Errorf("failed to write no data message: %w", writeErr)
}
return nil
}
w := tablewriter.NewWriter(f.opts.Writer)
defer func() {
if renderErr := w.Render(); renderErr != nil && err == nil {
err = fmt.Errorf("failed to render table: %w", renderErr)
}
}()
// disable ALL CAPS for column headers
w.Options(tablewriter.WithHeaderAutoFormat(tw.Off))
switch val.Kind() {
case reflect.Slice, reflect.Array:
return f.formatSlice(w, val)
@@ -52,13 +60,6 @@ func (f *TableFormatter) Format(data any) (err error) {
// formatSlice formats a slice of structs as a table
func (f *TableFormatter) formatSlice(w *tablewriter.Table, val reflect.Value) error {
if val.Len() == 0 {
if _, err := fmt.Fprintln(f.opts.Writer, "No data"); err != nil {
return fmt.Errorf("failed to write no data message: %w", err)
}
return nil
}
// Get the first element to determine columns
firstElem := val.Index(0)
if firstElem.Kind() == reflect.Ptr {