diff --git a/table/config.go b/table/config.go index 50bb764..523de82 100644 --- a/table/config.go +++ b/table/config.go @@ -50,8 +50,21 @@ type ColumnConfig struct { // VAlignHeader defines the vertical alignment in Header rows VAlignHeader text.VAlign - // WidthMin defines the minimum character length of the column - WidthMin int // WidthMax defines the maximum character length of the column WidthMax int + // WidthEnforcer enforces the WidthMax value on the column contents; + // default: text.WrapText + WidthMaxEnforcer WidthEnforcer + // WidthMin defines the minimum character length of the column + WidthMin int +} + +func (c ColumnConfig) getWidthMaxEnforcer() WidthEnforcer { + if c.WidthMax == 0 { + return widthEnforcerNone + } + if c.WidthMaxEnforcer != nil { + return c.WidthMaxEnforcer + } + return text.WrapText } diff --git a/table/config_test.go b/table/config_test.go new file mode 100644 index 0000000..a2558ce --- /dev/null +++ b/table/config_test.go @@ -0,0 +1,68 @@ +package table + +import ( + "testing" + + "github.com/jedib0t/go-pretty/text" + "github.com/stretchr/testify/assert" +) + +func TestColumnConfig_getWidthMaxEnforcer(t *testing.T) { + t.Run("no width enforcer", func(t *testing.T) { + cc := ColumnConfig{} + + widthEnforcer := cc.getWidthMaxEnforcer() + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 0)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 1)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 5)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 10)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 100)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 1000)) + }) + + t.Run("default width enforcer", func(t *testing.T) { + cc := ColumnConfig{ + WidthMax: 10, + } + + widthEnforcer := cc.getWidthMaxEnforcer() + assert.Equal(t, "", widthEnforcer("1234567890", 0)) + assert.Equal(t, "1\n2\n3\n4\n5\n6\n7\n8\n9\n0", widthEnforcer("1234567890", 1)) + assert.Equal(t, "12345\n67890", widthEnforcer("1234567890", 5)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 10)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 100)) + assert.Equal(t, "1234567890", widthEnforcer("1234567890", 1000)) + }) + + t.Run("custom width enforcer (1)", func(t *testing.T) { + cc := ColumnConfig{ + WidthMax: 10, + WidthMaxEnforcer: text.Trim, + } + + widthEnforcer := cc.getWidthMaxEnforcer() + assert.Equal(t, text.Trim("1234567890", 0), widthEnforcer("1234567890", 0)) + assert.Equal(t, text.Trim("1234567890", 1), widthEnforcer("1234567890", 1)) + assert.Equal(t, text.Trim("1234567890", 5), widthEnforcer("1234567890", 5)) + assert.Equal(t, text.Trim("1234567890", 10), widthEnforcer("1234567890", 10)) + assert.Equal(t, text.Trim("1234567890", 100), widthEnforcer("1234567890", 100)) + assert.Equal(t, text.Trim("1234567890", 1000), widthEnforcer("1234567890", 1000)) + }) + + t.Run("custom width enforcer (2)", func(t *testing.T) { + cc := ColumnConfig{ + WidthMax: 10, + WidthMaxEnforcer: func(col string, maxLen int) string { + return "foo" + }, + } + + widthEnforcer := cc.getWidthMaxEnforcer() + assert.Equal(t, "foo", widthEnforcer("1234567890", 0)) + assert.Equal(t, "foo", widthEnforcer("1234567890", 1)) + assert.Equal(t, "foo", widthEnforcer("1234567890", 5)) + assert.Equal(t, "foo", widthEnforcer("1234567890", 10)) + assert.Equal(t, "foo", widthEnforcer("1234567890", 100)) + assert.Equal(t, "foo", widthEnforcer("1234567890", 1000)) + }) +} diff --git a/table/render.go b/table/render.go index c6470ae..9dc7194 100644 --- a/table/render.go +++ b/table/render.go @@ -260,7 +260,8 @@ func (t *Table) renderRow(out *strings.Builder, rowNum int, row rowStr, hint ren colMaxLines := 0 rowWrapped := make(rowStr, len(row)) for colIdx, colStr := range row { - rowWrapped[colIdx] = text.WrapText(colStr, t.maxColumnLengths[colIdx]) + widthEnforcer := t.columnConfigMap[colIdx].getWidthMaxEnforcer() + rowWrapped[colIdx] = widthEnforcer(colStr, t.maxColumnLengths[colIdx]) colNumLines := strings.Count(rowWrapped[colIdx], "\n") + 1 if colNumLines > colMaxLines { colMaxLines = colNumLines diff --git a/table/render_test.go b/table/render_test.go index 7b5b98f..d962fef 100644 --- a/table/render_test.go +++ b/table/render_test.go @@ -2,7 +2,6 @@ package table import ( "fmt" - "os" "sort" "strings" "testing" @@ -72,7 +71,6 @@ func TestTable_Render(t *testing.T) { [< >|< >||< 10000>|< >] \-----v------------v-----------v--------v-----------------------------/ A Song of Ice and Fire` - fmt.Println(tw.Render()) assert.Equal(t, expectedOut, tw.Render()) } @@ -233,7 +231,6 @@ func TestTable_Render_Colored(t *testing.T) { tw.Style().Options.SeparateFooter = true tw.Style().Options.SeparateHeader = true tw.Style().Options.SeparateRows = true - tw.SetOutputMirror(os.Stdout) expectedOut := []string{ "\x1b[106;30m+\x1b[0m\x1b[106;30m---\x1b[0m\x1b[106;30m+\x1b[0m\x1b[106;30m-----\x1b[0m\x1b[106;30m+\x1b[0m\x1b[106;30m------------\x1b[0m\x1b[106;30m+\x1b[0m\x1b[106;30m-----------\x1b[0m\x1b[106;30m+\x1b[0m\x1b[106;30m--------\x1b[0m\x1b[106;30m+\x1b[0m\x1b[106;30m-----------------------------\x1b[0m\x1b[106;30m+\x1b[0m", @@ -398,7 +395,6 @@ func TestTable_Render_ColoredStyleAutoIndex(t *testing.T) { "\x1b[36;100m \x1b[0m\x1b[36;100m \x1b[0m\x1b[36;100m \x1b[0m\x1b[36;100m TOTAL \x1b[0m\x1b[36;100m 10000 \x1b[0m\x1b[36;100m \x1b[0m", }, "\n") out := table.Render() - fmt.Println(out) assert.Equal(t, expectedOut, out) // dump it out in a easy way to update the test if things are meant to diff --git a/table/util.go b/table/util.go index 7f93927..642b2a2 100644 --- a/table/util.go +++ b/table/util.go @@ -1,6 +1,8 @@ package table -import "reflect" +import ( + "reflect" +) // AutoIndexColumnID returns a unique Column ID/Name for the given Column Number. // The functionality is similar to what you get in an Excel spreadsheet w.r.t. @@ -25,3 +27,11 @@ func isNumber(x interface{}) bool { } return false } + +// WidthEnforcer is a function that helps enforce a width condition on a string. +type WidthEnforcer func(col string, maxLen int) string + +// widthEnforcerNone returns the input string as is without any modifications. +func widthEnforcerNone(col string, maxLen int) string { + return col +}