ProgressBarTest.php 25 KB

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