ProgressBarTest.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  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 Symfony\Component\Console\Helper\ProgressBar;
  12. use Symfony\Component\Console\Helper\Helper;
  13. use Symfony\Component\Console\Output\StreamOutput;
  14. /**
  15. * @group time-sensitive
  16. */
  17. class ProgressBarTest extends \PHPUnit_Framework_TestCase
  18. {
  19. public function testMultipleStart()
  20. {
  21. $bar = new ProgressBar($output = $this->getOutputStream());
  22. $bar->start();
  23. $bar->advance();
  24. $bar->start();
  25. rewind($output->getStream());
  26. $this->assertEquals(
  27. ' 0 [>---------------------------]'.
  28. $this->generateOutput(' 1 [->--------------------------]').
  29. $this->generateOutput(' 0 [>---------------------------]'),
  30. stream_get_contents($output->getStream())
  31. );
  32. }
  33. public function testAdvance()
  34. {
  35. $bar = new ProgressBar($output = $this->getOutputStream());
  36. $bar->start();
  37. $bar->advance();
  38. rewind($output->getStream());
  39. $this->assertEquals(
  40. ' 0 [>---------------------------]'.
  41. $this->generateOutput(' 1 [->--------------------------]'),
  42. stream_get_contents($output->getStream())
  43. );
  44. }
  45. public function testAdvanceWithStep()
  46. {
  47. $bar = new ProgressBar($output = $this->getOutputStream());
  48. $bar->start();
  49. $bar->advance(5);
  50. rewind($output->getStream());
  51. $this->assertEquals(
  52. ' 0 [>---------------------------]'.
  53. $this->generateOutput(' 5 [----->----------------------]'),
  54. stream_get_contents($output->getStream())
  55. );
  56. }
  57. public function testAdvanceMultipleTimes()
  58. {
  59. $bar = new ProgressBar($output = $this->getOutputStream());
  60. $bar->start();
  61. $bar->advance(3);
  62. $bar->advance(2);
  63. rewind($output->getStream());
  64. $this->assertEquals(
  65. ' 0 [>---------------------------]'.
  66. $this->generateOutput(' 3 [--->------------------------]').
  67. $this->generateOutput(' 5 [----->----------------------]'),
  68. stream_get_contents($output->getStream())
  69. );
  70. }
  71. public function testAdvanceOverMax()
  72. {
  73. $bar = new ProgressBar($output = $this->getOutputStream(), 10);
  74. $bar->setProgress(9);
  75. $bar->advance();
  76. $bar->advance();
  77. rewind($output->getStream());
  78. $this->assertEquals(
  79. ' 9/10 [=========================>--] 90%'.
  80. $this->generateOutput(' 10/10 [============================] 100%').
  81. $this->generateOutput(' 11/11 [============================] 100%'),
  82. stream_get_contents($output->getStream())
  83. );
  84. }
  85. public function testRegress()
  86. {
  87. $bar = new ProgressBar($output = $this->getOutputStream());
  88. $bar->start();
  89. $bar->advance();
  90. $bar->advance();
  91. $bar->advance(-1);
  92. rewind($output->getStream());
  93. $this->assertEquals(
  94. ' 0 [>---------------------------]'.
  95. $this->generateOutput(' 1 [->--------------------------]').
  96. $this->generateOutput(' 2 [-->-------------------------]').
  97. $this->generateOutput(' 1 [->--------------------------]'),
  98. stream_get_contents($output->getStream())
  99. );
  100. }
  101. public function testRegressWithStep()
  102. {
  103. $bar = new ProgressBar($output = $this->getOutputStream());
  104. $bar->start();
  105. $bar->advance(4);
  106. $bar->advance(4);
  107. $bar->advance(-2);
  108. rewind($output->getStream());
  109. $this->assertEquals(
  110. ' 0 [>---------------------------]'.
  111. $this->generateOutput(' 4 [---->-----------------------]').
  112. $this->generateOutput(' 8 [-------->-------------------]').
  113. $this->generateOutput(' 6 [------>---------------------]'),
  114. stream_get_contents($output->getStream())
  115. );
  116. }
  117. public function testRegressMultipleTimes()
  118. {
  119. $bar = new ProgressBar($output = $this->getOutputStream());
  120. $bar->start();
  121. $bar->advance(3);
  122. $bar->advance(3);
  123. $bar->advance(-1);
  124. $bar->advance(-2);
  125. rewind($output->getStream());
  126. $this->assertEquals(
  127. ' 0 [>---------------------------]'.
  128. $this->generateOutput(' 3 [--->------------------------]').
  129. $this->generateOutput(' 6 [------>---------------------]').
  130. $this->generateOutput(' 5 [----->----------------------]').
  131. $this->generateOutput(' 3 [--->------------------------]'),
  132. stream_get_contents($output->getStream())
  133. );
  134. }
  135. public function testRegressBelowMin()
  136. {
  137. $bar = new ProgressBar($output = $this->getOutputStream(), 10);
  138. $bar->setProgress(1);
  139. $bar->advance(-1);
  140. $bar->advance(-1);
  141. rewind($output->getStream());
  142. $this->assertEquals(
  143. ' 1/10 [==>-------------------------] 10%'.
  144. $this->generateOutput(' 0/10 [>---------------------------] 0%'),
  145. stream_get_contents($output->getStream())
  146. );
  147. }
  148. public function testFormat()
  149. {
  150. $expected =
  151. ' 0/10 [>---------------------------] 0%'.
  152. $this->generateOutput(' 10/10 [============================] 100%').
  153. $this->generateOutput(' 10/10 [============================] 100%')
  154. ;
  155. // max in construct, no format
  156. $bar = new ProgressBar($output = $this->getOutputStream(), 10);
  157. $bar->start();
  158. $bar->advance(10);
  159. $bar->finish();
  160. rewind($output->getStream());
  161. $this->assertEquals($expected, stream_get_contents($output->getStream()));
  162. // max in start, no format
  163. $bar = new ProgressBar($output = $this->getOutputStream());
  164. $bar->start(10);
  165. $bar->advance(10);
  166. $bar->finish();
  167. rewind($output->getStream());
  168. $this->assertEquals($expected, stream_get_contents($output->getStream()));
  169. // max in construct, explicit format before
  170. $bar = new ProgressBar($output = $this->getOutputStream(), 10);
  171. $bar->setFormat('normal');
  172. $bar->start();
  173. $bar->advance(10);
  174. $bar->finish();
  175. rewind($output->getStream());
  176. $this->assertEquals($expected, stream_get_contents($output->getStream()));
  177. // max in start, explicit format before
  178. $bar = new ProgressBar($output = $this->getOutputStream());
  179. $bar->setFormat('normal');
  180. $bar->start(10);
  181. $bar->advance(10);
  182. $bar->finish();
  183. rewind($output->getStream());
  184. $this->assertEquals($expected, stream_get_contents($output->getStream()));
  185. }
  186. public function testCustomizations()
  187. {
  188. $bar = new ProgressBar($output = $this->getOutputStream(), 10);
  189. $bar->setBarWidth(10);
  190. $bar->setBarCharacter('_');
  191. $bar->setEmptyBarCharacter(' ');
  192. $bar->setProgressCharacter('/');
  193. $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
  194. $bar->start();
  195. $bar->advance();
  196. rewind($output->getStream());
  197. $this->assertEquals(
  198. ' 0/10 [/ ] 0%'.
  199. $this->generateOutput(' 1/10 [_/ ] 10%'),
  200. stream_get_contents($output->getStream())
  201. );
  202. }
  203. public function testDisplayWithoutStart()
  204. {
  205. $bar = new ProgressBar($output = $this->getOutputStream(), 50);
  206. $bar->display();
  207. rewind($output->getStream());
  208. $this->assertEquals(
  209. ' 0/50 [>---------------------------] 0%',
  210. stream_get_contents($output->getStream())
  211. );
  212. }
  213. public function testDisplayWithQuietVerbosity()
  214. {
  215. $bar = new ProgressBar($output = $this->getOutputStream(true, StreamOutput::VERBOSITY_QUIET), 50);
  216. $bar->display();
  217. rewind($output->getStream());
  218. $this->assertEquals(
  219. '',
  220. stream_get_contents($output->getStream())
  221. );
  222. }
  223. public function testFinishWithoutStart()
  224. {
  225. $bar = new ProgressBar($output = $this->getOutputStream(), 50);
  226. $bar->finish();
  227. rewind($output->getStream());
  228. $this->assertEquals(
  229. ' 50/50 [============================] 100%',
  230. stream_get_contents($output->getStream())
  231. );
  232. }
  233. public function testPercent()
  234. {
  235. $bar = new ProgressBar($output = $this->getOutputStream(), 50);
  236. $bar->start();
  237. $bar->display();
  238. $bar->advance();
  239. $bar->advance();
  240. rewind($output->getStream());
  241. $this->assertEquals(
  242. ' 0/50 [>---------------------------] 0%'.
  243. $this->generateOutput(' 0/50 [>---------------------------] 0%').
  244. $this->generateOutput(' 1/50 [>---------------------------] 2%').
  245. $this->generateOutput(' 2/50 [=>--------------------------] 4%'),
  246. stream_get_contents($output->getStream())
  247. );
  248. }
  249. public function testOverwriteWithShorterLine()
  250. {
  251. $bar = new ProgressBar($output = $this->getOutputStream(), 50);
  252. $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
  253. $bar->start();
  254. $bar->display();
  255. $bar->advance();
  256. // set shorter format
  257. $bar->setFormat(' %current%/%max% [%bar%]');
  258. $bar->advance();
  259. rewind($output->getStream());
  260. $this->assertEquals(
  261. ' 0/50 [>---------------------------] 0%'.
  262. $this->generateOutput(' 0/50 [>---------------------------] 0%').
  263. $this->generateOutput(' 1/50 [>---------------------------] 2%').
  264. $this->generateOutput(' 2/50 [=>--------------------------]'),
  265. stream_get_contents($output->getStream())
  266. );
  267. }
  268. public function testStartWithMax()
  269. {
  270. $bar = new ProgressBar($output = $this->getOutputStream());
  271. $bar->setFormat('%current%/%max% [%bar%]');
  272. $bar->start(50);
  273. $bar->advance();
  274. rewind($output->getStream());
  275. $this->assertEquals(
  276. ' 0/50 [>---------------------------]'.
  277. $this->generateOutput(' 1/50 [>---------------------------]'),
  278. stream_get_contents($output->getStream())
  279. );
  280. }
  281. public function testSetCurrentProgress()
  282. {
  283. $bar = new ProgressBar($output = $this->getOutputStream(), 50);
  284. $bar->start();
  285. $bar->display();
  286. $bar->advance();
  287. $bar->setProgress(15);
  288. $bar->setProgress(25);
  289. rewind($output->getStream());
  290. $this->assertEquals(
  291. ' 0/50 [>---------------------------] 0%'.
  292. $this->generateOutput(' 0/50 [>---------------------------] 0%').
  293. $this->generateOutput(' 1/50 [>---------------------------] 2%').
  294. $this->generateOutput(' 15/50 [========>-------------------] 30%').
  295. $this->generateOutput(' 25/50 [==============>-------------] 50%'),
  296. stream_get_contents($output->getStream())
  297. );
  298. }
  299. public function testSetCurrentBeforeStarting()
  300. {
  301. $bar = new ProgressBar($this->getOutputStream());
  302. $bar->setProgress(15);
  303. $this->assertNotNull($bar->getStartTime());
  304. }
  305. public function testRedrawFrequency()
  306. {
  307. $bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream(), 6))->getMock();
  308. $bar->expects($this->exactly(4))->method('display');
  309. $bar->setRedrawFrequency(2);
  310. $bar->start();
  311. $bar->setProgress(1);
  312. $bar->advance(2);
  313. $bar->advance(2);
  314. $bar->advance(1);
  315. }
  316. public function testRedrawFrequencyIsAtLeastOneIfZeroGiven()
  317. {
  318. $bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream()))->getMock();
  319. $bar->expects($this->exactly(2))->method('display');
  320. $bar->setRedrawFrequency(0);
  321. $bar->start();
  322. $bar->advance();
  323. }
  324. public function testRedrawFrequencyIsAtLeastOneIfSmallerOneGiven()
  325. {
  326. $bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream()))->getMock();
  327. $bar->expects($this->exactly(2))->method('display');
  328. $bar->setRedrawFrequency(0.9);
  329. $bar->start();
  330. $bar->advance();
  331. }
  332. public function testMultiByteSupport()
  333. {
  334. $bar = new ProgressBar($output = $this->getOutputStream());
  335. $bar->start();
  336. $bar->setBarCharacter('■');
  337. $bar->advance(3);
  338. rewind($output->getStream());
  339. $this->assertEquals(
  340. ' 0 [>---------------------------]'.
  341. $this->generateOutput(' 3 [■■■>------------------------]'),
  342. stream_get_contents($output->getStream())
  343. );
  344. }
  345. public function testClear()
  346. {
  347. $bar = new ProgressBar($output = $this->getOutputStream(), 50);
  348. $bar->start();
  349. $bar->setProgress(25);
  350. $bar->clear();
  351. rewind($output->getStream());
  352. $this->assertEquals(
  353. ' 0/50 [>---------------------------] 0%'.
  354. $this->generateOutput(' 25/50 [==============>-------------] 50%').
  355. $this->generateOutput(''),
  356. stream_get_contents($output->getStream())
  357. );
  358. }
  359. public function testPercentNotHundredBeforeComplete()
  360. {
  361. $bar = new ProgressBar($output = $this->getOutputStream(), 200);
  362. $bar->start();
  363. $bar->display();
  364. $bar->advance(199);
  365. $bar->advance();
  366. rewind($output->getStream());
  367. $this->assertEquals(
  368. ' 0/200 [>---------------------------] 0%'.
  369. $this->generateOutput(' 0/200 [>---------------------------] 0%').
  370. $this->generateOutput(' 199/200 [===========================>] 99%').
  371. $this->generateOutput(' 200/200 [============================] 100%'),
  372. stream_get_contents($output->getStream())
  373. );
  374. }
  375. public function testNonDecoratedOutput()
  376. {
  377. $bar = new ProgressBar($output = $this->getOutputStream(false), 200);
  378. $bar->start();
  379. for ($i = 0; $i < 200; ++$i) {
  380. $bar->advance();
  381. }
  382. $bar->finish();
  383. rewind($output->getStream());
  384. $this->assertEquals(
  385. ' 0/200 [>---------------------------] 0%'.PHP_EOL.
  386. ' 20/200 [==>-------------------------] 10%'.PHP_EOL.
  387. ' 40/200 [=====>----------------------] 20%'.PHP_EOL.
  388. ' 60/200 [========>-------------------] 30%'.PHP_EOL.
  389. ' 80/200 [===========>----------------] 40%'.PHP_EOL.
  390. ' 100/200 [==============>-------------] 50%'.PHP_EOL.
  391. ' 120/200 [================>-----------] 60%'.PHP_EOL.
  392. ' 140/200 [===================>--------] 70%'.PHP_EOL.
  393. ' 160/200 [======================>-----] 80%'.PHP_EOL.
  394. ' 180/200 [=========================>--] 90%'.PHP_EOL.
  395. ' 200/200 [============================] 100%',
  396. stream_get_contents($output->getStream())
  397. );
  398. }
  399. public function testNonDecoratedOutputWithClear()
  400. {
  401. $bar = new ProgressBar($output = $this->getOutputStream(false), 50);
  402. $bar->start();
  403. $bar->setProgress(25);
  404. $bar->clear();
  405. $bar->setProgress(50);
  406. $bar->finish();
  407. rewind($output->getStream());
  408. $this->assertEquals(
  409. ' 0/50 [>---------------------------] 0%'.PHP_EOL.
  410. ' 25/50 [==============>-------------] 50%'.PHP_EOL.
  411. ' 50/50 [============================] 100%',
  412. stream_get_contents($output->getStream())
  413. );
  414. }
  415. public function testNonDecoratedOutputWithoutMax()
  416. {
  417. $bar = new ProgressBar($output = $this->getOutputStream(false));
  418. $bar->start();
  419. $bar->advance();
  420. rewind($output->getStream());
  421. $this->assertEquals(
  422. ' 0 [>---------------------------]'.PHP_EOL.
  423. ' 1 [->--------------------------]',
  424. stream_get_contents($output->getStream())
  425. );
  426. }
  427. public function testParallelBars()
  428. {
  429. $output = $this->getOutputStream();
  430. $bar1 = new ProgressBar($output, 2);
  431. $bar2 = new ProgressBar($output, 3);
  432. $bar2->setProgressCharacter('#');
  433. $bar3 = new ProgressBar($output);
  434. $bar1->start();
  435. $output->write("\n");
  436. $bar2->start();
  437. $output->write("\n");
  438. $bar3->start();
  439. for ($i = 1; $i <= 3; ++$i) {
  440. // up two lines
  441. $output->write("\033[2A");
  442. if ($i <= 2) {
  443. $bar1->advance();
  444. }
  445. $output->write("\n");
  446. $bar2->advance();
  447. $output->write("\n");
  448. $bar3->advance();
  449. }
  450. $output->write("\033[2A");
  451. $output->write("\n");
  452. $output->write("\n");
  453. $bar3->finish();
  454. rewind($output->getStream());
  455. $this->assertEquals(
  456. ' 0/2 [>---------------------------] 0%'."\n".
  457. ' 0/3 [#---------------------------] 0%'."\n".
  458. rtrim(' 0 [>---------------------------]').
  459. "\033[2A".
  460. $this->generateOutput(' 1/2 [==============>-------------] 50%')."\n".
  461. $this->generateOutput(' 1/3 [=========#------------------] 33%')."\n".
  462. rtrim($this->generateOutput(' 1 [->--------------------------]')).
  463. "\033[2A".
  464. $this->generateOutput(' 2/2 [============================] 100%')."\n".
  465. $this->generateOutput(' 2/3 [==================#---------] 66%')."\n".
  466. rtrim($this->generateOutput(' 2 [-->-------------------------]')).
  467. "\033[2A".
  468. "\n".
  469. $this->generateOutput(' 3/3 [============================] 100%')."\n".
  470. rtrim($this->generateOutput(' 3 [--->------------------------]')).
  471. "\033[2A".
  472. "\n".
  473. "\n".
  474. rtrim($this->generateOutput(' 3 [============================]')),
  475. stream_get_contents($output->getStream())
  476. );
  477. }
  478. public function testWithoutMax()
  479. {
  480. $output = $this->getOutputStream();
  481. $bar = new ProgressBar($output);
  482. $bar->start();
  483. $bar->advance();
  484. $bar->advance();
  485. $bar->advance();
  486. $bar->finish();
  487. rewind($output->getStream());
  488. $this->assertEquals(
  489. rtrim(' 0 [>---------------------------]').
  490. rtrim($this->generateOutput(' 1 [->--------------------------]')).
  491. rtrim($this->generateOutput(' 2 [-->-------------------------]')).
  492. rtrim($this->generateOutput(' 3 [--->------------------------]')).
  493. rtrim($this->generateOutput(' 3 [============================]')),
  494. stream_get_contents($output->getStream())
  495. );
  496. }
  497. public function testWithSmallScreen()
  498. {
  499. $output = $this->getOutputStream();
  500. $bar = new ProgressBar($output);
  501. putenv('COLUMNS=12');
  502. $bar->start();
  503. $bar->advance();
  504. putenv('COLUMNS=120');
  505. rewind($output->getStream());
  506. $this->assertEquals(
  507. ' 0 [>---]'.
  508. $this->generateOutput(' 1 [->--]'),
  509. stream_get_contents($output->getStream())
  510. );
  511. }
  512. public function testAddingPlaceholderFormatter()
  513. {
  514. ProgressBar::setPlaceholderFormatterDefinition('remaining_steps', function (ProgressBar $bar) {
  515. return $bar->getMaxSteps() - $bar->getProgress();
  516. });
  517. $bar = new ProgressBar($output = $this->getOutputStream(), 3);
  518. $bar->setFormat(' %remaining_steps% [%bar%]');
  519. $bar->start();
  520. $bar->advance();
  521. $bar->finish();
  522. rewind($output->getStream());
  523. $this->assertEquals(
  524. ' 3 [>---------------------------]'.
  525. $this->generateOutput(' 2 [=========>------------------]').
  526. $this->generateOutput(' 0 [============================]'),
  527. stream_get_contents($output->getStream())
  528. );
  529. }
  530. public function testMultilineFormat()
  531. {
  532. $bar = new ProgressBar($output = $this->getOutputStream(), 3);
  533. $bar->setFormat("%bar%\nfoobar");
  534. $bar->start();
  535. $bar->advance();
  536. $bar->clear();
  537. $bar->finish();
  538. rewind($output->getStream());
  539. $this->assertEquals(
  540. ">---------------------------\nfoobar".
  541. $this->generateOutput("=========>------------------\nfoobar").
  542. "\x0D\x1B[2K\x1B[1A\x1B[2K".
  543. $this->generateOutput("============================\nfoobar"),
  544. stream_get_contents($output->getStream())
  545. );
  546. }
  547. public function testAnsiColorsAndEmojis()
  548. {
  549. putenv('COLUMNS=156');
  550. $bar = new ProgressBar($output = $this->getOutputStream(), 15);
  551. ProgressBar::setPlaceholderFormatterDefinition('memory', function (ProgressBar $bar) {
  552. static $i = 0;
  553. $mem = 100000 * $i;
  554. $colors = $i++ ? '41;37' : '44;37';
  555. return "\033[".$colors.'m '.Helper::formatMemory($mem)." \033[0m";
  556. });
  557. $bar->setFormat(" \033[44;37m %title:-37s% \033[0m\n %current%/%max% %bar% %percent:3s%%\n 🏁 %remaining:-10s% %memory:37s%");
  558. $bar->setBarCharacter($done = "\033[32m●\033[0m");
  559. $bar->setEmptyBarCharacter($empty = "\033[31m●\033[0m");
  560. $bar->setProgressCharacter($progress = "\033[32m➤ \033[0m");
  561. $bar->setMessage('Starting the demo... fingers crossed', 'title');
  562. $bar->start();
  563. rewind($output->getStream());
  564. $this->assertEquals(
  565. " \033[44;37m Starting the demo... fingers crossed \033[0m\n".
  566. ' 0/15 '.$progress.str_repeat($empty, 26)." 0%\n".
  567. " \xf0\x9f\x8f\x81 < 1 sec \033[44;37m 0 B \033[0m",
  568. stream_get_contents($output->getStream())
  569. );
  570. ftruncate($output->getStream(), 0);
  571. rewind($output->getStream());
  572. $bar->setMessage('Looks good to me...', 'title');
  573. $bar->advance(4);
  574. rewind($output->getStream());
  575. $this->assertEquals(
  576. $this->generateOutput(
  577. " \033[44;37m Looks good to me... \033[0m\n".
  578. ' 4/15 '.str_repeat($done, 7).$progress.str_repeat($empty, 19)." 26%\n".
  579. " \xf0\x9f\x8f\x81 < 1 sec \033[41;37m 97 KiB \033[0m"
  580. ),
  581. stream_get_contents($output->getStream())
  582. );
  583. ftruncate($output->getStream(), 0);
  584. rewind($output->getStream());
  585. $bar->setMessage('Thanks, bye', 'title');
  586. $bar->finish();
  587. rewind($output->getStream());
  588. $this->assertEquals(
  589. $this->generateOutput(
  590. " \033[44;37m Thanks, bye \033[0m\n".
  591. ' 15/15 '.str_repeat($done, 28)." 100%\n".
  592. " \xf0\x9f\x8f\x81 < 1 sec \033[41;37m 195 KiB \033[0m"
  593. ),
  594. stream_get_contents($output->getStream())
  595. );
  596. putenv('COLUMNS=120');
  597. }
  598. public function testSetFormat()
  599. {
  600. $bar = new ProgressBar($output = $this->getOutputStream());
  601. $bar->setFormat('normal');
  602. $bar->start();
  603. rewind($output->getStream());
  604. $this->assertEquals(
  605. ' 0 [>---------------------------]',
  606. stream_get_contents($output->getStream())
  607. );
  608. $bar = new ProgressBar($output = $this->getOutputStream(), 10);
  609. $bar->setFormat('normal');
  610. $bar->start();
  611. rewind($output->getStream());
  612. $this->assertEquals(
  613. ' 0/10 [>---------------------------] 0%',
  614. stream_get_contents($output->getStream())
  615. );
  616. }
  617. /**
  618. * @dataProvider provideFormat
  619. */
  620. public function testFormatsWithoutMax($format)
  621. {
  622. $bar = new ProgressBar($output = $this->getOutputStream());
  623. $bar->setFormat($format);
  624. $bar->start();
  625. rewind($output->getStream());
  626. $this->assertNotEmpty(stream_get_contents($output->getStream()));
  627. }
  628. /**
  629. * Provides each defined format.
  630. *
  631. * @return array
  632. */
  633. public function provideFormat()
  634. {
  635. return array(
  636. array('normal'),
  637. array('verbose'),
  638. array('very_verbose'),
  639. array('debug'),
  640. );
  641. }
  642. protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
  643. {
  644. return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);
  645. }
  646. protected function generateOutput($expected)
  647. {
  648. $count = substr_count($expected, "\n");
  649. return "\x0D\x1B[2K".($count ? str_repeat("\x1B[1A\x1B[2K", $count) : '').$expected;
  650. }
  651. }