Skip to content

Commit

Permalink
table: ColumnConfig.WidthMaxEnforcer to customize WidthMax impl; fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jedib0t committed May 8, 2020
1 parent 9e7d9ee commit ecc96bf
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 8 deletions.
17 changes: 15 additions & 2 deletions table/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
68 changes: 68 additions & 0 deletions table/config_test.go
Original file line number Diff line number Diff line change
@@ -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))
})
}
3 changes: 2 additions & 1 deletion table/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions table/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package table

import (
"fmt"
"os"
"sort"
"strings"
"testing"
Expand Down Expand Up @@ -72,7 +71,6 @@ func TestTable_Render(t *testing.T) {
[< >|< >|<TOTAL >|< 10000>|< >]
\-----v------------v-----------v--------v-----------------------------/
A Song of Ice and Fire`
fmt.Println(tw.Render())
assert.Equal(t, expectedOut, tw.Render())
}

Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down
12 changes: 11 additions & 1 deletion table/util.go
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
}

0 comments on commit ecc96bf

Please sign in to comment.