Codebase list golang-github-bndr-gotabulate / 990784f3-a71f-487f-9a9d-90b4fab2a52d/main
New upstream snapshot. Debian Janitor 2 years ago
11 changed file(s) with 354 addition(s) and 124 deletion(s). Raw diff Collapse all Expand all
44 - 1.3
55 - tip
66 install:
7 - go get github.com/stretchr/testify/assert
7 - go get github.com/stretchr/testify/assert
8 - go get github.com/mattn/go-runewidth
0 # Gotabulate - Easily tabulate Data
0 # Gotabulate - Easily pretty-print tabular data
11 [![GoDoc](https://godoc.org/github.com/bndr/gotabulate?status.svg)](https://godoc.org/github.com/bndr/gotabulate)
22 [![Build Status](https://travis-ci.org/bndr/gotabulate.svg?branch=master)](https://travis-ci.org/bndr/gotabulate)
33
44 ## Summary
55
6 Go-Tabulate - Generic Go Library for easy tabulation of your data.
6 Go-Tabulate - Generic Go Library for easy pretty-printing of tabular data.
77
88 ## Installation
99
1212 ## Description
1313
1414 Supported data types:
15 - 2D Array of Int, Int64, Float64, String, interface{}
16 - Map of String, interface{} (Keys will be used as header)
15 - 2D Array of `Int`, `Int64`, `Float64`, `String`, `interface{}`
16 - Map of `String`, `interface{}` (Keys will be used as header)
1717
1818 ## Usage
19 ```go
20
19
20 ```go
2121 // Create Some Fake Rows
2222 row_1 := []interface{}{"john", 20, "ready"}
2323 row_2 := []interface{}{"bndr", 23, "ready"}
4444 +---------+--------+-----------+
4545 | bndr | 23 | ready |
4646 +---------+--------+-----------+
47
4847 ```
4948
5049 ## Example with String
5150
52 ```
51 ```go
5352 // Some Strings
5453 string_1 := []string{"TV", "1000$", "Sold"}
5554 string_2 := []string{"PC", "50%", "on Hold"}
7069
7170 PC 50% on Hold
7271 --------- ---------- ------------
73
7472 ```
7573
7674 ## Example with String Wrapping
8078 "Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis", "zzLorem ipsum", " test", "test"}, []string{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis",
8179 "Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis", "zzLorem ipsum", " test", "test"}, STRING_ARRAY, []string{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis",
8280 "Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis", "zzLorem ipsum", " test", "test"}, STRING_ARRAY})
81
8382 tabulate.SetHeaders([]string{"Header 1", "header 2", "header 3", "header 4"})
8483 // Set Max Cell Size
8584 tabulate.SetMaxCellSize(16)
130129 +---------------------+---------------------+----------------+-------------+-------------+
131130 | test string | test string 2 | test | row | bndr |
132131 +---------------------+---------------------+----------------+-------------+-------------+
133
134132 ```
135133 ## Examples
136134
137 ```
135 ```go
138136 t := gotabulate.Create([][]string{STRING_ARRAY, STRING_ARRAY})
137
139138 t.SetHeaders(HEADERS) // If not headers are set, the first row will be used.
139
140140 t.SetEmptyString("None") // Set what will be printed in the empty cell
141
141142 rendered_string := t.Render("simple") // Render() will return a string
142143
143144 Simple Table
197198 ```
198199
199200 ### Status
201
200202 Beta version. There may be edge cases that I have missed, so if your tables don't render properly please open up an issue.
201203
202204 ## Contribute
207209
208210 Apache License 2.0
209211
210 ### TODO
211 - Add more examples
212 - Implement more data table formats
213
214 ### Acknowledgement
215
216 Inspired by Python package https://pypi.python.org/pypi/tabulate
212 ## TODO
213
214 - [ ] Add more examples
215 - [ ] Better Documentation
216 - [ ] Implement more data table formats
217 - [ ] Decimal point alignment for floats
218
219 ## Acknowledgement
220
221 Inspired by Python package [tabulate](https://pypi.python.org/pypi/tabulate)
0 +----------------------+----------------------+----------------------+-------------+-------------+
1 | Title One |
2 +----------------------+----------------------+----------------------+-------------+-------------+
3 | Header 1 | Header 2 | Header 3 | Header 4 | Header 5 |
4 +======================+======================+======================+=============+=============+
5 | test string | test string 2 | test | row | bndr |
6 +----------------------+----------------------+----------------------+-------------+-------------+
7 | test string | test string 2 | test | row | bndr |
8 +----------------------+----------------------+----------------------+-------------+-------------+
9 | 4th element empty | 4th element empty | 4th element empty | None | None |
10 +----------------------+----------------------+----------------------+-------------+-------------+
0
1 Make Titles Great Again
2
3 Header 1 Header 2 Header 3 Header 4 Header 5
4
5 test string test string 2 test row bndr
6
7 test string test string 2 test row bndr
8
9 4th element empty 4th element empty 4th element empty None None
10
0 ---------------------- ---------------------- ---------------------- ------------- -------------
1 Simple Title
2 ---------------------- ---------------------- ---------------------- ------------- -------------
3 Header 1 Header 2 Header 3 Header 4 Header 5
4 ---------------------- ---------------------- ---------------------- ------------- -------------
5 test string test string 2 test row bndr
6
7 test string test string 2 test row bndr
8
9 4th element empty 4th element empty 4th element empty None None
10 ---------------------- ---------------------- ---------------------- ------------- -------------
0 +-----------+-------------------------+
1 | header | value |
2 +===========+=========================+
3 | test1 | This is a really |
4 | | long string, yaaaay |
5 | | it works, Vivamus |
6 | | laoreet vestibulum |
7 | | pretium. Nulla et |
8 | | ornare elit. Cum |
9 | | sociis natoque |
10 | | penatibus et magnis |
11 | | Vivamus laoreet |
12 | | vestibulum pretium. |
13 | | Nulla et ornare |
14 | | elit. Cum sociis |
15 | | natoque penatibus et |
16 | | magnis |
17 +-----------+-------------------------+
18 | test2 | AAAAAAAAAAAAAAAAAAA- |
19 | | ABBBBBBBBBBBBBBBBBB- |
20 | | BBBBBBBCCCCCCCCCCCC- |
21 | | CCCCCCCCCCCCCEEEEEE- |
22 | | EEEEEEEEEEEEEEDDDDD- |
23 | | DDDDDDDDd |
24 +-----------+-------------------------+
0 +-----------+---------------+
1 | 時間帯 | 挨拶 |
2 +===========+===============+
3 | 朝 | おはようご |
4 | | ざいます |
5 +-----------+---------------+
6 | 昼 | こんにちわ |
7 +-----------+---------------+
8 | 夜 | こんばんわ |
9 +-----------+---------------+
0 golang-github-bndr-gotabulate (1.1.2+git20210209.1.21a495b-1) UNRELEASED; urgency=low
1
2 * New upstream snapshot.
3
4 -- Debian Janitor <janitor@jelmer.uk> Fri, 12 Nov 2021 10:42:37 -0000
5
06 golang-github-bndr-gotabulate (1.1.2-3) unstable; urgency=medium
17
28 [ Debian Janitor ]
00 package gotabulate
11
2 import "fmt"
3 import "bytes"
4 import "math"
2 import (
3 "bytes"
4 "fmt"
5 "math"
6 "unicode/utf8"
7
8 "github.com/mattn/go-runewidth"
9 )
510
611 // Basic Structure of TableFormat
712 type TableFormat struct {
1116 LineBottom Line
1217 HeaderRow Row
1318 DataRow Row
19 TitleRow Row
1420 Padding int
1521 HeaderHide bool
1622 FitScreen bool
4147 LineBottom: Line{"", "-", " ", ""},
4248 HeaderRow: Row{"", " ", ""},
4349 DataRow: Row{"", " ", ""},
50 TitleRow: Row{"", " ", ""},
4451 Padding: 1,
4552 },
4653 "plain": TableFormat{
4754 HeaderRow: Row{"", " ", ""},
4855 DataRow: Row{"", " ", ""},
56 TitleRow: Row{"", " ", ""},
4957 Padding: 1,
5058 },
5159 "grid": TableFormat{
5563 LineBottom: Line{"+", "-", "+", "+"},
5664 HeaderRow: Row{"|", "|", "|"},
5765 DataRow: Row{"|", "|", "|"},
66 TitleRow: Row{"|", " ", "|"},
5867 Padding: 1,
5968 },
6069 }
6473
6574 // Main Tabulate structure
6675 type Tabulate struct {
67 Data []*TabulateRow
68 Headers []string
69 FloatFormat byte
70 TableFormat TableFormat
71 Align string
72 EmptyVar string
73 HideLines []string
74 MaxSize int
75 WrapStrings bool
76 Data []*TabulateRow
77 Title string
78 TitleAlign string
79 Headers []string
80 FloatFormat byte
81 TableFormat TableFormat
82 Align string
83 EmptyVar string
84 HideLines []string
85 MaxSize int
86 WrapStrings bool
87 WrapDelimiter rune
88 SplitConcat string
89 DenseMode bool
7690 }
7791
7892 // Represents normalized tabulate Row
7993 type TabulateRow struct {
8094 Elements []string
8195 Continuos bool
82 Extra bool
96 }
97
98 type writeBuffer struct {
99 Buffer bytes.Buffer
100 }
101
102 func createBuffer() *writeBuffer {
103 return &writeBuffer{}
104 }
105
106 func (b *writeBuffer) Write(str string, count int) *writeBuffer {
107 for i := 0; i < count; i++ {
108 b.Buffer.WriteString(str)
109 }
110 return b
111 }
112 func (b *writeBuffer) String() string {
113 return b.Buffer.String()
83114 }
84115
85116 // Add padding to each cell
89120 }
90121 padded := make([]string, len(arr))
91122 for index, el := range arr {
92 var buffer bytes.Buffer
93 // Pad left
94 for i := 0; i < padding; i++ {
95 buffer.WriteString(" ")
96 }
97
98 buffer.WriteString(el)
99
100 // Pad Right
101 for i := 0; i < padding; i++ {
102 buffer.WriteString(" ")
103 }
104
105 padded[index] = buffer.String()
123 b := createBuffer()
124 b.Write(" ", padding)
125 b.Write(el, 1)
126 b.Write(" ", padding)
127 padded[index] = b.String()
106128 }
107129 return padded
108130 }
109131
110132 // Align right (Add padding left)
111133 func (t *Tabulate) padLeft(width int, str string) string {
112 var buffer bytes.Buffer
113 // Pad left
114 padding := width - len(str)
115 for i := 0; i < padding; i++ {
116 buffer.WriteString(" ")
117 }
118 buffer.WriteString(str)
119 return buffer.String()
134 b := createBuffer()
135 b.Write(" ", (width - runewidth.StringWidth(str)))
136 b.Write(str, 1)
137 return b.String()
120138 }
121139
122140 // Align Left (Add padding right)
123141 func (t *Tabulate) padRight(width int, str string) string {
124 var buffer bytes.Buffer
125 padding := width - len(str)
126
127 buffer.WriteString(str)
128
129 // Add Padding right
130 for i := 0; i < padding; i++ {
131 buffer.WriteString(" ")
132 }
133 return buffer.String()
142 b := createBuffer()
143 b.Write(str, 1)
144 b.Write(" ", (width - runewidth.StringWidth(str)))
145 return b.String()
134146 }
135147
136148 // Center the element in the cell
137149 func (t *Tabulate) padCenter(width int, str string) string {
138 var buffer bytes.Buffer
139 length := len(str)
140
141 padding := int(math.Ceil(float64((width - length)) / 2.0))
142
143 // Add padding left
144 for i := 0; i < padding; i++ {
145 buffer.WriteString(" ")
146 }
147
148 // Write string
149 buffer.WriteString(str)
150
151 // Calculate how much space is left
152 current := (width - len(buffer.String()))
153
154 // Add padding right
155 for i := 0; i < current; i++ {
156 buffer.WriteString(" ")
157 }
158 return buffer.String()
150 b := createBuffer()
151 padding := int(math.Ceil(float64((width - runewidth.StringWidth(str))) / 2.0))
152 b.Write(" ", padding)
153 b.Write(str, 1)
154 b.Write(" ", (width - runewidth.StringWidth(b.String())))
155
156 return b.String()
159157 }
160158
161159 // Build Line based on padded_widths from t.GetWidths()
163161 cells := make([]string, len(padded_widths))
164162
165163 for i, _ := range cells {
166 var buffer bytes.Buffer
167 for j := 0; j < padding[i]+MIN_PADDING; j++ {
168 buffer.WriteString(l.hline)
169 }
170 cells[i] = buffer.String()
171 }
164 b := createBuffer()
165 b.Write(l.hline, padding[i]+MIN_PADDING)
166 cells[i] = b.String()
167 }
168
172169 var buffer bytes.Buffer
173
174 // Print begin
175170 buffer.WriteString(l.begin)
176171
177172 // Print contents
178173 for i := 0; i < len(cells); i++ {
174 buffer.WriteString(cells[i])
179175 if i != len(cells)-1 {
180 buffer.WriteString(cells[i] + l.sep)
181 } else {
182 buffer.WriteString(cells[i])
183 }
184 }
185
186 // Print end
176 buffer.WriteString(l.sep)
177 }
178 }
179
187180 buffer.WriteString(l.end)
188181 return buffer.String()
189182 }
197190 // Print contents
198191 for i := 0; i < len(padded_widths); i++ {
199192 output := ""
200 if len(elements) > i {
193 if len(elements) <= i || (len(elements) > i && elements[i] == " nil ") {
194 output = padFunc(padded_widths[i], t.EmptyVar)
195 } else if len(elements) > i {
201196 output = padFunc(padded_widths[i], elements[i])
202 } else {
203 output = padFunc(padded_widths[i], t.EmptyVar)
204197 }
205198 buffer.WriteString(output)
206199 if i != len(padded_widths)-1 {
207200 buffer.WriteString(d.sep)
208201 }
209202 }
210 // Print end
203
211204 buffer.WriteString(d.end)
212
213205 return buffer.String()
206 }
207
208 //SetWrapDelimiter assigns the character ina string that the rednderer
209 //will attempt to split strings on when a cell must be wrapped
210 func (t *Tabulate) SetWrapDelimiter(r rune) {
211 t.WrapDelimiter = r
212 }
213
214 //SetSplitConcat assigns the character that will be used when a WrapDelimiter is
215 //set but the renderer cannot abide by the desired split. This may happen when
216 //the WrapDelimiter is a space ' ' but a single word is longer than the width of a cell
217 func (t *Tabulate) SetSplitConcat(r string) {
218 t.SplitConcat = r
214219 }
215220
216221 // Render the data table
218223 var lines []string
219224
220225 // If headers are set use them, otherwise pop the first row
221 if len(t.Headers) < 1 {
226 if len(t.Headers) < 1 && len(t.Data) > 1 {
222227 t.Headers, t.Data = t.Data[0].Elements, t.Data[1:]
223228 }
224229
235240
236241 // Check if Data is present
237242 if len(t.Data) < 1 {
238 panic("No Data specified")
243 return ""
239244 }
240245
241246 if len(t.Headers) < len(t.Data[0].Elements) {
255260 padded_widths[i] = cols[i] + MIN_PADDING*t.TableFormat.Padding
256261 }
257262
263 // Calculate total width of the table
264 totalWidth := len(t.TableFormat.DataRow.sep) * (len(cols) - 1) // Include all but the final separator
265 for _, w := range padded_widths {
266 totalWidth += w
267 }
268
258269 // Start appending lines
270 if len(t.Title) > 0 {
271 if !inSlice("aboveTitle", t.HideLines) {
272 lines = append(lines, t.buildLine(padded_widths, cols, t.TableFormat.LineTop))
273 }
274 savedAlign := t.Align
275 if len(t.TitleAlign) > 0 {
276 t.SetAlign(t.TitleAlign) // Temporary replace alignment with the title alignment
277 }
278 lines = append(lines, t.buildRow([]string{t.Title}, []int{totalWidth}, nil, t.TableFormat.TitleRow))
279 t.SetAlign(savedAlign)
280 }
259281
260282 // Append top line if not hidden
261283 if !inSlice("top", t.HideLines) {
273295 // Add Data Rows
274296 for index, element := range t.Data {
275297 lines = append(lines, t.buildRow(t.padRow(element.Elements, t.TableFormat.Padding), padded_widths, cols, t.TableFormat.DataRow))
276 if index < len(t.Data)-1 {
277 if element.Continuos != true {
298 if !t.DenseMode && index < len(t.Data)-1 {
299 if element.Continuos != true && !inSlice("betweenLine", t.HideLines) {
278300 lines = append(lines, t.buildLine(padded_widths, cols, t.TableFormat.LineBetweenRows))
279301 }
280302 }
298320 widths := make([]int, len(headers))
299321 current_max := len(t.EmptyVar)
300322 for i := 0; i < len(headers); i++ {
301 current_max = len(headers[i])
323 current_max = runewidth.StringWidth(headers[i])
302324 for _, item := range data {
303325 if len(item.Elements) > i && len(widths) > i {
304326 element := item.Elements[i]
305 if len(element) > current_max {
306 widths[i] = len(element)
307 current_max = len(element)
327 strLength := runewidth.StringWidth(element)
328 if strLength > current_max {
329 widths[i] = strLength
330 current_max = strLength
308331 } else {
309332 widths[i] = current_max
310333 }
313336 }
314337
315338 return widths
339 }
340
341 // SetTitle sets the title of the table can also accept a second string to define an alignment for the title
342 func (t *Tabulate) SetTitle(title ...string) *Tabulate {
343
344 t.Title = title[0]
345 if len(title) > 1 {
346 t.TitleAlign = title[1]
347 }
348
349 return t
316350 }
317351
318352 // Set Headers of the table
354388 // Can be:
355389 // top - Top line of the table,
356390 // belowheader - Line below the header,
357 // bottom - Bottom line of the table
391 // bottomLine - Bottom line of the table
392 // betweenLine - Between line of the table
358393 func (t *Tabulate) SetHideLines(hide []string) {
359394 t.HideLines = hide
360395 }
370405 t.MaxSize = max
371406 }
372407
408 // Sets dense mode
409 // Under dense mode, no space line between rows
410 func (t *Tabulate) SetDenseMode() {
411 t.DenseMode = true
412 }
413
414 func (t *Tabulate) splitElement(e string) (bool, string) {
415 //check if we are not attempting to smartly wrap
416 if t.WrapDelimiter == 0 {
417 if t.SplitConcat == "" {
418 return false, runewidth.Truncate(e, t.MaxSize, "")
419 } else {
420 return false, runewidth.Truncate(e, t.MaxSize, t.SplitConcat)
421 }
422 }
423
424 //we are attempting to wrap
425 //grab the current width
426 var i int
427 for i = t.MaxSize; i > 1; i-- {
428 //loop through our proposed truncation size looking for one that ends on
429 //our requested delimiter
430 x := runewidth.Truncate(e, i, "")
431 //check if the NEXT string is a
432 //delimiter, if it IS, then we truncate and tell the caller to shrink
433 r, _ := utf8.DecodeRuneInString(e[i:])
434 if r == 0 || r == 1 {
435 //decode failed, take the truncation as is
436 return false, x
437 }
438 if r == t.WrapDelimiter {
439 return true, x //inform the caller that they can remove the next rune
440 }
441 }
442 //didn't find a good length, truncate at will
443 if t.SplitConcat != "" {
444 return false, runewidth.Truncate(e, t.MaxSize, t.SplitConcat)
445 }
446 return false, runewidth.Truncate(e, t.MaxSize, "")
447 }
448
373449 // If string size is larger than t.MaxSize, then split it to multiple cells (downwards)
374450 func (t *Tabulate) wrapCellData() []*TabulateRow {
375451 var arr []*TabulateRow
452 var cleanSplit bool
453 var addr int
454 if len(t.Data) == 0 {
455 return arr
456 }
376457 next := t.Data[0]
377458 for index := 0; index <= len(t.Data); index++ {
378459 elements := next.Elements
379460 new_elements := make([]string, len(elements))
380461
381462 for i, e := range elements {
382 if len(e) > t.MaxSize {
383 new_elements[i] = e[t.MaxSize:]
384 elements[i] = e[:t.MaxSize]
463 if runewidth.StringWidth(e) > t.MaxSize {
464 elements[i] = runewidth.Truncate(e, t.MaxSize, "")
465 cleanSplit, elements[i] = t.splitElement(e)
466 if cleanSplit {
467 //remove the next rune
468 r, w := utf8.DecodeRuneInString(e[len(elements[i]):])
469 if r != 0 && r != 1 {
470 addr = w
471 }
472 } else {
473 addr = 0
474 }
475 new_elements[i] = e[len(elements[i])+addr:]
385476 next.Continuos = true
386477 }
387478 }
388479
389480 if next.Continuos {
390481 arr = append(arr, next)
391 next = &TabulateRow{Elements: new_elements, Extra: true}
482 next = &TabulateRow{Elements: new_elements}
392483 index--
393 } else if next.Extra && index+1 < len(t.Data) {
394 arr = append(arr, next)
395 next = t.Data[index+1]
396484 } else if index+1 < len(t.Data) {
397485 arr = append(arr, next)
398486 next = t.Data[index+1]
00 package gotabulate
11
2 import "testing"
3 import "io/ioutil"
4 import "github.com/stretchr/testify/assert"
2 import (
3 "io/ioutil"
4 "testing"
5
6 "github.com/stretchr/testify/assert"
7 )
58
69 var HEADERS = []string{"Header 1", "Header 2", "Header 3", "Header 4", "Header 5"}
710 var INT_ARRAY = []int{1, 2, 3, 1000, 200}
5558 // TODO
5659 }
5760
61 func TestSingleColumn(t *testing.T) {
62 tab := Create([][]string{
63 {"test"},
64 })
65 tab.SetMaxCellSize(20)
66 tab.SetWrapStrings(true)
67 tab.Render("grid")
68 }
69
5870 // Test Simple
5971 func TestSimpleFloats(t *testing.T) {
6072 tabulate := Create([][]float64{FLOAT_ARRAY, FLOAT_ARRAY, FLOAT_ARRAY[:len(FLOAT_ARRAY)-1]})
174186 tabulate.SetMaxCellSize(16)
175187 tabulate.SetWrapStrings(true)
176188 assert.Equal(t, tabulate.Render("simple"), readTable("_tests/test_string_wrap_simple"))
189 }
190 func TestMultiByteString(t *testing.T) {
191 tabulate := Create([][]string{
192 {"朝", "おはようございます"},
193 {"昼", "こんにちわ"},
194 {"夜", "こんばんわ"},
195 })
196 tabulate.SetHeaders([]string{"時間帯", "挨拶"})
197 tabulate.SetMaxCellSize(10)
198 tabulate.SetWrapStrings(true)
199 assert.Equal(t, tabulate.Render("grid"), readTable("_tests/test_multibyte_string"))
177200 }
178201 func readTable(path string) string {
179202 buf, err := ioutil.ReadFile(path)
182205 }
183206 return string(buf)
184207 }
208
209 func TestSplitCell(t *testing.T) {
210 tab := Create([][]string{
211 {"header", "value"},
212 {"test1", "This is a really long string, yaaaay it works, Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis"},
213 {"test2", "AAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDd"},
214 })
215 tab.SetMaxCellSize(20)
216 tab.SetWrapStrings(true)
217 tab.SetWrapDelimiter(' ')
218 tab.SetSplitConcat("-")
219 assert.Equal(t, tab.Render("grid"), readTable("_tests/smart_wrap"))
220 }
221
222 func TestTitlesGrid(t *testing.T) {
223 tabulate := Create([][]string{STRING_ARRAY, STRING_ARRAY, EMPTY_ARRAY})
224 tabulate.SetTitle("Title One", "center")
225 tabulate.SetHeaders(HEADERS)
226 tabulate.SetEmptyString("None")
227 assert.Equal(t, tabulate.Render("grid"), readTable("_tests/grid_strings_titled"))
228 }
229
230 func TestTitlesPlain(t *testing.T) {
231 tabulate := Create([][]string{STRING_ARRAY, STRING_ARRAY, EMPTY_ARRAY})
232 tabulate.SetTitle("Make Titles Great Again", "left")
233 tabulate.SetHeaders(HEADERS)
234 tabulate.SetEmptyString("None")
235 assert.Equal(t, tabulate.Render("plain"), readTable("_tests/plain_strings_titled"))
236 }
237
238 func TestTitlesSimple(t *testing.T) {
239 tabulate := Create([][]string{STRING_ARRAY, STRING_ARRAY, EMPTY_ARRAY})
240 tabulate.SetTitle("Simple Title", "right")
241 tabulate.SetHeaders(HEADERS)
242 tabulate.SetEmptyString("None")
243 assert.Equal(t, tabulate.Render("simple"), readTable("_tests/simple_strings_titled"))
244 }
3232 normalized[index] = strconv.FormatFloat(el.(float64), format, -1, 64)
3333 case uint64:
3434 normalized[index] = strconv.FormatUint(el.(uint64), 10)
35 case nil:
36 normalized[index] = "nil"
3537 default:
3638 normalized[index] = fmt.Sprintf("%s", el)
3739 }