1use Term::Table; 2use Term::Table::Util qw/USE_GCS/; 3 4use Test2::Tools::Tiny; 5 6use utf8; 7use strict; 8use warnings; 9 10use Test2::API qw/test2_stack/; 11test2_stack->top->format->encoding('utf8'); 12 13sub table { Term::Table->new(@_)->render } 14 15tests unicode_display_width => sub { 16 my $wide = "foo bar baz 婧"; 17 18 my $have_gcstring = eval { require Unicode::GCString; 1 }; 19 20 tests no_unicode_linebreak => sub { 21 my @table = table('header' => [ 'a', 'b'], 'rows' => [[ '婧', '߃' ]]); 22 23 is( 24 $table[0], 25 "Unicode::GCString is not installed, table may not display all unicode characters properly", 26 "got unicode note" 27 ); 28 } unless USE_GCS; 29 30 tests with_unicode_linebreak => sub { 31 my @table = table( 32 'header' => [ 'a', 'b'], 33 'rows' => [[ 'a婧b', '߃' ]], 34 'max_width' => 80, 35 ); 36 is_deeply( 37 \@table, 38 [ 39 '+------+---+', 40 '| a | b |', 41 '+------+---+', 42 '| a婧b | ߃ |', 43 '+------+---+', 44 ], 45 "Support for unicode characters that use multiple columns" 46 ); 47 } if USE_GCS; 48}; 49 50tests width => sub { 51 my @table = table( 52 max_width => 40, 53 header => [ 'a', 'b', 'c', 'd' ], 54 rows => [ 55 [ qw/aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccc ddddddddddddddddddddddddddddd/ ], 56 [ qw/AAAAAAAAAAAAAAAAAAAAAAAAAA BBBBBBBBBBBBBBBBBBBBB CCCCCCCCCCCCCCCCCCCCCCC DDDDDDDDDDDDDDDDDDDDDDDDDDDDD/ ], 57 ], 58 ); 59 60 is_deeply( 61 \@table, 62 [ 63 '+-------+-------+-------+-------+', 64 '| a | b | c | d |', 65 '+-------+-------+-------+-------+', 66 '| aaaaa | bbbbb | ccccc | ddddd |', 67 '| aaaaa | bbbbb | ccccc | ddddd |', 68 '| aaaaa | bbbbb | ccccc | ddddd |', 69 '| aaaaa | bbbbb | ccccc | ddddd |', 70 '| aaaaa | b | ccc | ddddd |', 71 '| a | | | dddd |', 72 '| | | | |', 73 '| AAAAA | BBBBB | CCCCC | DDDDD |', 74 '| AAAAA | BBBBB | CCCCC | DDDDD |', 75 '| AAAAA | BBBBB | CCCCC | DDDDD |', 76 '| AAAAA | BBBBB | CCCCC | DDDDD |', 77 '| AAAAA | B | CCC | DDDDD |', 78 '| A | | | DDDD |', 79 '+-------+-------+-------+-------+', 80 ], 81 "Basic table, small width" 82 ); 83 84 @table = table( 85 max_width => 60, 86 header => [ 'a', 'b', 'c', 'd' ], 87 rows => [ 88 [ qw/aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccc ddddddddddddddddddddddddddddd/ ], 89 [ qw/AAAAAAAAAAAAAAAAAAAAAAAAAA BBBBBBBBBBBBBBBBBBBBB CCCCCCCCCCCCCCCCCCCCCCC DDDDDDDDDDDDDDDDDDDDDDDDDDDDD/ ], 90 ], 91 ); 92 93 is_deeply( 94 \@table, 95 [ 96 '+------------+------------+------------+------------+', 97 '| a | b | c | d |', 98 '+------------+------------+------------+------------+', 99 '| aaaaaaaaaa | bbbbbbbbbb | cccccccccc | dddddddddd |', 100 '| aaaaaaaaaa | bbbbbbbbbb | cccccccccc | dddddddddd |', 101 '| aaaaaa | b | ccc | ddddddddd |', 102 '| | | | |', 103 '| AAAAAAAAAA | BBBBBBBBBB | CCCCCCCCCC | DDDDDDDDDD |', 104 '| AAAAAAAAAA | BBBBBBBBBB | CCCCCCCCCC | DDDDDDDDDD |', 105 '| AAAAAA | B | CCC | DDDDDDDDD |', 106 '+------------+------------+------------+------------+', 107 ], 108 "Basic table, bigger width" 109 ); 110 111 @table = table( 112 max_width => 60, 113 header => [ 'a', 'b', 'c', 'd' ], 114 rows => [ 115 [ qw/aaaa bbbb cccc dddd/ ], 116 [ qw/AAAA BBBB CCCC DDDD/ ], 117 ], 118 ); 119 120 is_deeply( 121 \@table, 122 [ 123 '+------+------+------+------+', 124 '| a | b | c | d |', 125 '+------+------+------+------+', 126 '| aaaa | bbbb | cccc | dddd |', 127 '| AAAA | BBBB | CCCC | DDDD |', 128 '+------+------+------+------+', 129 ], 130 "Short table, well under minimum", 131 ); 132}; 133 134tests collapse => sub { 135 my @table = table( 136 max_width => 60, 137 collapse => 1, 138 header => [ 'a', 'b', 'c', 'd' ], 139 rows => [ 140 [ qw/aaaa bbbb/, undef, qw/dddd/ ], 141 [ qw/AAAA BBBB/, '', qw/DDDD/ ], 142 ], 143 ); 144 145 is_deeply( 146 \@table, 147 [ 148 '+------+------+------+', 149 '| a | b | d |', 150 '+------+------+------+', 151 '| aaaa | bbbb | dddd |', 152 '| AAAA | BBBB | DDDD |', 153 '+------+------+------+', 154 ], 155 "Table collapsed", 156 ); 157 158 @table = table( 159 max_width => 60, 160 collapse => 0, 161 header => [ 'a', 'b', 'c', 'd' ], 162 rows => [ 163 [ qw/aaaa bbbb/, undef, qw/dddd/ ], 164 [ qw/AAAA BBBB/, '', qw/DDDD/ ], 165 ], 166 ); 167 168 is_deeply( 169 \@table, 170 [ 171 '+------+------+---+------+', 172 '| a | b | c | d |', 173 '+------+------+---+------+', 174 '| aaaa | bbbb | | dddd |', 175 '| AAAA | BBBB | | DDDD |', 176 '+------+------+---+------+', 177 ], 178 "Table not collapsed", 179 ); 180 181 @table = table( 182 max_width => 60, 183 collapse => 1, 184 header => [ 'a', 'b', 'c', 'd' ], 185 rows => [ 186 [ qw/aaaa bbbb/, undef, qw/dddd/ ], 187 [ qw/AAAA BBBB/, 0, qw/DDDD/ ], 188 ], 189 ); 190 191 is_deeply( 192 \@table, 193 [ 194 '+------+------+---+------+', 195 '| a | b | c | d |', 196 '+------+------+---+------+', 197 '| aaaa | bbbb | | dddd |', 198 '| AAAA | BBBB | 0 | DDDD |', 199 '+------+------+---+------+', 200 ], 201 "'0' value does not cause collapse", 202 ); 203 204}; 205 206tests header => sub { 207 my @table = table( 208 max_width => 60, 209 header => [ 'a', 'b', 'c', 'd' ], 210 rows => [ 211 [ qw/aaaa bbbb cccc dddd/ ], 212 [ qw/AAAA BBBB CCCC DDDD/ ], 213 ], 214 ); 215 216 is_deeply( 217 \@table, 218 [ 219 '+------+------+------+------+', 220 '| a | b | c | d |', 221 '+------+------+------+------+', 222 '| aaaa | bbbb | cccc | dddd |', 223 '| AAAA | BBBB | CCCC | DDDD |', 224 '+------+------+------+------+', 225 ], 226 "Table with header", 227 ); 228}; 229 230tests no_header => sub { 231 my @table = table( 232 max_width => 60, 233 rows => [ 234 [ qw/aaaa bbbb cccc dddd/ ], 235 [ qw/AAAA BBBB CCCC DDDD/ ], 236 ], 237 ); 238 239 is_deeply( 240 \@table, 241 [ 242 '+------+------+------+------+', 243 '| aaaa | bbbb | cccc | dddd |', 244 '| AAAA | BBBB | CCCC | DDDD |', 245 '+------+------+------+------+', 246 ], 247 "Table without header", 248 ); 249}; 250 251tests sanitize => sub { 252 my @table = table( 253 max_width => 60, 254 sanitize => 1, 255 header => [ 'data1' ], 256 rows => [["a\t\n\r\b\a \N{U+000B}bф"]], 257 ); 258 259 my $have_gcstring = eval { require Unicode::GCString; 1 } || 0; 260 261 is_deeply( 262 \@table, 263 [ 264 ( 265 $have_gcstring 266 ? () 267 : ("Unicode::GCString is not installed, table may not display all unicode characters properly") 268 ), 269 '+------------------------------------------------------+', 270 '| data1 |', 271 '+------------------------------------------------------+', 272 '| a\\t\\n |', 273 '| \\r\\b\\a\\N{U+A0}\\N{U+1680}\\N{U+2000}\\N{U+2001}\\N{U+200 |', 274 '| 2}\\N{U+2003}\\N{U+2004}\\N{U+2008}\\N{U+2028}\\N{U+2029} |', 275 "| \\N{U+3000}\\N{U+200C}\\N{U+FEFF}\\N{U+B}b\x{444} |", 276 '+------------------------------------------------------+' 277 ], 278 "Sanitized data" 279 ); 280}; 281 282tests mark_tail => sub { 283 my @table = table( 284 max_width => 60, 285 mark_tail => 1, 286 header => [ 'data1', 'data2' ], 287 rows => [[" abc def ", " abc def \t"]], 288 ); 289 290 is_deeply( 291 \@table, 292 [ 293 '+----------------------+----------------+', 294 '| data1 | data2 |', 295 '+----------------------+----------------+', 296 '| abc def \N{U+20} | abc def \t |', 297 '+----------------------+----------------+', 298 ], 299 "Sanitized data" 300 ); 301 302}; 303 304done_testing; 305