1 package table
2
3 import (
4 "strings"
5 "testing"
6 "unicode/utf8"
7
8 "github.com/jedib0t/go-pretty/v6/text"
9 "github.com/stretchr/testify/assert"
10 )
11
12 var (
13 testCaption = "A Song of Ice and Fire"
14 testColor = text.Colors{text.FgGreen}
15 testColorHiRedBold = text.Colors{text.FgHiRed, text.Bold}
16 testColorHiBlueBold = text.Colors{text.FgHiBlue, text.Bold}
17 testCSSClass = "test-css-class"
18 testFooter = Row{"", "", "Total", 10000}
19 testFooterMultiLine = Row{"", "", "Total\nSalary", 10000}
20 testHeader = Row{"#", "First Name", "Last Name", "Salary"}
21 testHeaderMultiLine = Row{"#", "First\nName", "Last\nName", "Salary"}
22 testRows = []Row{
23 {1, "Arya", "Stark", 3000},
24 {20, "Jon", "Snow", 2000, "You know nothing, Jon Snow!"},
25 {300, "Tyrion", "Lannister", 5000},
26 }
27 testRowMultiLine = Row{0, "Winter", "Is", 0, "Coming.\r\nThe North Remembers!\nThis is known."}
28 testRowNewLines = Row{0, "Valar", "Morghulis", 0, "Faceless\nMen"}
29 testRowPipes = Row{0, "Valar", "Morghulis", 0, "Faceless|Men"}
30 testRowTabs = Row{0, "Valar", "Morghulis", 0, "Faceless\tMen"}
31 testTitle1 = "Game of Thrones"
32 testTitle2 = "When you play the Game of Thrones, you win or you die. There is no middle ground."
33 )
34
35 func init() {
36 text.EnableColors()
37 }
38
39 type myMockOutputMirror struct {
40 mirroredOutput string
41 }
42
43 func (t *myMockOutputMirror) Write(p []byte) (n int, err error) {
44 t.mirroredOutput += string(p)
45 return len(p), nil
46 }
47
48 func TestNewWriter(t *testing.T) {
49 tw := NewWriter()
50 assert.NotNil(t, tw.Style())
51 assert.Equal(t, StyleDefault, *tw.Style())
52
53 tw.SetStyle(StyleBold)
54 assert.NotNil(t, tw.Style())
55 assert.Equal(t, StyleBold, *tw.Style())
56 }
57
58 func TestTable_AppendFooter(t *testing.T) {
59 table := Table{}
60 assert.Equal(t, 0, len(table.rowsFooterRaw))
61
62 table.AppendFooter([]interface{}{})
63 assert.Equal(t, 0, table.Length())
64 assert.Equal(t, 1, len(table.rowsFooterRaw))
65 assert.Equal(t, 0, len(table.rowsHeaderRaw))
66
67 table.AppendFooter([]interface{}{})
68 assert.Equal(t, 0, table.Length())
69 assert.Equal(t, 2, len(table.rowsFooterRaw))
70 assert.Equal(t, 0, len(table.rowsHeaderRaw))
71
72 table.AppendFooter([]interface{}{}, RowConfig{AutoMerge: true})
73 assert.Equal(t, 0, table.Length())
74 assert.Equal(t, 3, len(table.rowsFooterRaw))
75 assert.Equal(t, 0, len(table.rowsHeaderRaw))
76 assert.False(t, table.rowsFooterConfigMap[0].AutoMerge)
77 assert.False(t, table.rowsFooterConfigMap[1].AutoMerge)
78 assert.True(t, table.rowsFooterConfigMap[2].AutoMerge)
79 }
80
81 func TestTable_AppendHeader(t *testing.T) {
82 table := Table{}
83 assert.Equal(t, 0, len(table.rowsHeaderRaw))
84
85 table.AppendHeader([]interface{}{})
86 assert.Equal(t, 0, table.Length())
87 assert.Equal(t, 0, len(table.rowsFooterRaw))
88 assert.Equal(t, 1, len(table.rowsHeaderRaw))
89
90 table.AppendHeader([]interface{}{})
91 assert.Equal(t, 0, table.Length())
92 assert.Equal(t, 0, len(table.rowsFooterRaw))
93 assert.Equal(t, 2, len(table.rowsHeaderRaw))
94
95 table.AppendHeader([]interface{}{}, RowConfig{AutoMerge: true})
96 assert.Equal(t, 0, table.Length())
97 assert.Equal(t, 0, len(table.rowsFooterRaw))
98 assert.Equal(t, 3, len(table.rowsHeaderRaw))
99 assert.False(t, table.rowsHeaderConfigMap[0].AutoMerge)
100 assert.False(t, table.rowsHeaderConfigMap[1].AutoMerge)
101 assert.True(t, table.rowsHeaderConfigMap[2].AutoMerge)
102 }
103
104 func TestTable_AppendRow(t *testing.T) {
105 table := Table{}
106 assert.Equal(t, 0, table.Length())
107
108 table.AppendRow([]interface{}{})
109 assert.Equal(t, 1, table.Length())
110 assert.Equal(t, 0, len(table.rowsFooter))
111 assert.Equal(t, 0, len(table.rowsHeader))
112
113 table.AppendRow([]interface{}{})
114 assert.Equal(t, 2, table.Length())
115 assert.Equal(t, 0, len(table.rowsFooter))
116 assert.Equal(t, 0, len(table.rowsHeader))
117
118 table.AppendRow([]interface{}{}, RowConfig{AutoMerge: true})
119 assert.Equal(t, 3, table.Length())
120 assert.Equal(t, 0, len(table.rowsFooterRaw))
121 assert.Equal(t, 0, len(table.rowsHeaderRaw))
122 assert.False(t, table.rowsConfigMap[0].AutoMerge)
123 assert.False(t, table.rowsConfigMap[1].AutoMerge)
124 assert.True(t, table.rowsConfigMap[2].AutoMerge)
125 }
126
127 func TestTable_AppendRows(t *testing.T) {
128 table := Table{}
129 assert.Equal(t, 0, table.Length())
130
131 table.AppendRows([]Row{{}})
132 assert.Equal(t, 1, table.Length())
133 assert.Equal(t, 0, len(table.rowsFooter))
134 assert.Equal(t, 0, len(table.rowsHeader))
135
136 table.AppendRows([]Row{{}})
137 assert.Equal(t, 2, table.Length())
138 assert.Equal(t, 0, len(table.rowsFooter))
139 assert.Equal(t, 0, len(table.rowsHeader))
140
141 table.AppendRows([]Row{{}, {}}, RowConfig{AutoMerge: true})
142 assert.Equal(t, 4, table.Length())
143 assert.Equal(t, 0, len(table.rowsFooterRaw))
144 assert.Equal(t, 0, len(table.rowsHeaderRaw))
145 assert.False(t, table.rowsConfigMap[0].AutoMerge)
146 assert.False(t, table.rowsConfigMap[1].AutoMerge)
147 assert.True(t, table.rowsConfigMap[2].AutoMerge)
148 assert.True(t, table.rowsConfigMap[3].AutoMerge)
149 }
150
151 func TestTable_Length(t *testing.T) {
152 table := Table{}
153 assert.Zero(t, table.Length())
154
155 table.AppendRow(testRows[0])
156 assert.Equal(t, 1, table.Length())
157 table.AppendRow(testRows[1])
158 assert.Equal(t, 2, table.Length())
159
160 table.AppendHeader(testHeader)
161 assert.Equal(t, 2, table.Length())
162 }
163
164 func TestTable_ResetFooters(t *testing.T) {
165 table := Table{}
166 table.AppendFooter(testFooter)
167 assert.NotEmpty(t, table.rowsFooterRaw)
168
169 table.ResetFooters()
170 assert.Empty(t, table.rowsFooterRaw)
171 }
172
173 func TestTable_ResetHeaders(t *testing.T) {
174 table := Table{}
175 table.AppendHeader(testHeader)
176 assert.NotEmpty(t, table.rowsHeaderRaw)
177
178 table.ResetHeaders()
179 assert.Empty(t, table.rowsHeaderRaw)
180 }
181
182 func TestTable_ResetRows(t *testing.T) {
183 table := Table{}
184 table.AppendRows(testRows)
185 assert.NotEmpty(t, table.rowsRaw)
186
187 table.ResetRows()
188 assert.Empty(t, table.rowsRaw)
189 }
190
191 func TestTable_SetAllowedRowLength(t *testing.T) {
192 table := Table{}
193 table.AppendRows(testRows)
194 table.SetStyle(styleTest)
195
196 expectedOutWithNoRowLimit := `(-----^--------^-----------^------^-----------------------------)
197 [< 1>|<Arya >|<Stark >|<3000>|< >]
198 [< 20>|<Jon >|<Snow >|<2000>|<You know nothing, Jon Snow!>]
199 [<300>|<Tyrion>|<Lannister>|<5000>|< >]
200 \-----v--------v-----------v------v-----------------------------/`
201 assert.Zero(t, table.allowedRowLength)
202 assert.Equal(t, expectedOutWithNoRowLimit, table.Render())
203
204 table.SetAllowedRowLength(utf8.RuneCountInString(table.style.Box.UnfinishedRow))
205 assert.Equal(t, utf8.RuneCountInString(table.style.Box.UnfinishedRow), table.allowedRowLength)
206 assert.Equal(t, "", table.Render())
207
208 table.SetAllowedRowLength(5)
209 expectedOutWithRowLimit := `( ~~~
210 [ ~~~
211 [ ~~~
212 [ ~~~
213 \ ~~~`
214 assert.Equal(t, 5, table.allowedRowLength)
215 assert.Equal(t, expectedOutWithRowLimit, table.Render())
216
217 table.SetAllowedRowLength(30)
218 expectedOutWithRowLimit = `(-----^--------^---------- ~~~
219 [< 1>|<Arya >|<Stark ~~~
220 [< 20>|<Jon >|<Snow ~~~
221 [<300>|<Tyrion>|<Lannister ~~~
222 \-----v--------v---------- ~~~`
223 assert.Equal(t, 30, table.allowedRowLength)
224 assert.Equal(t, expectedOutWithRowLimit, table.Render())
225
226 table.SetAllowedRowLength(300)
227 assert.Equal(t, 300, table.allowedRowLength)
228 assert.Equal(t, expectedOutWithNoRowLimit, table.Render())
229 }
230
231 func TestTable_SetAutoIndex(t *testing.T) {
232 table := Table{}
233 table.AppendRows(testRows)
234 table.SetStyle(styleTest)
235
236 expectedOut := `(-----^--------^-----------^------^-----------------------------)
237 [< 1>|<Arya >|<Stark >|<3000>|< >]
238 [< 20>|<Jon >|<Snow >|<2000>|<You know nothing, Jon Snow!>]
239 [<300>|<Tyrion>|<Lannister>|<5000>|< >]
240 \-----v--------v-----------v------v-----------------------------/`
241 assert.False(t, table.autoIndex)
242 assert.Equal(t, expectedOut, table.Render())
243
244 table.SetAutoIndex(true)
245 expectedOut = `(---^-----^--------^-----------^------^-----------------------------)
246 [< >|< A>|< B >|< C >|< D>|< E >]
247 {---+-----+--------+-----------+------+-----------------------------}
248 [<1>|< 1>|<Arya >|<Stark >|<3000>|< >]
249 [<2>|< 20>|<Jon >|<Snow >|<2000>|<You know nothing, Jon Snow!>]
250 [<3>|<300>|<Tyrion>|<Lannister>|<5000>|< >]
251 \---v-----v--------v-----------v------v-----------------------------/`
252 assert.True(t, table.autoIndex)
253 assert.Equal(t, expectedOut, table.Render())
254
255 table.AppendHeader(testHeader)
256 expectedOut = `(---^-----^------------^-----------^--------^-----------------------------)
257 [< >|< #>|<FIRST NAME>|<LAST NAME>|<SALARY>|< >]
258 {---+-----+------------+-----------+--------+-----------------------------}
259 [<1>|< 1>|<Arya >|<Stark >|< 3000>|< >]
260 [<2>|< 20>|<Jon >|<Snow >|< 2000>|<You know nothing, Jon Snow!>]
261 [<3>|<300>|<Tyrion >|<Lannister>|< 5000>|< >]
262 \---v-----v------------v-----------v--------v-----------------------------/`
263 assert.True(t, table.autoIndex)
264 assert.Equal(t, expectedOut, table.Render())
265
266 table.AppendRow(testRowMultiLine)
267 expectedOut = `(---^-----^------------^-----------^--------^-----------------------------)
268 [< >|< #>|<FIRST NAME>|<LAST NAME>|<SALARY>|< >]
269 {---+-----+------------+-----------+--------+-----------------------------}
270 [<1>|< 1>|<Arya >|<Stark >|< 3000>|< >]
271 [<2>|< 20>|<Jon >|<Snow >|< 2000>|<You know nothing, Jon Snow!>]
272 [<3>|<300>|<Tyrion >|<Lannister>|< 5000>|< >]
273 [<4>|< 0>|<Winter >|<Is >|< 0>|<Coming. >]
274 [< >|< >|< >|< >|< >|<The North Remembers! >]
275 [< >|< >|< >|< >|< >|<This is known. >]
276 \---v-----v------------v-----------v--------v-----------------------------/`
277 assert.Equal(t, expectedOut, table.Render())
278
279 table.SetStyle(StyleLight)
280 expectedOut = `┌───┬─────┬────────────┬───────────┬────────┬─────────────────────────────┐
281 │ │ # │ FIRST NAME │ LAST NAME │ SALARY │ │
282 ├───┼─────┼────────────┼───────────┼────────┼─────────────────────────────┤
283 │ 1 │ 1 │ Arya │ Stark │ 3000 │ │
284 │ 2 │ 20 │ Jon │ Snow │ 2000 │ You know nothing, Jon Snow! │
285 │ 3 │ 300 │ Tyrion │ Lannister │ 5000 │ │
286 │ 4 │ 0 │ Winter │ Is │ 0 │ Coming. │
287 │ │ │ │ │ │ The North Remembers! │
288 │ │ │ │ │ │ This is known. │
289 └───┴─────┴────────────┴───────────┴────────┴─────────────────────────────┘`
290 assert.Equal(t, expectedOut, table.Render())
291 }
292
293 func TestTable_SetCaption(t *testing.T) {
294 table := Table{}
295 assert.Empty(t, table.caption)
296
297 table.SetCaption(testCaption)
298 assert.NotEmpty(t, table.caption)
299 assert.Equal(t, testCaption, table.caption)
300 }
301
302 func TestTable_SetColumnConfigs(t *testing.T) {
303 table := Table{}
304 assert.Empty(t, table.columnConfigs)
305
306 table.SetColumnConfigs([]ColumnConfig{{}, {}, {}})
307 assert.NotEmpty(t, table.columnConfigs)
308 assert.Equal(t, 3, len(table.columnConfigs))
309 }
310
311 func TestTable_SetHTMLCSSClass(t *testing.T) {
312 table := Table{}
313 table.AppendRow(testRows[0])
314 expectedHTML := `<table class="` + DefaultHTMLCSSClass + `">
315 <tbody>
316 <tr>
317 <td align="right">1</td>
318 <td>Arya</td>
319 <td>Stark</td>
320 <td align="right">3000</td>
321 </tr>
322 </tbody>
323 </table>`
324 assert.Equal(t, "", table.htmlCSSClass)
325 assert.Equal(t, expectedHTML, table.RenderHTML())
326
327 table.SetHTMLCSSClass(testCSSClass)
328 assert.Equal(t, testCSSClass, table.htmlCSSClass)
329 assert.Equal(t, strings.Replace(expectedHTML, DefaultHTMLCSSClass, testCSSClass, -1), table.RenderHTML())
330 }
331
332 func TestTable_SetOutputMirror(t *testing.T) {
333 table := Table{}
334 table.AppendRow(testRows[0])
335 expectedOut := `+---+------+-------+------+
336 | 1 | Arya | Stark | 3000 |
337 +---+------+-------+------+`
338 assert.Equal(t, nil, table.outputMirror)
339 assert.Equal(t, expectedOut, table.Render())
340
341 mockOutputMirror := &myMockOutputMirror{}
342 table.SetOutputMirror(mockOutputMirror)
343 assert.Equal(t, mockOutputMirror, table.outputMirror)
344 assert.Equal(t, expectedOut, table.Render())
345 assert.Equal(t, expectedOut+"\n", mockOutputMirror.mirroredOutput)
346 }
347
348 func TestTable_SePageSize(t *testing.T) {
349 table := Table{}
350 assert.Equal(t, 0, table.pageSize)
351
352 table.SetPageSize(13)
353 assert.Equal(t, 13, table.pageSize)
354 }
355
356 func TestTable_SortByColumn(t *testing.T) {
357 table := Table{}
358 assert.Empty(t, table.sortBy)
359
360 table.SortBy([]SortBy{{Name: "#", Mode: Asc}})
361 assert.Equal(t, 1, len(table.sortBy))
362
363 table.SortBy([]SortBy{{Name: "First Name", Mode: Dsc}, {Name: "Last Name", Mode: Asc}})
364 assert.Equal(t, 2, len(table.sortBy))
365 }
366
367 func TestTable_SetStyle(t *testing.T) {
368 table := Table{}
369 assert.NotNil(t, table.Style())
370 assert.Equal(t, StyleDefault, *table.Style())
371
372 table.SetStyle(StyleDefault)
373 assert.NotNil(t, table.Style())
374 assert.Equal(t, StyleDefault, *table.Style())
375 }
376
View as plain text