File: render_automerge_test.go

package info (click to toggle)
golang-github-jedib0t-go-pretty 6.5.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,700 kB
  • sloc: makefile: 28; sh: 14
file content (765 lines) | stat: -rw-r--r-- 71,054 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
package table

import (
	"testing"

	"github.com/jedib0t/go-pretty/v6/text"
)

func TestTable_Render_AutoMerge(t *testing.T) {
	rcAutoMerge := RowConfig{AutoMerge: true}

	t.Run("columns only", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "RCE\nEXE", "RCE\nRUN"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "N"})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y"})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y"})
		tw.AppendFooter(Row{"", "", "", 7, 5, 3})
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 1, AutoMerge: true},
			{Number: 2, AutoMerge: true},
			{Number: 3, AutoMerge: true},
			{Number: 4, AutoMerge: true},
			{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
			{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬─────────┬────────┬───────────┬───────────┬─────┬─────┐
│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINER │ RCE │ RCE │
│   │         │        │           │           │ EXE │ RUN │
├───┼─────────┼────────┼───────────┼───────────┼─────┼─────┤
│ 1 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 1       │  Y  │  Y  │
├───┤         │        │           ├───────────┼─────┼─────┤
│ 2 │         │        │           │ C 2       │  Y  │  N  │
├───┤         │        ├───────────┼───────────┼─────┼─────┤
│ 3 │         │        │ NS 1B     │ C 3       │  N  │  N  │
├───┤         ├────────┼───────────┼───────────┼─────┼─────┤
│ 4 │         │ Pod 1B │ NS 2      │ C 4       │  N  │  N  │
├───┤         │        │           ├───────────┼─────┼─────┤
│ 5 │         │        │           │ C 5       │  Y  │  N  │
├───┼─────────┼────────┼───────────┼───────────┼─────┼─────┤
│ 6 │ b.b.b.b │ Pod 2  │ NS 3      │ C 6       │  Y  │  Y  │
├───┤         │        │           ├───────────┼─────┼─────┤
│ 7 │         │        │           │ C 7       │  Y  │  Y  │
├───┼─────────┼────────┼───────────┼───────────┼─────┼─────┤
│   │         │        │           │ 7         │  5  │  3  │
└───┴─────────┴────────┴───────────┴───────────┴─────┴─────┘`)
	})

	t.Run("columns only with hidden columns", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "RCE\nEXE", "RCE\nRUN"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "Y", "Y"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "N"})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y"})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "N"})
		tw.AppendFooter(Row{"", "", "", 7, 5, 3})
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 1, AutoMerge: true},
			{Number: 2, AutoMerge: true},
			{Number: 3, AutoMerge: true},
			{Number: 4, Hidden: true},
			{Number: 5, Hidden: true, Align: text.AlignCenter},
			{Number: 6, Hidden: true, Align: text.AlignCenter},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌─────────┬────────┬───────────┐
│ NODE IP │ PODS   │ NAMESPACE │
├─────────┼────────┼───────────┤
│ a.a.a.a │ Pod 1A │ NS 1A     │
│         │        │           │
│         │        │           │
│         │        ├───────────┤
│         │        │ NS 1B     │
│         ├────────┼───────────┤
│         │ Pod 1B │ NS 2      │
│         │        │           │
│         │        │           │
├─────────┼────────┼───────────┤
│ b.b.b.b │ Pod 2  │ NS 3      │
│         │        │           │
│         │        │           │
├─────────┼────────┼───────────┤
│         │        │           │
└─────────┴────────┴───────────┘`)
	})

	t.Run("rows only", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "RCE", "RCE"}, rcAutoMerge)
		tw.AppendHeader(Row{"", "", "", "", "EXE", "RUN"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "N"})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y"}, RowConfig{AutoMerge: true, AutoMergeAlign: text.AlignRight})
		tw.AppendFooter(Row{"", "", "", 7, 5, 3})
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
			{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬─────────┬────────┬───────────┬───────────┬───────────┐
│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINER │    RCE    │
│   ├─────────┼────────┼───────────┼───────────┼─────┬─────┤
│   │         │        │           │           │ EXE │ RUN │
├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤
│ 1 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 1       │     Y     │
├───┼─────────┼────────┼───────────┼───────────┼─────┬─────┤
│ 2 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 2       │  Y  │  N  │
├───┼─────────┼────────┼───────────┼───────────┼─────┼─────┤
│ 3 │ a.a.a.a │ Pod 1A │ NS 1B     │ C 3       │  N  │  N  │
├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤
│ 4 │ a.a.a.a │ Pod 1B │ NS 2      │ C 4       │     N     │
├───┼─────────┼────────┼───────────┼───────────┼─────┬─────┤
│ 5 │ a.a.a.a │ Pod 1B │ NS 2      │ C 5       │  Y  │  N  │
├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤
│ 6 │ b.b.b.b │ Pod 2  │ NS 3      │ C 6       │     Y     │
├───┼─────────┼────────┼───────────┼───────────┼───────────┤
│ 7 │ b.b.b.b │ Pod 2  │ NS 3      │ C 7       │         Y │
├───┼─────────┼────────┼───────────┼───────────┼─────┬─────┤
│   │         │        │           │ 7         │  5  │  3  │
└───┴─────────┴────────┴───────────┴───────────┴─────┴─────┘`)
	})

	t.Run("rows and columns", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "RCE", "RCE"}, rcAutoMerge)
		tw.AppendHeader(Row{"", "", "", "", "EXE", "RUN"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y"}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 3})
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 1, AutoMerge: true},
			{Number: 2, AutoMerge: true},
			{Number: 3, AutoMerge: true},
			{Number: 4, AutoMerge: true},
			{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
			{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬─────────┬────────┬───────────┬───────────┬───────────┐
│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINER │    RCE    │
│   ├─────────┼────────┼───────────┼───────────┼─────┬─────┤
│   │         │        │           │           │ EXE │ RUN │
├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤
│ 1 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 1       │     Y     │
├───┤         │        │           ├───────────┼─────┬─────┤
│ 2 │         │        │           │ C 2       │  Y  │  N  │
├───┤         │        ├───────────┼───────────┼─────┴─────┤
│ 3 │         │        │ NS 1B     │ C 3       │     N     │
├───┤         ├────────┼───────────┼───────────┼───────────┤
│ 4 │         │ Pod 1B │ NS 2      │ C 4       │     N     │
├───┤         │        │           ├───────────┼─────┬─────┤
│ 5 │         │        │           │ C 5       │  Y  │  N  │
├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤
│ 6 │ b.b.b.b │ Pod 2  │ NS 3      │ C 6       │     Y     │
├───┤         │        │           ├───────────┼───────────┤
│ 7 │         │        │           │ C 7       │     Y     │
├───┼─────────┼────────┼───────────┼───────────┼─────┬─────┤
│   │         │        │           │ 7         │  5  │  3  │
└───┴─────────┴────────┴───────────┴───────────┴─────┴─────┘`)
	})

	t.Run("rows and columns no headers or footers", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "N"})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y"}, RowConfig{AutoMerge: true, AutoMergeAlign: text.AlignRight})
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 5, Align: text.AlignCenter, AlignHeader: text.AlignCenter},
			{Number: 6, Align: text.AlignCenter, AlignHeader: text.AlignCenter},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌─────────┬────────┬───────┬─────┬───────┐
│ a.a.a.a │ Pod 1A │ NS 1A │ C 1 │   Y   │
├─────────┼────────┼───────┼─────┼───┬───┤
│ a.a.a.a │ Pod 1A │ NS 1A │ C 2 │ Y │ N │
├─────────┼────────┼───────┼─────┼───┼───┤
│ a.a.a.a │ Pod 1A │ NS 1B │ C 3 │ N │ N │
├─────────┼────────┼───────┼─────┼───┴───┤
│ a.a.a.a │ Pod 1B │ NS 2  │ C 4 │   N   │
├─────────┼────────┼───────┼─────┼───┬───┤
│ a.a.a.a │ Pod 1B │ NS 2  │ C 5 │ Y │ N │
├─────────┼────────┼───────┼─────┼───┴───┤
│ b.b.b.b │ Pod 2  │ NS 3  │ C 6 │   Y   │
├─────────┼────────┼───────┼─────┼───────┤
│ b.b.b.b │ Pod 2  │ NS 3  │ C 7 │     Y │
└─────────┴────────┴───────┴─────┴───────┘`)
	})

	t.Run("rows and columns no headers or footers with auto-index", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N"})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "N"})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y"}, RowConfig{AutoMerge: true, AutoMergeAlign: text.AlignRight})
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 5, Align: text.AlignCenter, AlignHeader: text.AlignCenter},
			{Number: 6, Align: text.AlignCenter, AlignHeader: text.AlignCenter},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬─────────┬────────┬───────┬─────┬───┬───┐
│   │    A    │    B   │   C   │  D  │ E │ F │
├───┼─────────┼────────┼───────┼─────┼───┴───┤
│ 1 │ a.a.a.a │ Pod 1A │ NS 1A │ C 1 │   Y   │
├───┼─────────┼────────┼───────┼─────┼───┬───┤
│ 2 │ a.a.a.a │ Pod 1A │ NS 1A │ C 2 │ Y │ N │
├───┼─────────┼────────┼───────┼─────┼───┼───┤
│ 3 │ a.a.a.a │ Pod 1A │ NS 1B │ C 3 │ N │ N │
├───┼─────────┼────────┼───────┼─────┼───┴───┤
│ 4 │ a.a.a.a │ Pod 1B │ NS 2  │ C 4 │   N   │
├───┼─────────┼────────┼───────┼─────┼───┬───┤
│ 5 │ a.a.a.a │ Pod 1B │ NS 2  │ C 5 │ Y │ N │
├───┼─────────┼────────┼───────┼─────┼───┴───┤
│ 6 │ b.b.b.b │ Pod 2  │ NS 3  │ C 6 │   Y   │
├───┼─────────┼────────┼───────┼─────┼───────┤
│ 7 │ b.b.b.b │ Pod 2  │ NS 3  │ C 7 │     Y │
└───┴─────────┴────────┴───────┴─────┴───────┘`)
	})

	t.Run("rows and columns and headers and footers", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "RCE", "RCE", "ID"}, rcAutoMerge)
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "EXE", "RUN", ""})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y", 123}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "N", 234})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N", 345})
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N", 456}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "N", 567})
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y", 678}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y", 789}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 5}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 3}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 5}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 3}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 5}, rcAutoMerge)
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 1, AutoMerge: true},
			{Number: 2, AutoMerge: true},
			{Number: 3, AutoMerge: true},
			{Number: 4, AutoMerge: true},
			{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
			{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬─────────┬────────┬───────────┬───────────┬───────────┬─────┐
│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINER │    RCE    │  ID │
│   │         │        │           │           ├─────┬─────┼─────┤
│   │         │        │           │           │ EXE │ RUN │     │
├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┼─────┤
│ 1 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 1       │     Y     │ 123 │
├───┤         │        │           ├───────────┼─────┬─────┼─────┤
│ 2 │         │        │           │ C 2       │  Y  │  N  │ 234 │
├───┤         │        ├───────────┼───────────┼─────┼─────┼─────┤
│ 3 │         │        │ NS 1B     │ C 3       │  N  │  N  │ 345 │
├───┤         ├────────┼───────────┼───────────┼─────┴─────┼─────┤
│ 4 │         │ Pod 1B │ NS 2      │ C 4       │     N     │ 456 │
├───┤         │        │           ├───────────┼─────┬─────┼─────┤
│ 5 │         │        │           │ C 5       │  Y  │  N  │ 567 │
├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┼─────┤
│ 6 │ b.b.b.b │ Pod 2  │ NS 3      │ C 6       │     Y     │ 678 │
├───┤         │        │           ├───────────┼───────────┼─────┤
│ 7 │         │        │           │ C 7       │     Y     │ 789 │
├───┼─────────┴────────┴───────────┼───────────┼───────────┼─────┤
│   │                              │ 7         │     5     │     │
│   │                              │           ├─────┬─────┼─────┤
│   │                              │           │  5  │  3  │     │
│   │                              │           ├─────┴─────┼─────┤
│   │                              │           │     5     │     │
│   │                              │           ├─────┬─────┼─────┤
│   │                              │           │  5  │  3  │     │
│   │                              │           ├─────┴─────┼─────┤
│   │                              │           │     5     │     │
└───┴──────────────────────────────┴───────────┴───────────┴─────┘`)
	})

	t.Run("samurai sudoku", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendRow(Row{"1.1\n1.1", "1.2\n1.2", "1.3\n1.3", " ", "2.1\n2.1", "2.2\n2.2", "2.3\n2.3"})
		tw.AppendRow(Row{"1.4\n1.4", "1.5\n1.5", "1.6\n1.6", " ", "2.4\n2.4", "2.5\n2.5", "2.6\n2.6"})
		tw.AppendRow(Row{"1.7\n1.7", "1.8\n1.8", "1.9\n0.1", "0.2\n0.2", "2.7\n0.3", "2.8\n2.8", "2.9\n2.9"})
		tw.AppendRow(Row{" ", " ", "0.4\n0.4", "0.5\n0.5", "0.6\n0.6", " ", " "}, rcAutoMerge)
		tw.AppendRow(Row{"3.1\n3.1", "3.2\n3.2", "3.3\n0.7", "0.8\n0.8", "4.1\n0.9", "4.2\n4.2", "4.3\n4.3"})
		tw.AppendRow(Row{"3.4\n3.4", "3.5\n3.5", "3.6\n3.6", " ", "4.4\n4.4", "4.5\n4.5", "4.6\n4.6"})
		tw.AppendRow(Row{"3.7\n3.7", "3.8\n3.8", "3.9\n3.9", " ", "4.7\n4.7", "4.8\n4.8", "4.9\n4.9"})
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 4, AutoMerge: true},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Box.PaddingLeft = ""
		tw.Style().Box.PaddingRight = ""
		tw.Style().Options.DrawBorder = true
		tw.Style().Options.SeparateRows = true
		tw.Style().Options.SeparateColumns = true

		compareOutput(t, tw.Render(), `
┌───┬───┬───┬───┬───┬───┬───┐
│1.1│1.2│1.3│   │2.1│2.2│2.3│
│1.1│1.2│1.3│   │2.1│2.2│2.3│
├───┼───┼───┤   ├───┼───┼───┤
│1.4│1.5│1.6│   │2.4│2.5│2.6│
│1.4│1.5│1.6│   │2.4│2.5│2.6│
├───┼───┼───┼───┼───┼───┼───┤
│1.7│1.8│1.9│0.2│2.7│2.8│2.9│
│1.7│1.8│0.1│0.2│0.3│2.8│2.9│
├───┴───┼───┼───┼───┼───┴───┤
│       │0.4│0.5│0.6│       │
│       │0.4│0.5│0.6│       │
├───┬───┼───┼───┼───┼───┬───┤
│3.1│3.2│3.3│0.8│4.1│4.2│4.3│
│3.1│3.2│0.7│0.8│0.9│4.2│4.3│
├───┼───┼───┼───┼───┼───┼───┤
│3.4│3.5│3.6│   │4.4│4.5│4.6│
│3.4│3.5│3.6│   │4.4│4.5│4.6│
├───┼───┼───┤   ├───┼───┼───┤
│3.7│3.8│3.9│   │4.7│4.8│4.9│
│3.7│3.8│3.9│   │4.7│4.8│4.9│
└───┴───┴───┴───┴───┴───┴───┘`)
	})

	testLongCol1 := "4F8F5CB531E3D49A61CF417CD133792CCFA501FD8DA53EE368FED20E5FE0248C3A0B64F98A6533CEE1DA614C3A8DDEC791FF05FEE6D971D57C1348320F4EB42DR"
	testLongRowCCs := []ColumnConfig{
		{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
		{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
		{Number: 7, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
		{Number: 8, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
	}
	generateTableForLongRows := func() Writer {
		tw := NewWriter()
		tw.AppendHeader(Row{"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6", "Column 7", "Column 8"}, rcAutoMerge)
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs(testLongRowCCs)
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true
		return tw
	}

	t.Run("long column no merge", func(t *testing.T) {
		tw := generateTableForLongRows()
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1 + "W", testLongCol1 + "H", testLongCol1 + "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬──────────────────────────┬──────────────────────────┬──────────────────────────┬──────────────────────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │         COLUMN 5         │         COLUMN 6         │         COLUMN 7         │         COLUMN 8         │
├───┼──────────┼──────────┼──────────┼──────────┼──────────────────────────┼──────────────────────────┼──────────────────────────┼──────────────────────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │ 4F8F5CB531E3D49A61CF417C │ 4F8F5CB531E3D49A61CF417C │ 4F8F5CB531E3D49A61CF417C │ 4F8F5CB531E3D49A61CF417C │
│   │          │          │          │          │ D133792CCFA501FD8DA53EE3 │ D133792CCFA501FD8DA53EE3 │ D133792CCFA501FD8DA53EE3 │ D133792CCFA501FD8DA53EE3 │
│   │          │          │          │          │ 68FED20E5FE0248C3A0B64F9 │ 68FED20E5FE0248C3A0B64F9 │ 68FED20E5FE0248C3A0B64F9 │ 68FED20E5FE0248C3A0B64F9 │
│   │          │          │          │          │ 8A6533CEE1DA614C3A8DDEC7 │ 8A6533CEE1DA614C3A8DDEC7 │ 8A6533CEE1DA614C3A8DDEC7 │ 8A6533CEE1DA614C3A8DDEC7 │
│   │          │          │          │          │ 91FF05FEE6D971D57C134832 │ 91FF05FEE6D971D57C134832 │ 91FF05FEE6D971D57C134832 │ 91FF05FEE6D971D57C134832 │
│   │          │          │          │          │         0F4EB42DR        │        0F4EB42DRW        │        0F4EB42DRH        │        0F4EB42DRY        │
├───┼──────────┼──────────┼──────────┼──────────┼──────────────────────────┴──────────────────────────┴──────────────────────────┴──────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                                                     Y                                                     │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                                                     Y                                                     │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────┘`)
	})

	t.Run("long column partially merged #1", func(t *testing.T) {
		tw := generateTableForLongRows()
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1, testLongCol1 + "R", testLongCol1 + "R"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬─────────────┬─────────────┬─────────────┬─────────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │   COLUMN 5  │   COLUMN 6  │   COLUMN 7  │   COLUMN 8  │
├───┼──────────┼──────────┼──────────┼──────────┼─────────────┴─────────────┼─────────────┴─────────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │  4F8F5CB531E3D49A61CF417C │  4F8F5CB531E3D49A61CF417C │
│   │          │          │          │          │  D133792CCFA501FD8DA53EE3 │  D133792CCFA501FD8DA53EE3 │
│   │          │          │          │          │  68FED20E5FE0248C3A0B64F9 │  68FED20E5FE0248C3A0B64F9 │
│   │          │          │          │          │  8A6533CEE1DA614C3A8DDEC7 │  8A6533CEE1DA614C3A8DDEC7 │
│   │          │          │          │          │  91FF05FEE6D971D57C134832 │  91FF05FEE6D971D57C134832 │
│   │          │          │          │          │         0F4EB42DR         │         0F4EB42DRR        │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────┴───────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                           Y                           │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                           Y                           │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────────────────┘`)
	})

	t.Run("long column partially merged #2", func(t *testing.T) {
		tw := generateTableForLongRows()
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1, testLongCol1, testLongCol1 + "E"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────────────────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │ COLUMN 5 │ COLUMN 6 │ COLUMN 7 │         COLUMN 8         │
├───┼──────────┼──────────┼──────────┼──────────┼──────────┴──────────┴──────────┼──────────────────────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │    4F8F5CB531E3D49A61CF417C    │ 4F8F5CB531E3D49A61CF417C │
│   │          │          │          │          │    D133792CCFA501FD8DA53EE3    │ D133792CCFA501FD8DA53EE3 │
│   │          │          │          │          │    68FED20E5FE0248C3A0B64F9    │ 68FED20E5FE0248C3A0B64F9 │
│   │          │          │          │          │    8A6533CEE1DA614C3A8DDEC7    │ 8A6533CEE1DA614C3A8DDEC7 │
│   │          │          │          │          │    91FF05FEE6D971D57C134832    │ 91FF05FEE6D971D57C134832 │
│   │          │          │          │          │            0F4EB42DR           │        0F4EB42DRE        │
├───┼──────────┼──────────┼──────────┼──────────┼────────────────────────────────┴──────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                             Y                             │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                             Y                             │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────────────────────┘`)
	})

	t.Run("long column fully merged", func(t *testing.T) {
		tw := generateTableForLongRows()
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1, testLongCol1, testLongCol1}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │ COLUMN 5 │ COLUMN 6 │ COLUMN 7 │ COLUMN 8 │
├───┼──────────┼──────────┼──────────┼──────────┼──────────┴──────────┴──────────┴──────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │          4F8F5CB531E3D49A61CF417C         │
│   │          │          │          │          │          D133792CCFA501FD8DA53EE3         │
│   │          │          │          │          │          68FED20E5FE0248C3A0B64F9         │
│   │          │          │          │          │          8A6533CEE1DA614C3A8DDEC7         │
│   │          │          │          │          │          91FF05FEE6D971D57C134832         │
│   │          │          │          │          │                 0F4EB42DR                 │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                     Y                     │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                     Y                     │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────┘`)
	})

	t.Run("headers and footers", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "RCE1", "RCE2"}, rcAutoMerge)
		tw.AppendHeader(Row{"", "", "", "", "EXE EXE EXE", "EXE EXE EXE"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y"}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 5}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 6, 4, 4}, rcAutoMerge)
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
			{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬─────────┬────────┬───────────┬───────────┬──────┬──────┐
│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINER │ RCE1 │ RCE2 │
│   ├─────────┴────────┴───────────┴───────────┼──────┴──────┤
│   │                                          │   EXE EXE   │
│   │                                          │     EXE     │
├───┼─────────┬────────┬───────────┬───────────┼─────────────┤
│ 1 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 1       │      Y      │
├───┼─────────┼────────┼───────────┼───────────┼─────────────┤
│ 2 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 2       │      Y      │
├───┼─────────┼────────┼───────────┼───────────┼─────────────┤
│ 3 │ a.a.a.a │ Pod 1A │ NS 1B     │ C 3       │      N      │
├───┼─────────┼────────┼───────────┼───────────┼─────────────┤
│ 4 │ a.a.a.a │ Pod 1B │ NS 2      │ C 4       │      N      │
├───┼─────────┼────────┼───────────┼───────────┼─────────────┤
│ 5 │ a.a.a.a │ Pod 1B │ NS 2      │ C 5       │      Y      │
├───┼─────────┼────────┼───────────┼───────────┼─────────────┤
│ 6 │ b.b.b.b │ Pod 2  │ NS 3      │ C 6       │      Y      │
├───┼─────────┼────────┼───────────┼───────────┼─────────────┤
│ 7 │ b.b.b.b │ Pod 2  │ NS 3      │ C 7       │      Y      │
├───┼─────────┴────────┴───────────┼───────────┼─────────────┤
│   │                              │ 7         │      5      │
│   ├──────────────────────────────┼───────────┼─────────────┤
│   │                              │ 6         │      4      │
└───┴──────────────────────────────┴───────────┴─────────────┘`)
	})

	t.Run("long header column", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"Node IP", "Pods", "Namespace", "Container", "RCE1", "RCE2", "RCE3"}, rcAutoMerge)
		tw.AppendHeader(Row{"", "", "", "", "EXE EXE EXE", "EXE EXE EXE", "EXE EXE EXE"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 7, 5, 5, 5}, rcAutoMerge)
		tw.AppendFooter(Row{"", "", "", 6, 4, 4, 3}, rcAutoMerge)
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
			{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
			{Number: 7, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬─────────┬────────┬───────────┬───────────┬──────┬──────┬──────┐
│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINER │ RCE1 │ RCE2 │ RCE3 │
│   ├─────────┴────────┴───────────┴───────────┼──────┴──────┴──────┤
│   │                                          │       EXE EXE      │
│   │                                          │         EXE        │
├───┼─────────┬────────┬───────────┬───────────┼────────────────────┤
│ 1 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 1       │          Y         │
├───┼─────────┼────────┼───────────┼───────────┼────────────────────┤
│ 2 │ a.a.a.a │ Pod 1A │ NS 1A     │ C 2       │          Y         │
├───┼─────────┼────────┼───────────┼───────────┼────────────────────┤
│ 3 │ a.a.a.a │ Pod 1A │ NS 1B     │ C 3       │          N         │
├───┼─────────┼────────┼───────────┼───────────┼────────────────────┤
│ 4 │ a.a.a.a │ Pod 1B │ NS 2      │ C 4       │          N         │
├───┼─────────┼────────┼───────────┼───────────┼────────────────────┤
│ 5 │ a.a.a.a │ Pod 1B │ NS 2      │ C 5       │          Y         │
├───┼─────────┼────────┼───────────┼───────────┼────────────────────┤
│ 6 │ b.b.b.b │ Pod 2  │ NS 3      │ C 6       │          Y         │
├───┼─────────┼────────┼───────────┼───────────┼────────────────────┤
│ 7 │ b.b.b.b │ Pod 2  │ NS 3      │ C 7       │          Y         │
├───┼─────────┴────────┴───────────┼───────────┼────────────────────┤
│   │                              │ 7         │          5         │
│   ├──────────────────────────────┼───────────┼─────────────┬──────┤
│   │                              │ 6         │      4      │   3  │
└───┴──────────────────────────────┴───────────┴─────────────┴──────┘`)
	})

	t.Run("empty cells", func(t *testing.T) {
		tw := NewWriter()
		rowConfigAutoMerge := RowConfig{AutoMerge: true}
		tw.AppendRow(Row{"Product", "Standalone", "foo bar", "a.a.a.a", ""}, rowConfigAutoMerge)
		tw.AppendRow(Row{"Test", "Standalone", "bar baz", "b.b.b.b", ""}, rowConfigAutoMerge)
		tw.AppendRow(Row{"Product", "RedisCluster", "foo baz", "", "Cluster #1"}, rowConfigAutoMerge)
		tw.AppendRow(Row{"Product", "RedisCluster", "bar baz", "", "Cluster #2"}, rowConfigAutoMerge)
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 1, AutoMerge: true},
			{Number: 2, AutoMerge: true},
			{Number: 3, AutoMerge: true},
			{Number: 4, AutoMerge: true},
			{Number: 5, AutoMerge: true},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `┌───┬─────────┬──────────────┬─────────┬─────────┬────────────┐
│   │    A    │       B      │    C    │    D    │      E     │
├───┼─────────┼──────────────┼─────────┼─────────┼────────────┤
│ 1 │ Product │ Standalone   │ foo bar │ a.a.a.a │            │
├───┼─────────┤              ├─────────┼─────────┤            │
│ 2 │ Test    │              │ bar baz │ b.b.b.b │            │
├───┼─────────┼──────────────┼─────────┼─────────┼────────────┤
│ 3 │ Product │ RedisCluster │ foo baz │         │ Cluster #1 │
├───┤         │              ├─────────┤         ├────────────┤
│ 4 │         │              │ bar baz │         │ Cluster #2 │
└───┴─────────┴──────────────┴─────────┴─────────┴────────────┘`)
	})

	t.Run("everything", func(t *testing.T) {
		tw := NewWriter()
		tw.AppendHeader(Row{"COLUMNS", "COLUMNS", "COLUMNS", "COLUMNS", "COLUMNS", "COLUMNS", "COLUMNS"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1B", "C 3", "N", "N", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 4", "N", "Y", "N"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1B", "NS 2", "C 5", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 6", "N", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"b.b.b.b", "Pod 2", "NS 3", "C 7", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendFooter(Row{"foo", "foo", "foo", "foo", "bar", "bar", "bar"}, rcAutoMerge)
		tw.AppendFooter(Row{7, 7, 7, 7, 7, 7, 7}, rcAutoMerge)
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs([]ColumnConfig{
			{Number: 1, AutoMerge: true},
			{Number: 2, AutoMerge: true},
			{Number: 3, AutoMerge: true},
			{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
			{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
			{Number: 7, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 7, WidthMaxEnforcer: text.WrapHard},
		})
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true

		compareOutput(t, tw.Render(), `
┌───┬───────────────────────────────────────────────────┐
│   │                      COLUMNS                      │
├───┼─────────┬─────────┬─────────┬─────────┬───────────┤
│ 1 │ a.a.a.a │ Pod 1A  │ NS 1A   │ C 1     │     Y     │
├───┤         │         │         ├─────────┼───────┬───┤
│ 2 │         │         │         │ C 2     │   Y   │ N │
├───┤         │         ├─────────┼─────────┼───────┴───┤
│ 3 │         │         │ NS 1B   │ C 3     │     N     │
├───┤         ├─────────┼─────────┼─────────┼───┬───┬───┤
│ 4 │         │ Pod 1B  │ NS 2    │ C 4     │ N │ Y │ N │
├───┤         │         │         ├─────────┼───┴───┴───┤
│ 5 │         │         │         │ C 5     │     Y     │
├───┼─────────┼─────────┼─────────┼─────────┼───┬───────┤
│ 6 │ b.b.b.b │ Pod 2   │ NS 3    │ C 6     │ N │   Y   │
├───┤         │         │         ├─────────┼───┴───────┤
│ 7 │         │         │         │ C 7     │     Y     │
├───┼─────────┴─────────┴─────────┴─────────┼───────────┤
│   │                  FOO                  │    BAR    │
│   ├───────────────────────────────────────┴───────────┤
│   │                         7                         │
└───┴───────────────────────────────────────────────────┘`)
	})
}

func TestTable_Render_AutoMergeLongColumns(t *testing.T) {
	rcAutoMerge := RowConfig{AutoMerge: true}

	testLongCol1 := "4F8F5CB531E3D49A61CF417CD133792CCFA501FD8DA53EE368FED20E5FE0248C3A0B64F98A6533CEE1DA614C3A8DDEC791FF05FEE6D971D57C1348320F4EB42DR"
	testLongRowCCs := []ColumnConfig{
		{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
		{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
		{Number: 7, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
		{Number: 8, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter, WidthMax: 24, WidthMaxEnforcer: text.WrapHard},
	}
	generateTableForLongRows := func(longRow Row) Writer {
		tw := NewWriter()
		tw.AppendHeader(Row{"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6", "Column 7", "Column 8"}, rcAutoMerge)
		tw.AppendRow(longRow, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)
		tw.AppendRow(Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 2", "Y", "Y", "Y", "Y"}, rcAutoMerge)
		tw.SetAutoIndex(true)
		tw.SetColumnConfigs(testLongRowCCs)
		tw.SetStyle(StyleLight)
		tw.Style().Options.SeparateRows = true
		return tw
	}

	t.Run("no merge", func(t *testing.T) {
		tw := generateTableForLongRows(
			Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1 + "W", testLongCol1 + "H", testLongCol1 + "Y"},
		)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬──────────────────────────┬──────────────────────────┬──────────────────────────┬──────────────────────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │         COLUMN 5         │         COLUMN 6         │         COLUMN 7         │         COLUMN 8         │
├───┼──────────┼──────────┼──────────┼──────────┼──────────────────────────┼──────────────────────────┼──────────────────────────┼──────────────────────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │ 4F8F5CB531E3D49A61CF417C │ 4F8F5CB531E3D49A61CF417C │ 4F8F5CB531E3D49A61CF417C │ 4F8F5CB531E3D49A61CF417C │
│   │          │          │          │          │ D133792CCFA501FD8DA53EE3 │ D133792CCFA501FD8DA53EE3 │ D133792CCFA501FD8DA53EE3 │ D133792CCFA501FD8DA53EE3 │
│   │          │          │          │          │ 68FED20E5FE0248C3A0B64F9 │ 68FED20E5FE0248C3A0B64F9 │ 68FED20E5FE0248C3A0B64F9 │ 68FED20E5FE0248C3A0B64F9 │
│   │          │          │          │          │ 8A6533CEE1DA614C3A8DDEC7 │ 8A6533CEE1DA614C3A8DDEC7 │ 8A6533CEE1DA614C3A8DDEC7 │ 8A6533CEE1DA614C3A8DDEC7 │
│   │          │          │          │          │ 91FF05FEE6D971D57C134832 │ 91FF05FEE6D971D57C134832 │ 91FF05FEE6D971D57C134832 │ 91FF05FEE6D971D57C134832 │
│   │          │          │          │          │         0F4EB42DR        │        0F4EB42DRW        │        0F4EB42DRH        │        0F4EB42DRY        │
├───┼──────────┼──────────┼──────────┼──────────┼──────────────────────────┴──────────────────────────┴──────────────────────────┴──────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                                                     Y                                                     │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                                                     Y                                                     │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────┘`)
	})

	t.Run("merge 2 pairs", func(t *testing.T) {
		tw := generateTableForLongRows(
			Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1, testLongCol1 + "R", testLongCol1 + "R"},
		)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬─────────────┬─────────────┬─────────────┬─────────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │   COLUMN 5  │   COLUMN 6  │   COLUMN 7  │   COLUMN 8  │
├───┼──────────┼──────────┼──────────┼──────────┼─────────────┴─────────────┼─────────────┴─────────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │  4F8F5CB531E3D49A61CF417C │  4F8F5CB531E3D49A61CF417C │
│   │          │          │          │          │  D133792CCFA501FD8DA53EE3 │  D133792CCFA501FD8DA53EE3 │
│   │          │          │          │          │  68FED20E5FE0248C3A0B64F9 │  68FED20E5FE0248C3A0B64F9 │
│   │          │          │          │          │  8A6533CEE1DA614C3A8DDEC7 │  8A6533CEE1DA614C3A8DDEC7 │
│   │          │          │          │          │  91FF05FEE6D971D57C134832 │  91FF05FEE6D971D57C134832 │
│   │          │          │          │          │         0F4EB42DR         │         0F4EB42DRR        │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────┴───────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                           Y                           │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                           Y                           │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────────────────┘`)
	})

	t.Run("marge 3 columns", func(t *testing.T) {
		tw := generateTableForLongRows(
			Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1, testLongCol1, testLongCol1 + "E"},
		)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────────────────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │ COLUMN 5 │ COLUMN 6 │ COLUMN 7 │         COLUMN 8         │
├───┼──────────┼──────────┼──────────┼──────────┼──────────┴──────────┴──────────┼──────────────────────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │    4F8F5CB531E3D49A61CF417C    │ 4F8F5CB531E3D49A61CF417C │
│   │          │          │          │          │    D133792CCFA501FD8DA53EE3    │ D133792CCFA501FD8DA53EE3 │
│   │          │          │          │          │    68FED20E5FE0248C3A0B64F9    │ 68FED20E5FE0248C3A0B64F9 │
│   │          │          │          │          │    8A6533CEE1DA614C3A8DDEC7    │ 8A6533CEE1DA614C3A8DDEC7 │
│   │          │          │          │          │    91FF05FEE6D971D57C134832    │ 91FF05FEE6D971D57C134832 │
│   │          │          │          │          │            0F4EB42DR           │        0F4EB42DRE        │
├───┼──────────┼──────────┼──────────┼──────────┼────────────────────────────────┴──────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                             Y                             │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                             Y                             │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────────────────────┘`)
	})

	t.Run("merge 4 columns", func(t *testing.T) {
		tw := generateTableForLongRows(
			Row{"a.a.a.a", "Pod 1A", "NS 1A", "C 1", testLongCol1, testLongCol1, testLongCol1, testLongCol1},
		)

		compareOutput(t, tw.Render(), `
┌───┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│   │ COLUMN 1 │ COLUMN 2 │ COLUMN 3 │ COLUMN 4 │ COLUMN 5 │ COLUMN 6 │ COLUMN 7 │ COLUMN 8 │
├───┼──────────┼──────────┼──────────┼──────────┼──────────┴──────────┴──────────┴──────────┤
│ 1 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 1      │          4F8F5CB531E3D49A61CF417C         │
│   │          │          │          │          │          D133792CCFA501FD8DA53EE3         │
│   │          │          │          │          │          68FED20E5FE0248C3A0B64F9         │
│   │          │          │          │          │          8A6533CEE1DA614C3A8DDEC7         │
│   │          │          │          │          │          91FF05FEE6D971D57C134832         │
│   │          │          │          │          │                 0F4EB42DR                 │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────┤
│ 2 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                     Y                     │
├───┼──────────┼──────────┼──────────┼──────────┼───────────────────────────────────────────┤
│ 3 │ a.a.a.a  │ Pod 1A   │ NS 1A    │ C 2      │                     Y                     │
└───┴──────────┴──────────┴──────────┴──────────┴───────────────────────────────────────────┘`)
	})
}