TYPO3  7.6
TableTest.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace Symfony\Component\Console\Tests\Helper;
13 
19 
20 class TableTest extends \PHPUnit_Framework_TestCase
21 {
22  protected $stream;
23 
24  protected function setUp()
25  {
26  $this->stream = fopen('php://memory', 'r+');
27  }
28 
29  protected function tearDown()
30  {
31  fclose($this->stream);
32  $this->stream = null;
33  }
34 
38  public function testRender($headers, $rows, $style, $expected)
39  {
40  $table = new Table($output = $this->getOutputStream());
41  $table
42  ->setHeaders($headers)
43  ->setRows($rows)
44  ->setStyle($style)
45  ;
46  $table->render();
47 
48  $this->assertEquals($expected, $this->getOutputContent($output));
49  }
50 
54  public function testRenderAddRows($headers, $rows, $style, $expected)
55  {
56  $table = new Table($output = $this->getOutputStream());
57  $table
58  ->setHeaders($headers)
59  ->addRows($rows)
60  ->setStyle($style)
61  ;
62  $table->render();
63 
64  $this->assertEquals($expected, $this->getOutputContent($output));
65  }
66 
70  public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected)
71  {
72  $table = new Table($output = $this->getOutputStream());
73  $table
74  ->setHeaders($headers)
75  ->setStyle($style)
76  ;
77  foreach ($rows as $row) {
78  $table->addRow($row);
79  }
80  $table->render();
81 
82  $this->assertEquals($expected, $this->getOutputContent($output));
83  }
84 
85  public function testRenderProvider()
86  {
87  $books = array(
88  array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
89  array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
90  array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
91  array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
92  );
93 
94  return array(
95  array(
96  array('ISBN', 'Title', 'Author'),
97  $books,
98  'default',
99 <<<TABLE
100 +---------------+--------------------------+------------------+
101 | ISBN | Title | Author |
102 +---------------+--------------------------+------------------+
103 | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
104 | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
105 | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
106 | 80-902734-1-6 | And Then There Were None | Agatha Christie |
107 +---------------+--------------------------+------------------+
108 
109 TABLE
110  ),
111  array(
112  array('ISBN', 'Title', 'Author'),
113  $books,
114  'compact',
115 <<<TABLE
116  ISBN Title Author
117  99921-58-10-7 Divine Comedy Dante Alighieri
118  9971-5-0210-0 A Tale of Two Cities Charles Dickens
119  960-425-059-0 The Lord of the Rings J. R. R. Tolkien
120  80-902734-1-6 And Then There Were None Agatha Christie
121 
122 TABLE
123  ),
124  array(
125  array('ISBN', 'Title', 'Author'),
126  $books,
127  'borderless',
128 <<<TABLE
129  =============== ========================== ==================
130  ISBN Title Author
131  =============== ========================== ==================
132  99921-58-10-7 Divine Comedy Dante Alighieri
133  9971-5-0210-0 A Tale of Two Cities Charles Dickens
134  960-425-059-0 The Lord of the Rings J. R. R. Tolkien
135  80-902734-1-6 And Then There Were None Agatha Christie
136  =============== ========================== ==================
137 
138 TABLE
139  ),
140  array(
141  array('ISBN', 'Title'),
142  array(
143  array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
144  array('9971-5-0210-0'),
145  array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
146  array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
147  ),
148  'default',
149 <<<TABLE
150 +---------------+--------------------------+------------------+
151 | ISBN | Title | |
152 +---------------+--------------------------+------------------+
153 | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
154 | 9971-5-0210-0 | | |
155 | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
156 | 80-902734-1-6 | And Then There Were None | Agatha Christie |
157 +---------------+--------------------------+------------------+
158 
159 TABLE
160  ),
161  array(
162  array(),
163  array(
164  array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
165  array('9971-5-0210-0'),
166  array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
167  array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
168  ),
169  'default',
170 <<<TABLE
171 +---------------+--------------------------+------------------+
172 | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
173 | 9971-5-0210-0 | | |
174 | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
175 | 80-902734-1-6 | And Then There Were None | Agatha Christie |
176 +---------------+--------------------------+------------------+
177 
178 TABLE
179  ),
180  array(
181  array('ISBN', 'Title', 'Author'),
182  array(
183  array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'),
184  array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
185  array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
186  array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"),
187  ),
188  'default',
189 <<<TABLE
190 +---------------+----------------------------+-----------------+
191 | ISBN | Title | Author |
192 +---------------+----------------------------+-----------------+
193 | 99921-58-10-7 | Divine | Dante Alighieri |
194 | | Comedy | |
195 | 9971-5-0210-2 | Harry Potter | Rowling |
196 | | and the Chamber of Secrets | Joanne K. |
197 | 9971-5-0210-2 | Harry Potter | Rowling |
198 | | and the Chamber of Secrets | Joanne K. |
199 | 960-425-059-0 | The Lord of the Rings | J. R. R. |
200 | | | Tolkien |
201 +---------------+----------------------------+-----------------+
202 
203 TABLE
204  ),
205  array(
206  array('ISBN', 'Title'),
207  array(),
208  'default',
209 <<<TABLE
210 +------+-------+
211 | ISBN | Title |
212 +------+-------+
213 
214 TABLE
215  ),
216  array(
217  array(),
218  array(),
219  'default',
220  '',
221  ),
222  'Cell text with tags used for Output styling' => array(
223  array('ISBN', 'Title', 'Author'),
224  array(
225  array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
226  array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
227  ),
228  'default',
229 <<<TABLE
230 +---------------+----------------------+-----------------+
231 | ISBN | Title | Author |
232 +---------------+----------------------+-----------------+
233 | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
234 | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
235 +---------------+----------------------+-----------------+
236 
237 TABLE
238  ),
239  'Cell text with tags not used for Output styling' => array(
240  array('ISBN', 'Title', 'Author'),
241  array(
242  array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
243  array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
244  ),
245  'default',
246 <<<TABLE
247 +----------------------------------+----------------------+-----------------+
248 | ISBN | Title | Author |
249 +----------------------------------+----------------------+-----------------+
250 | <strong>99921-58-10-700</strong> | <f>Divine Com</f> | Dante Alighieri |
251 | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
252 +----------------------------------+----------------------+-----------------+
253 
254 TABLE
255  ),
256  'Cell with colspan' => array(
257  array('ISBN', 'Title', 'Author'),
258  array(
259  array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
260  new TableSeparator(),
261  array(new TableCell('Divine Comedy(Dante Alighieri)', array('colspan' => 3))),
262  new TableSeparator(),
263  array(
264  new TableCell('Arduino: A Quick-Start Guide', array('colspan' => 2)),
265  'Mark Schmidt',
266  ),
267  new TableSeparator(),
268  array(
269  '9971-5-0210-0',
270  new TableCell("A Tale of \nTwo Cities", array('colspan' => 2)),
271  ),
272  ),
273  'default',
274 <<<TABLE
275 +----------------+---------------+-----------------+
276 | ISBN | Title | Author |
277 +----------------+---------------+-----------------+
278 | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
279 +----------------+---------------+-----------------+
280 | Divine Comedy(Dante Alighieri) |
281 +----------------+---------------+-----------------+
282 | Arduino: A Quick-Start Guide | Mark Schmidt |
283 +----------------+---------------+-----------------+
284 | 9971-5-0210-0 | A Tale of |
285 | | Two Cities |
286 +----------------+---------------+-----------------+
287 
288 TABLE
289  ),
290  'Cell with rowspan' => array(
291  array('ISBN', 'Title', 'Author'),
292  array(
293  array(
294  new TableCell('9971-5-0210-0', array('rowspan' => 3)),
295  'Divine Comedy',
296  'Dante Alighieri',
297  ),
298  array('A Tale of Two Cities', 'Charles Dickens'),
299  array("The Lord of \nthe Rings", "J. R. \nR. Tolkien"),
300  new TableSeparator(),
301  array('80-902734-1-6', new TableCell("And Then \nThere \nWere None", array('rowspan' => 3)), 'Agatha Christie'),
302  array('80-902734-1-7', 'Test'),
303  ),
304  'default',
305 <<<TABLE
306 +---------------+----------------------+-----------------+
307 | ISBN | Title | Author |
308 +---------------+----------------------+-----------------+
309 | 9971-5-0210-0 | Divine Comedy | Dante Alighieri |
310 | | A Tale of Two Cities | Charles Dickens |
311 | | The Lord of | J. R. |
312 | | the Rings | R. Tolkien |
313 +---------------+----------------------+-----------------+
314 | 80-902734-1-6 | And Then | Agatha Christie |
315 | 80-902734-1-7 | There | Test |
316 | | Were None | |
317 +---------------+----------------------+-----------------+
318 
319 TABLE
320  ),
321  'Cell with rowspan and colspan' => array(
322  array('ISBN', 'Title', 'Author'),
323  array(
324  array(
325  new TableCell('9971-5-0210-0', array('rowspan' => 2, 'colspan' => 2)),
326  'Dante Alighieri',
327  ),
328  array('Charles Dickens'),
329  new TableSeparator(),
330  array(
331  'Dante Alighieri',
332  new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 2)),
333  ),
334  array('J. R. R. Tolkien'),
335  array('J. R. R'),
336  ),
337  'default',
338 <<<TABLE
339 +------------------+--------+-----------------+
340 | ISBN | Title | Author |
341 +------------------+--------+-----------------+
342 | 9971-5-0210-0 | Dante Alighieri |
343 | | Charles Dickens |
344 +------------------+--------+-----------------+
345 | Dante Alighieri | 9971-5-0210-0 |
346 | J. R. R. Tolkien | |
347 | J. R. R | |
348 +------------------+--------+-----------------+
349 
350 TABLE
351  ),
352  'Cell with rowspan and colspan contains new line break' => array(
353  array('ISBN', 'Title', 'Author'),
354  array(
355  array(
356  new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
357  'Dante Alighieri',
358  ),
359  array('Charles Dickens'),
360  new TableSeparator(),
361  array(
362  'Dante Alighieri',
363  new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
364  ),
365  array('Charles Dickens'),
366  new TableSeparator(),
367  array(
368  new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
369  new TableCell("Dante \nAlighieri", array('rowspan' => 2, 'colspan' => 1)),
370  ),
371  ),
372  'default',
373 <<<TABLE
374 +-----------------+-------+-----------------+
375 | ISBN | Title | Author |
376 +-----------------+-------+-----------------+
377 | 9971 | Dante Alighieri |
378 | -5- | Charles Dickens |
379 | 021 | |
380 | 0-0 | |
381 +-----------------+-------+-----------------+
382 | Dante Alighieri | 9971 |
383 | Charles Dickens | -5- |
384 | | 021 |
385 | | 0-0 |
386 +-----------------+-------+-----------------+
387 | 9971 | Dante |
388 | -5- | Alighieri |
389 | 021 | |
390 | 0-0 | |
391 +-----------------+-------+-----------------+
392 
393 TABLE
394  ),
395  'Cell with rowspan and colspan without using TableSeparator' => array(
396  array('ISBN', 'Title', 'Author'),
397  array(
398  array(
399  new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
400  'Dante Alighieri',
401  ),
402  array('Charles Dickens'),
403  array(
404  'Dante Alighieri',
405  new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
406  ),
407  array('Charles Dickens'),
408  ),
409  'default',
410 <<<TABLE
411 +-----------------+-------+-----------------+
412 | ISBN | Title | Author |
413 +-----------------+-------+-----------------+
414 | 9971 | Dante Alighieri |
415 | -5- | Charles Dickens |
416 | 021 | |
417 | 0-0 | |
418 | Dante Alighieri | 9971 |
419 | Charles Dickens | -5- |
420 | | 021 |
421 | | 0-0 |
422 +-----------------+-------+-----------------+
423 
424 TABLE
425  ),
426  'Cell with rowspan and colspan with separator inside a rowspan' => array(
427  array('ISBN', 'Author'),
428  array(
429  array(
430  new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)),
431  'Dante Alighieri',
432  ),
433  array(new TableSeparator()),
434  array('Charles Dickens'),
435  ),
436  'default',
437 <<<TABLE
438 +---------------+-----------------+
439 | ISBN | Author |
440 +---------------+-----------------+
441 | 9971-5-0210-0 | Dante Alighieri |
442 | |-----------------|
443 | | Charles Dickens |
444 +---------------+-----------------+
445 
446 TABLE
447  ),
448  'Multiple header lines' => array(
449  array(
450  array(new TableCell('Main title', array('colspan' => 3))),
451  array('ISBN', 'Title', 'Author'),
452  ),
453  array(),
454  'default',
455 <<<TABLE
456 +------+-------+--------+
457 | Main title |
458 +------+-------+--------+
459 | ISBN | Title | Author |
460 +------+-------+--------+
461 
462 TABLE
463  ),
464  );
465  }
466 
467  public function testRenderMultiByte()
468  {
469  if (!function_exists('mb_strlen')) {
470  $this->markTestSkipped('The "mbstring" extension is not available');
471  }
472 
473  $table = new Table($output = $this->getOutputStream());
474  $table
475  ->setHeaders(array('■■'))
476  ->setRows(array(array(1234)))
477  ->setStyle('default')
478  ;
479  $table->render();
480 
481  $expected =
482 <<<TABLE
483 +------+
484 | ■■ |
485 +------+
486 | 1234 |
487 +------+
488 
489 TABLE;
490 
491  $this->assertEquals($expected, $this->getOutputContent($output));
492  }
493 
494  public function testStyle()
495  {
496  $style = new TableStyle();
497  $style
498  ->setHorizontalBorderChar('.')
499  ->setVerticalBorderChar('.')
500  ->setCrossingChar('.')
501  ;
502 
503  Table::setStyleDefinition('dotfull', $style);
504  $table = new Table($output = $this->getOutputStream());
505  $table
506  ->setHeaders(array('Foo'))
507  ->setRows(array(array('Bar')))
508  ->setStyle('dotfull');
509  $table->render();
510 
511  $expected =
512 <<<TABLE
513 .......
514 . Foo .
515 .......
516 . Bar .
517 .......
518 
519 TABLE;
520 
521  $this->assertEquals($expected, $this->getOutputContent($output));
522  }
523 
524  public function testRowSeparator()
525  {
526  $table = new Table($output = $this->getOutputStream());
527  $table
528  ->setHeaders(array('Foo'))
529  ->setRows(array(
530  array('Bar1'),
531  new TableSeparator(),
532  array('Bar2'),
533  new TableSeparator(),
534  array('Bar3'),
535  ));
536  $table->render();
537 
538  $expected =
539 <<<TABLE
540 +------+
541 | Foo |
542 +------+
543 | Bar1 |
544 +------+
545 | Bar2 |
546 +------+
547 | Bar3 |
548 +------+
549 
550 TABLE;
551 
552  $this->assertEquals($expected, $this->getOutputContent($output));
553 
554  $this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works');
555  }
556 
557  protected function getOutputStream()
558  {
559  return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
560  }
561 
562  protected function getOutputContent(StreamOutput $output)
563  {
564  rewind($output->getStream());
565 
566  return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
567  }
568 }