Skip to content

Commit 0be1ea6

Browse files
committed
Add option to limit the number of rows in table
Sometimes, the table is rendered externally or with few outside parameters and turns out to be too long to be displayed properly. It requires some slice modifications in order to truncate the list and to introduce an ellipsis to indicate that the table row count was reduced. Add table option to tell the table renderer a limit on how many rows should be added to the final result. An ellipsis is added to indicate that the number of rows was truncated.
1 parent d481292 commit 0be1ea6

File tree

4 files changed

+70
-20
lines changed

4 files changed

+70
-20
lines changed

go.sum

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
21
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
32
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
43
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
5-
github.com/gonvenience/bunt v1.0.6 h1:b3KEkaSlbXx3m4s2Gg5NfKkbo3YR3daCbqeecbDG9IE=
6-
github.com/gonvenience/bunt v1.0.6/go.mod h1:lsyhkmNpSAzhVx059BD0fQy5F29rWcS6AHb7UWNlT/s=
7-
github.com/gonvenience/bunt v1.0.7 h1:g4xg5OlNNNGNnwRZ/F4r3inRgnbfrbjnw1lO4BODmb4=
8-
github.com/gonvenience/bunt v1.0.7/go.mod h1:lsyhkmNpSAzhVx059BD0fQy5F29rWcS6AHb7UWNlT/s=
9-
github.com/gonvenience/bunt v1.1.0 h1:jKaW7wwtIS1pW29ykowAv1m5TdSo47uZgtZRGD4ss2c=
10-
github.com/gonvenience/bunt v1.1.0/go.mod h1:lsyhkmNpSAzhVx059BD0fQy5F29rWcS6AHb7UWNlT/s=
114
github.com/gonvenience/bunt v1.1.1 h1:isYxOpDqbRMOSRhZtoux1tYvhhQ/AIbVDFrs24l6t0M=
125
github.com/gonvenience/bunt v1.1.1/go.mod h1:lsyhkmNpSAzhVx059BD0fQy5F29rWcS6AHb7UWNlT/s=
136
github.com/gonvenience/term v1.0.0 h1:joCB/j0Ngmdakd3muuLgAGPMf7DNKdoe708c1I6RiBs=
147
github.com/gonvenience/term v1.0.0/go.mod h1:wohD4Iqso9Eol7qc2VnNhSFFhZxok5PvO7pZhdrAn4E=
15-
github.com/gonvenience/wrap v1.0.0 h1:N1zDI7z/uPd5ZQa8jII/ye/VENy3wgLXG962vw3ytMM=
16-
github.com/gonvenience/wrap v1.0.0/go.mod h1:L47Cm1sK1G8QmFAYQfkHcF/sQ1IBJUa0u4sjqiLqPdM=
178
github.com/gonvenience/wrap v1.1.0 h1:d8gEZrXS/zg4BC1q0U4nHpPIh5k6muKpQ1+rQFBwpYc=
189
github.com/gonvenience/wrap v1.1.0/go.mod h1:L47Cm1sK1G8QmFAYQfkHcF/sQ1IBJUa0u4sjqiLqPdM=
1910
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
@@ -27,16 +18,10 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
2718
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 h1:kw1v0NlnN+GZcU8Ma8CLF2Zzgjfx95gs3/GN3vYAPpo=
2819
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
2920
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
30-
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
3121
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
32-
github.com/onsi/ginkgo v1.9.0 h1:SZjF721BByVj8QH636/8S2DnX4n0Re3SteMmw3N+tzc=
33-
github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
3422
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
3523
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
36-
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
3724
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
38-
github.com/onsi/gomega v1.6.0 h1:8XTW0fcJZEq9q+Upcyws4JSGua2MFysCL5xkaSgHc+M=
39-
github.com/onsi/gomega v1.6.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
4025
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
4126
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
4227
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
@@ -55,7 +40,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5
5540
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5641
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
5742
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
58-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
5943
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6044
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
6145
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

table.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type options struct {
4747
columnAlignment []Alignment
4848
errors []error
4949
omitLinefeedAtEnd bool
50+
rowLimit int
5051
}
5152

5253
func defaultOptions(cols int) options {
@@ -62,6 +63,7 @@ func defaultOptions(cols int) options {
6263
columnAlignment: alignments,
6364
errors: []error{},
6465
omitLinefeedAtEnd: false,
66+
rowLimit: -1,
6567
}
6668
}
6769

@@ -119,6 +121,13 @@ func OmitLinefeedAtTableEnd() TableOption {
119121
}
120122
}
121123

124+
// LimitRows sets a limit at which point the table is truncated
125+
func LimitRows(limit int) TableOption {
126+
return func(opts *options) {
127+
opts.rowLimit = limit
128+
}
129+
}
130+
122131
// Table renders a string with a well spaced and aligned table output
123132
func Table(table [][]string, tableOptions ...TableOption) (string, error) {
124133
maxs, err := lookupMaxLengthPerColumn(table)
@@ -138,11 +147,22 @@ func Table(table [][]string, tableOptions ...TableOption) (string, error) {
138147
}
139148

140149
var (
141-
buf bytes.Buffer
142-
lastIdx int = len(table) - 1
150+
buf bytes.Buffer
151+
idx int = 0
152+
rowLimit int = len(table)
143153
)
144154

145-
for i, row := range table {
155+
if options.rowLimit >= 0 {
156+
rowLimit = options.rowLimit
157+
}
158+
159+
if rowLimit > len(table) {
160+
return "", &RowLimitExceedsTableSize{Limit: rowLimit, Rows: len(table)}
161+
}
162+
163+
for ; idx < rowLimit; idx++ {
164+
row := table[idx]
165+
146166
if options.desiredRowWidth > 0 {
147167
rawRowWidth := lookupPlainRowLength(row, maxs, options.separator)
148168

@@ -190,7 +210,13 @@ func Table(table [][]string, tableOptions ...TableOption) (string, error) {
190210
// Make sure to add a linefeed to the end of each line, unless it is
191211
// the last line of the table and the settings indicate that there must
192212
// be no linefeed at the last line
193-
if lastline := i >= lastIdx; !lastline || !options.omitLinefeedAtEnd {
213+
if lastline := idx >= rowLimit-1; !lastline || !options.omitLinefeedAtEnd {
214+
// Special case in which the number of table rows is limited, add an
215+
// ellipsis to indicate the truncation
216+
if lastline && rowLimit >= 0 && rowLimit < len(table) {
217+
buf.WriteString("\n[...]")
218+
}
219+
194220
buf.WriteString("\n")
195221
}
196222
}

table_error.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,14 @@ type ColumnIndexIsOutOfBoundsError struct {
5454
func (e *ColumnIndexIsOutOfBoundsError) Error() string {
5555
return fmt.Sprintf("unable to render table, the provided column index %d is out of bounds", e.ColumnIdx)
5656
}
57+
58+
// RowLimitExceedsTableSize is used to describe that the specified maximum row
59+
// number exceeds the actual number of rows in the table
60+
type RowLimitExceedsTableSize struct {
61+
Limit int
62+
Rows int
63+
}
64+
65+
func (e *RowLimitExceedsTableSize) Error() string {
66+
return fmt.Sprintf("unable to render table, the provided row limit of %d exceeds the number of rows %d", e.Limit, e.Rows)
67+
}

table_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,5 +168,34 @@ un deux trois`
168168
Expect(err).ToNot(HaveOccurred())
169169
Expect(tableString).To(BeEquivalentTo(expectedResult))
170170
})
171+
172+
It("should be possible to limit the number of rows", func() {
173+
input := [][]string{
174+
{"eins", "zwei", "drei"},
175+
{"one", "two", "three"},
176+
{"un", "deux", "trois"},
177+
}
178+
179+
expectedResult := `eins zwei drei
180+
one two three
181+
[...]
182+
`
183+
184+
tableString, err := Table(input, LimitRows(2))
185+
Expect(err).ToNot(HaveOccurred())
186+
Expect(tableString).To(BeEquivalentTo(expectedResult))
187+
})
188+
189+
It("should fail when using an invalid row limit", func() {
190+
input := [][]string{
191+
{"eins", "zwei", "drei"},
192+
{"one", "two", "three"},
193+
{"un", "deux", "trois"},
194+
}
195+
196+
tableString, err := Table(input, LimitRows(4))
197+
Expect(err).Should(MatchError(&RowLimitExceedsTableSize{4, 3}))
198+
Expect(tableString).To(BeEquivalentTo(""))
199+
})
171200
})
172201
})

0 commit comments

Comments
 (0)