/src/Symfony/Component/Console/Tests/Helper/TableTest.php

https://github.com/deviantintegral/symfony · PHP · 854 lines · 738 code · 87 blank · 29 comment · 0 complexity · ecbcd76528ca6b6e472f6b4ecde9d9fe MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Console\Tests\Helper;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\Console\Helper\Table;
  13. use Symfony\Component\Console\Helper\TableStyle;
  14. use Symfony\Component\Console\Helper\TableSeparator;
  15. use Symfony\Component\Console\Helper\TableCell;
  16. use Symfony\Component\Console\Output\StreamOutput;
  17. class TableTest extends TestCase
  18. {
  19. protected $stream;
  20. protected function setUp()
  21. {
  22. $this->stream = fopen('php://memory', 'r+');
  23. }
  24. protected function tearDown()
  25. {
  26. fclose($this->stream);
  27. $this->stream = null;
  28. }
  29. /**
  30. * @dataProvider renderProvider
  31. */
  32. public function testRender($headers, $rows, $style, $expected, $decorated = false)
  33. {
  34. $table = new Table($output = $this->getOutputStream($decorated));
  35. $table
  36. ->setHeaders($headers)
  37. ->setRows($rows)
  38. ->setStyle($style)
  39. ;
  40. $table->render();
  41. $this->assertEquals($expected, $this->getOutputContent($output));
  42. }
  43. /**
  44. * @dataProvider renderProvider
  45. */
  46. public function testRenderAddRows($headers, $rows, $style, $expected, $decorated = false)
  47. {
  48. $table = new Table($output = $this->getOutputStream($decorated));
  49. $table
  50. ->setHeaders($headers)
  51. ->addRows($rows)
  52. ->setStyle($style)
  53. ;
  54. $table->render();
  55. $this->assertEquals($expected, $this->getOutputContent($output));
  56. }
  57. /**
  58. * @dataProvider renderProvider
  59. */
  60. public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected, $decorated = false)
  61. {
  62. $table = new Table($output = $this->getOutputStream($decorated));
  63. $table
  64. ->setHeaders($headers)
  65. ->setStyle($style)
  66. ;
  67. foreach ($rows as $row) {
  68. $table->addRow($row);
  69. }
  70. $table->render();
  71. $this->assertEquals($expected, $this->getOutputContent($output));
  72. }
  73. public function renderProvider()
  74. {
  75. $books = array(
  76. array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
  77. array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
  78. array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
  79. array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
  80. );
  81. return array(
  82. array(
  83. array('ISBN', 'Title', 'Author'),
  84. $books,
  85. 'default',
  86. <<<'TABLE'
  87. +---------------+--------------------------+------------------+
  88. | ISBN | Title | Author |
  89. +---------------+--------------------------+------------------+
  90. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  91. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
  92. | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
  93. | 80-902734-1-6 | And Then There Were None | Agatha Christie |
  94. +---------------+--------------------------+------------------+
  95. TABLE
  96. ),
  97. array(
  98. array('ISBN', 'Title', 'Author'),
  99. $books,
  100. 'compact',
  101. <<<'TABLE'
  102. ISBN Title Author
  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. TABLE
  108. ),
  109. array(
  110. array('ISBN', 'Title', 'Author'),
  111. $books,
  112. 'borderless',
  113. <<<'TABLE'
  114. =============== ========================== ==================
  115. ISBN Title Author
  116. =============== ========================== ==================
  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. 'box',
  128. <<<'TABLE'
  129. ISBN Title Author
  130. 99921-58-10-7 Divine Comedy Dante Alighieri
  131. 9971-5-0210-0 A Tale of Two Cities Charles Dickens
  132. 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
  133. 80-902734-1-6 And Then There Were None Agatha Christie
  134. TABLE
  135. ),
  136. array(
  137. array('ISBN', 'Title'),
  138. array(
  139. array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
  140. array('9971-5-0210-0'),
  141. array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
  142. array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
  143. ),
  144. 'default',
  145. <<<'TABLE'
  146. +---------------+--------------------------+------------------+
  147. | ISBN | Title | |
  148. +---------------+--------------------------+------------------+
  149. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  150. | 9971-5-0210-0 | | |
  151. | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
  152. | 80-902734-1-6 | And Then There Were None | Agatha Christie |
  153. +---------------+--------------------------+------------------+
  154. TABLE
  155. ),
  156. array(
  157. array(),
  158. array(
  159. array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
  160. array('9971-5-0210-0'),
  161. array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
  162. array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
  163. ),
  164. 'default',
  165. <<<'TABLE'
  166. +---------------+--------------------------+------------------+
  167. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  168. | 9971-5-0210-0 | | |
  169. | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
  170. | 80-902734-1-6 | And Then There Were None | Agatha Christie |
  171. +---------------+--------------------------+------------------+
  172. TABLE
  173. ),
  174. array(
  175. array('ISBN', 'Title', 'Author'),
  176. array(
  177. array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'),
  178. array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
  179. array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
  180. array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"),
  181. ),
  182. 'default',
  183. <<<'TABLE'
  184. +---------------+----------------------------+-----------------+
  185. | ISBN | Title | Author |
  186. +---------------+----------------------------+-----------------+
  187. | 99921-58-10-7 | Divine | Dante Alighieri |
  188. | | Comedy | |
  189. | 9971-5-0210-2 | Harry Potter | Rowling |
  190. | | and the Chamber of Secrets | Joanne K. |
  191. | 9971-5-0210-2 | Harry Potter | Rowling |
  192. | | and the Chamber of Secrets | Joanne K. |
  193. | 960-425-059-0 | The Lord of the Rings | J. R. R. |
  194. | | | Tolkien |
  195. +---------------+----------------------------+-----------------+
  196. TABLE
  197. ),
  198. array(
  199. array('ISBN', 'Title'),
  200. array(),
  201. 'default',
  202. <<<'TABLE'
  203. +------+-------+
  204. | ISBN | Title |
  205. +------+-------+
  206. TABLE
  207. ),
  208. array(
  209. array(),
  210. array(),
  211. 'default',
  212. '',
  213. ),
  214. 'Cell text with tags used for Output styling' => array(
  215. array('ISBN', 'Title', 'Author'),
  216. array(
  217. array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
  218. array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
  219. ),
  220. 'default',
  221. <<<'TABLE'
  222. +---------------+----------------------+-----------------+
  223. | ISBN | Title | Author |
  224. +---------------+----------------------+-----------------+
  225. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  226. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
  227. +---------------+----------------------+-----------------+
  228. TABLE
  229. ),
  230. 'Cell text with tags not used for Output styling' => array(
  231. array('ISBN', 'Title', 'Author'),
  232. array(
  233. array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
  234. array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
  235. ),
  236. 'default',
  237. <<<'TABLE'
  238. +----------------------------------+----------------------+-----------------+
  239. | ISBN | Title | Author |
  240. +----------------------------------+----------------------+-----------------+
  241. | <strong>99921-58-10-700</strong> | <f>Divine Com</f> | Dante Alighieri |
  242. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
  243. +----------------------------------+----------------------+-----------------+
  244. TABLE
  245. ),
  246. 'Cell with colspan' => array(
  247. array('ISBN', 'Title', 'Author'),
  248. array(
  249. array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
  250. new TableSeparator(),
  251. array(new TableCell('Divine Comedy(Dante Alighieri)', array('colspan' => 3))),
  252. new TableSeparator(),
  253. array(
  254. new TableCell('Arduino: A Quick-Start Guide', array('colspan' => 2)),
  255. 'Mark Schmidt',
  256. ),
  257. new TableSeparator(),
  258. array(
  259. '9971-5-0210-0',
  260. new TableCell("A Tale of \nTwo Cities", array('colspan' => 2)),
  261. ),
  262. new TableSeparator(),
  263. array(
  264. new TableCell('Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil!', array('colspan' => 3)),
  265. ),
  266. ),
  267. 'default',
  268. <<<'TABLE'
  269. +-------------------------------+-------------------------------+-----------------------------+
  270. | ISBN | Title | Author |
  271. +-------------------------------+-------------------------------+-----------------------------+
  272. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  273. +-------------------------------+-------------------------------+-----------------------------+
  274. | Divine Comedy(Dante Alighieri) |
  275. +-------------------------------+-------------------------------+-----------------------------+
  276. | Arduino: A Quick-Start Guide | Mark Schmidt |
  277. +-------------------------------+-------------------------------+-----------------------------+
  278. | 9971-5-0210-0 | A Tale of |
  279. | | Two Cities |
  280. +-------------------------------+-------------------------------+-----------------------------+
  281. | Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil! |
  282. +-------------------------------+-------------------------------+-----------------------------+
  283. TABLE
  284. ),
  285. 'Cell with rowspan' => array(
  286. array('ISBN', 'Title', 'Author'),
  287. array(
  288. array(
  289. new TableCell('9971-5-0210-0', array('rowspan' => 3)),
  290. new TableCell('Divine Comedy', array('rowspan' => 2)),
  291. 'Dante Alighieri',
  292. ),
  293. array(),
  294. array("The Lord of \nthe Rings", "J. R. \nR. Tolkien"),
  295. new TableSeparator(),
  296. array('80-902734-1-6', new TableCell("And Then \nThere \nWere None", array('rowspan' => 3)), 'Agatha Christie'),
  297. array('80-902734-1-7', 'Test'),
  298. ),
  299. 'default',
  300. <<<'TABLE'
  301. +---------------+---------------+-----------------+
  302. | ISBN | Title | Author |
  303. +---------------+---------------+-----------------+
  304. | 9971-5-0210-0 | Divine Comedy | Dante Alighieri |
  305. | | | |
  306. | | The Lord of | J. R. |
  307. | | the Rings | R. Tolkien |
  308. +---------------+---------------+-----------------+
  309. | 80-902734-1-6 | And Then | Agatha Christie |
  310. | 80-902734-1-7 | There | Test |
  311. | | Were None | |
  312. +---------------+---------------+-----------------+
  313. TABLE
  314. ),
  315. 'Cell with rowspan and colspan' => array(
  316. array('ISBN', 'Title', 'Author'),
  317. array(
  318. array(
  319. new TableCell('9971-5-0210-0', array('rowspan' => 2, 'colspan' => 2)),
  320. 'Dante Alighieri',
  321. ),
  322. array('Charles Dickens'),
  323. new TableSeparator(),
  324. array(
  325. 'Dante Alighieri',
  326. new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 2)),
  327. ),
  328. array('J. R. R. Tolkien'),
  329. array('J. R. R'),
  330. ),
  331. 'default',
  332. <<<'TABLE'
  333. +------------------+---------+-----------------+
  334. | ISBN | Title | Author |
  335. +------------------+---------+-----------------+
  336. | 9971-5-0210-0 | Dante Alighieri |
  337. | | Charles Dickens |
  338. +------------------+---------+-----------------+
  339. | Dante Alighieri | 9971-5-0210-0 |
  340. | J. R. R. Tolkien | |
  341. | J. R. R | |
  342. +------------------+---------+-----------------+
  343. TABLE
  344. ),
  345. 'Cell with rowspan and colspan contains new line break' => array(
  346. array('ISBN', 'Title', 'Author'),
  347. array(
  348. array(
  349. new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
  350. 'Dante Alighieri',
  351. ),
  352. array('Charles Dickens'),
  353. new TableSeparator(),
  354. array(
  355. 'Dante Alighieri',
  356. new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
  357. ),
  358. array('Charles Dickens'),
  359. new TableSeparator(),
  360. array(
  361. new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
  362. new TableCell("Dante \nAlighieri", array('rowspan' => 2, 'colspan' => 1)),
  363. ),
  364. ),
  365. 'default',
  366. <<<'TABLE'
  367. +-----------------+-------+-----------------+
  368. | ISBN | Title | Author |
  369. +-----------------+-------+-----------------+
  370. | 9971 | Dante Alighieri |
  371. | -5- | Charles Dickens |
  372. | 021 | |
  373. | 0-0 | |
  374. +-----------------+-------+-----------------+
  375. | Dante Alighieri | 9971 |
  376. | Charles Dickens | -5- |
  377. | | 021 |
  378. | | 0-0 |
  379. +-----------------+-------+-----------------+
  380. | 9971 | Dante |
  381. | -5- | Alighieri |
  382. | 021 | |
  383. | 0-0 | |
  384. +-----------------+-------+-----------------+
  385. TABLE
  386. ),
  387. 'Cell with rowspan and colspan without using TableSeparator' => array(
  388. array('ISBN', 'Title', 'Author'),
  389. array(
  390. array(
  391. new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
  392. 'Dante Alighieri',
  393. ),
  394. array('Charles Dickens'),
  395. array(
  396. 'Dante Alighieri',
  397. new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
  398. ),
  399. array('Charles Dickens'),
  400. ),
  401. 'default',
  402. <<<'TABLE'
  403. +-----------------+-------+-----------------+
  404. | ISBN | Title | Author |
  405. +-----------------+-------+-----------------+
  406. | 9971 | Dante Alighieri |
  407. | -5- | Charles Dickens |
  408. | 021 | |
  409. | 0-0 | |
  410. | Dante Alighieri | 9971 |
  411. | Charles Dickens | -5- |
  412. | | 021 |
  413. | | 0-0 |
  414. +-----------------+-------+-----------------+
  415. TABLE
  416. ),
  417. 'Cell with rowspan and colspan with separator inside a rowspan' => array(
  418. array('ISBN', 'Author'),
  419. array(
  420. array(
  421. new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)),
  422. 'Dante Alighieri',
  423. ),
  424. array(new TableSeparator()),
  425. array('Charles Dickens'),
  426. ),
  427. 'default',
  428. <<<'TABLE'
  429. +---------------+-----------------+
  430. | ISBN | Author |
  431. +---------------+-----------------+
  432. | 9971-5-0210-0 | Dante Alighieri |
  433. | |-----------------|
  434. | | Charles Dickens |
  435. +---------------+-----------------+
  436. TABLE
  437. ),
  438. 'Multiple header lines' => array(
  439. array(
  440. array(new TableCell('Main title', array('colspan' => 3))),
  441. array('ISBN', 'Title', 'Author'),
  442. ),
  443. array(),
  444. 'default',
  445. <<<'TABLE'
  446. +------+-------+--------+
  447. | Main title |
  448. +------+-------+--------+
  449. | ISBN | Title | Author |
  450. +------+-------+--------+
  451. TABLE
  452. ),
  453. 'Row with multiple cells' => array(
  454. array(),
  455. array(
  456. array(
  457. new TableCell('1', array('colspan' => 3)),
  458. new TableCell('2', array('colspan' => 2)),
  459. new TableCell('3', array('colspan' => 2)),
  460. new TableCell('4', array('colspan' => 2)),
  461. ),
  462. ),
  463. 'default',
  464. <<<'TABLE'
  465. +---+--+--+---+--+---+--+---+--+
  466. | 1 | 2 | 3 | 4 |
  467. +---+--+--+---+--+---+--+---+--+
  468. TABLE
  469. ),
  470. 'Coslpan and table cells with comment style' => array(
  471. array(
  472. new TableCell('<comment>Long Title</comment>', array('colspan' => 3)),
  473. ),
  474. array(
  475. array(
  476. new TableCell('9971-5-0210-0', array('colspan' => 3)),
  477. ),
  478. new TableSeparator(),
  479. array(
  480. 'Dante Alighieri',
  481. 'J. R. R. Tolkien',
  482. 'J. R. R',
  483. ),
  484. ),
  485. 'default',
  486. <<<TABLE
  487. +-----------------+------------------+---------+
  488. |\033[32m \033[39m\033[33mLong Title\033[39m\033[32m \033[39m|
  489. +-----------------+------------------+---------+
  490. | 9971-5-0210-0 |
  491. +-----------------+------------------+---------+
  492. | Dante Alighieri | J. R. R. Tolkien | J. R. R |
  493. +-----------------+------------------+---------+
  494. TABLE
  495. ,
  496. true,
  497. ),
  498. 'Row with formatted cells containing a newline' => array(
  499. array(),
  500. array(
  501. array(
  502. new TableCell('<error>Dont break'."\n".'here</error>', array('colspan' => 2)),
  503. ),
  504. new TableSeparator(),
  505. array(
  506. 'foo',
  507. new TableCell('<error>Dont break'."\n".'here</error>', array('rowspan' => 2)),
  508. ),
  509. array(
  510. 'bar',
  511. ),
  512. ),
  513. 'default',
  514. <<<'TABLE'
  515. +-------+------------+
  516. | Dont break |
  517. | here |
  518. +-------+------------+
  519. | foo | Dont break |
  520. | bar | here |
  521. +-------+------------+
  522. TABLE
  523. ,
  524. true,
  525. ),
  526. );
  527. }
  528. public function testRenderMultiByte()
  529. {
  530. $table = new Table($output = $this->getOutputStream());
  531. $table
  532. ->setHeaders(array('■■'))
  533. ->setRows(array(array(1234)))
  534. ->setStyle('default')
  535. ;
  536. $table->render();
  537. $expected =
  538. <<<'TABLE'
  539. +------+
  540. | |
  541. +------+
  542. | 1234 |
  543. +------+
  544. TABLE;
  545. $this->assertEquals($expected, $this->getOutputContent($output));
  546. }
  547. public function testTableCellWithNumericIntValue()
  548. {
  549. $table = new Table($output = $this->getOutputStream());
  550. $table->setRows(array(array(new TableCell(12345))));
  551. $table->render();
  552. $expected =
  553. <<<'TABLE'
  554. +-------+
  555. | 12345 |
  556. +-------+
  557. TABLE;
  558. $this->assertEquals($expected, $this->getOutputContent($output));
  559. }
  560. public function testTableCellWithNumericFloatValue()
  561. {
  562. $table = new Table($output = $this->getOutputStream());
  563. $table->setRows(array(array(new TableCell(12345.01))));
  564. $table->render();
  565. $expected =
  566. <<<'TABLE'
  567. +----------+
  568. | 12345.01 |
  569. +----------+
  570. TABLE;
  571. $this->assertEquals($expected, $this->getOutputContent($output));
  572. }
  573. public function testStyle()
  574. {
  575. $style = new TableStyle();
  576. $style
  577. ->setHorizontalBorderChar('.')
  578. ->setVerticalBorderChar('.')
  579. ->setCrossingChar('.')
  580. ;
  581. Table::setStyleDefinition('dotfull', $style);
  582. $table = new Table($output = $this->getOutputStream());
  583. $table
  584. ->setHeaders(array('Foo'))
  585. ->setRows(array(array('Bar')))
  586. ->setStyle('dotfull');
  587. $table->render();
  588. $expected =
  589. <<<'TABLE'
  590. .......
  591. . Foo .
  592. .......
  593. . Bar .
  594. .......
  595. TABLE;
  596. $this->assertEquals($expected, $this->getOutputContent($output));
  597. }
  598. public function testRowSeparator()
  599. {
  600. $table = new Table($output = $this->getOutputStream());
  601. $table
  602. ->setHeaders(array('Foo'))
  603. ->setRows(array(
  604. array('Bar1'),
  605. new TableSeparator(),
  606. array('Bar2'),
  607. new TableSeparator(),
  608. array('Bar3'),
  609. ));
  610. $table->render();
  611. $expected =
  612. <<<'TABLE'
  613. +------+
  614. | Foo |
  615. +------+
  616. | Bar1 |
  617. +------+
  618. | Bar2 |
  619. +------+
  620. | Bar3 |
  621. +------+
  622. TABLE;
  623. $this->assertEquals($expected, $this->getOutputContent($output));
  624. $this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works');
  625. }
  626. public function testRenderMultiCalls()
  627. {
  628. $table = new Table($output = $this->getOutputStream());
  629. $table->setRows(array(
  630. array(new TableCell('foo', array('colspan' => 2))),
  631. ));
  632. $table->render();
  633. $table->render();
  634. $table->render();
  635. $expected =
  636. <<<TABLE
  637. +----+---+
  638. | foo |
  639. +----+---+
  640. +----+---+
  641. | foo |
  642. +----+---+
  643. +----+---+
  644. | foo |
  645. +----+---+
  646. TABLE;
  647. $this->assertEquals($expected, $this->getOutputContent($output));
  648. }
  649. public function testColumnStyle()
  650. {
  651. $table = new Table($output = $this->getOutputStream());
  652. $table
  653. ->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
  654. ->setRows(array(
  655. array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
  656. array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
  657. ));
  658. $style = new TableStyle();
  659. $style->setPadType(STR_PAD_LEFT);
  660. $table->setColumnStyle(3, $style);
  661. $table->render();
  662. $expected =
  663. <<<TABLE
  664. +---------------+----------------------+-----------------+--------+
  665. | ISBN | Title | Author | Price |
  666. +---------------+----------------------+-----------------+--------+
  667. | 99921-58-10-7 | Divine Comedy | Dante Alighieri | 9.95 |
  668. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
  669. +---------------+----------------------+-----------------+--------+
  670. TABLE;
  671. $this->assertEquals($expected, $this->getOutputContent($output));
  672. }
  673. /**
  674. * @expectedException \Symfony\Component\Console\Exception\InvalidArgumentException
  675. * @expectedExceptionMessage A cell must be a TableCell, a scalar or an object implementing __toString, array given.
  676. */
  677. public function testThrowsWhenTheCellInAnArray()
  678. {
  679. $table = new Table($output = $this->getOutputStream());
  680. $table
  681. ->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
  682. ->setRows(array(
  683. array('99921-58-10-7', array(), 'Dante Alighieri', '9.95'),
  684. ));
  685. $table->render();
  686. }
  687. public function testColumnWith()
  688. {
  689. $table = new Table($output = $this->getOutputStream());
  690. $table
  691. ->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
  692. ->setRows(array(
  693. array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
  694. array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
  695. ))
  696. ->setColumnWidth(0, 15)
  697. ->setColumnWidth(3, 10);
  698. $style = new TableStyle();
  699. $style->setPadType(STR_PAD_LEFT);
  700. $table->setColumnStyle(3, $style);
  701. $table->render();
  702. $expected =
  703. <<<TABLE
  704. +-----------------+----------------------+-----------------+------------+
  705. | ISBN | Title | Author | Price |
  706. +-----------------+----------------------+-----------------+------------+
  707. | 99921-58-10-7 | Divine Comedy | Dante Alighieri | 9.95 |
  708. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
  709. +-----------------+----------------------+-----------------+------------+
  710. TABLE;
  711. $this->assertEquals($expected, $this->getOutputContent($output));
  712. }
  713. public function testColumnWiths()
  714. {
  715. $table = new Table($output = $this->getOutputStream());
  716. $table
  717. ->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
  718. ->setRows(array(
  719. array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
  720. array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
  721. ))
  722. ->setColumnWidths(array(15, 0, -1, 10));
  723. $style = new TableStyle();
  724. $style->setPadType(STR_PAD_LEFT);
  725. $table->setColumnStyle(3, $style);
  726. $table->render();
  727. $expected =
  728. <<<TABLE
  729. +-----------------+----------------------+-----------------+------------+
  730. | ISBN | Title | Author | Price |
  731. +-----------------+----------------------+-----------------+------------+
  732. | 99921-58-10-7 | Divine Comedy | Dante Alighieri | 9.95 |
  733. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
  734. +-----------------+----------------------+-----------------+------------+
  735. TABLE;
  736. $this->assertEquals($expected, $this->getOutputContent($output));
  737. }
  738. /**
  739. * @expectedException \Symfony\Component\Console\Exception\InvalidArgumentException
  740. * @expectedExceptionMessage Style "absent" is not defined.
  741. */
  742. public function testIsNotDefinedStyleException()
  743. {
  744. $table = new Table($this->getOutputStream());
  745. $table->setStyle('absent');
  746. }
  747. /**
  748. * @expectedException \Symfony\Component\Console\Exception\InvalidArgumentException
  749. * @expectedExceptionMessage Style "absent" is not defined.
  750. */
  751. public function testGetStyleDefinition()
  752. {
  753. Table::getStyleDefinition('absent');
  754. }
  755. protected function getOutputStream($decorated = false)
  756. {
  757. return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, $decorated);
  758. }
  759. protected function getOutputContent(StreamOutput $output)
  760. {
  761. rewind($output->getStream());
  762. return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
  763. }
  764. }