PageRenderTime 62ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/unit/cli/output/helpers/ProgressBarTest.php

https://github.com/mako-framework/framework
PHP | 369 lines | 244 code | 74 blank | 51 comment | 8 complexity | da3e737d9cd99d0f23b8c4ced2aca143 MD5 | raw file
  1. <?php
  2. /**
  3. * @copyright Frederic G. Østby
  4. * @license http://www.makoframework.com/license
  5. */
  6. namespace mako\tests\unit\cli\output\helpers;
  7. use mako\cli\exceptions\CliException;
  8. use mako\cli\output\helpers\ProgressBar;
  9. use mako\cli\output\Output;
  10. use mako\tests\TestCase;
  11. use Mockery;
  12. /**
  13. * @group unit
  14. */
  15. class ProgressBarTest extends TestCase
  16. {
  17. /**
  18. *
  19. */
  20. public function testProgressWithZeroItems(): void
  21. {
  22. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  23. $output = Mockery::mock(Output::class);
  24. $output->shouldReceive('write')->never();
  25. $progressBar = new ProgressBar($output, 0);
  26. $progressBar->draw();
  27. }
  28. /**
  29. *
  30. */
  31. public function testBasicProgress(): void
  32. {
  33. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  34. $output = Mockery::mock(Output::class);
  35. $output->shouldReceive('write')->once()->with("\r00/10 -------------------- 0% ");
  36. $output->shouldReceive('write')->once()->with("\r01/10 ==------------------ 10% ");
  37. $output->shouldReceive('write')->once()->with("\r02/10 ====---------------- 20% ");
  38. $output->shouldReceive('write')->once()->with("\r03/10 ======-------------- 30% ");
  39. $output->shouldReceive('write')->once()->with("\r04/10 ========------------ 40% ");
  40. $output->shouldReceive('write')->once()->with("\r05/10 ==========---------- 50% ");
  41. $output->shouldReceive('write')->once()->with("\r06/10 ============-------- 60% ");
  42. $output->shouldReceive('write')->once()->with("\r07/10 ==============------ 70% ");
  43. $output->shouldReceive('write')->once()->with("\r08/10 ================---- 80% ");
  44. $output->shouldReceive('write')->once()->with("\r09/10 ==================-- 90% ");
  45. $output->shouldReceive('write')->once()->with("\r10/10 ==================== 100% ");
  46. $output->shouldReceive('write')->once()->with(PHP_EOL);
  47. $progressBar = new class ($output, 10) extends ProgressBar
  48. {
  49. protected function shouldRedraw(): bool
  50. {
  51. return ($this->progress % 1) === 0;
  52. }
  53. };
  54. $progressBar->draw();
  55. for($i = 0; $i < 10; $i++)
  56. {
  57. $progressBar->advance();
  58. }
  59. }
  60. /**
  61. *
  62. */
  63. public function testProgressWithCustomWidth(): void
  64. {
  65. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  66. $output = Mockery::mock(Output::class);
  67. $output->shouldReceive('write')->once()->with("\r00/10 ---------------------------------------- 0% ");
  68. $output->shouldReceive('write')->once()->with("\r01/10 ====------------------------------------ 10% ");
  69. $output->shouldReceive('write')->once()->with("\r02/10 ========-------------------------------- 20% ");
  70. $output->shouldReceive('write')->once()->with("\r03/10 ============---------------------------- 30% ");
  71. $output->shouldReceive('write')->once()->with("\r04/10 ================------------------------ 40% ");
  72. $output->shouldReceive('write')->once()->with("\r05/10 ====================-------------------- 50% ");
  73. $output->shouldReceive('write')->once()->with("\r06/10 ========================---------------- 60% ");
  74. $output->shouldReceive('write')->once()->with("\r07/10 ============================------------ 70% ");
  75. $output->shouldReceive('write')->once()->with("\r08/10 ================================-------- 80% ");
  76. $output->shouldReceive('write')->once()->with("\r09/10 ====================================---- 90% ");
  77. $output->shouldReceive('write')->once()->with("\r10/10 ======================================== 100% ");
  78. $output->shouldReceive('write')->once()->with(PHP_EOL);
  79. $progressBar = new class ($output, 10) extends ProgressBar
  80. {
  81. protected function shouldRedraw(): bool
  82. {
  83. return ($this->progress % 1) === 0;
  84. }
  85. };
  86. $progressBar->setWidth(40);
  87. $progressBar->draw();
  88. for($i = 0; $i < 10; $i++)
  89. {
  90. $progressBar->advance();
  91. }
  92. }
  93. /**
  94. *
  95. */
  96. public function testProgressWithCustomTemplates(): void
  97. {
  98. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  99. $output = Mockery::mock(Output::class);
  100. $output->shouldReceive('write')->once()->with("\r00/10 ____________________ 0% ");
  101. $output->shouldReceive('write')->once()->with("\r01/10 ++__________________ 10% ");
  102. $output->shouldReceive('write')->once()->with("\r02/10 ++++________________ 20% ");
  103. $output->shouldReceive('write')->once()->with("\r03/10 ++++++______________ 30% ");
  104. $output->shouldReceive('write')->once()->with("\r04/10 ++++++++____________ 40% ");
  105. $output->shouldReceive('write')->once()->with("\r05/10 ++++++++++__________ 50% ");
  106. $output->shouldReceive('write')->once()->with("\r06/10 ++++++++++++________ 60% ");
  107. $output->shouldReceive('write')->once()->with("\r07/10 ++++++++++++++______ 70% ");
  108. $output->shouldReceive('write')->once()->with("\r08/10 ++++++++++++++++____ 80% ");
  109. $output->shouldReceive('write')->once()->with("\r09/10 ++++++++++++++++++__ 90% ");
  110. $output->shouldReceive('write')->once()->with("\r10/10 ++++++++++++++++++++ 100% ");
  111. $output->shouldReceive('write')->once()->with(PHP_EOL);
  112. $progressBar = new class ($output, 10) extends ProgressBar
  113. {
  114. protected function shouldRedraw(): bool
  115. {
  116. return ($this->progress % 1) === 0;
  117. }
  118. };
  119. $progressBar->setEmptyTemplate('_');
  120. $progressBar->setFilledTemplate('+');
  121. $progressBar->draw();
  122. for($i = 0; $i < 10; $i++)
  123. {
  124. $progressBar->advance();
  125. }
  126. }
  127. /**
  128. *
  129. */
  130. public function testProgressWithPrefix(): void
  131. {
  132. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  133. $output = Mockery::mock(Output::class);
  134. $output->shouldReceive('write')->once()->with("\rProcessing files: 00/10 -------------------- 0% ");
  135. $output->shouldReceive('write')->once()->with("\rProcessing files: 01/10 ==------------------ 10% ");
  136. $output->shouldReceive('write')->once()->with("\rProcessing files: 02/10 ====---------------- 20% ");
  137. $output->shouldReceive('write')->once()->with("\rProcessing files: 03/10 ======-------------- 30% ");
  138. $output->shouldReceive('write')->once()->with("\rProcessing files: 04/10 ========------------ 40% ");
  139. $output->shouldReceive('write')->once()->with("\rProcessing files: 05/10 ==========---------- 50% ");
  140. $output->shouldReceive('write')->once()->with("\rProcessing files: 06/10 ============-------- 60% ");
  141. $output->shouldReceive('write')->once()->with("\rProcessing files: 07/10 ==============------ 70% ");
  142. $output->shouldReceive('write')->once()->with("\rProcessing files: 08/10 ================---- 80% ");
  143. $output->shouldReceive('write')->once()->with("\rProcessing files: 09/10 ==================-- 90% ");
  144. $output->shouldReceive('write')->once()->with("\rProcessing files: 10/10 ==================== 100% ");
  145. $output->shouldReceive('write')->once()->with(PHP_EOL);
  146. $progressBar = new class ($output, 10) extends ProgressBar
  147. {
  148. protected function shouldRedraw(): bool
  149. {
  150. return ($this->progress % 1) === 0;
  151. }
  152. };
  153. $progressBar->setPrefix('Processing files:');
  154. $progressBar->draw();
  155. for($i = 0; $i < 10; $i++)
  156. {
  157. $progressBar->advance();
  158. }
  159. }
  160. /**
  161. *
  162. */
  163. public function testProgressWith100ItemsAndDefaultMinTimeBetweenRedraw(): void
  164. {
  165. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  166. $output = Mockery::mock(Output::class);
  167. $output->shouldReceive('write')->times(102);
  168. $progressBar = new class ($output, 100) extends ProgressBar
  169. {
  170. protected function getMicrotime(): float
  171. {
  172. static $time = 0;
  173. return $time += 1.0; // More than the default minTimeBetweenRedraw value of 0.1 secuonds
  174. }
  175. };
  176. $progressBar->draw();
  177. for($i = 0; $i < 100; $i++)
  178. {
  179. $progressBar->advance();
  180. }
  181. }
  182. /**
  183. *
  184. */
  185. public function testProgressTimeBetweenRedraw(): void
  186. {
  187. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  188. $output = Mockery::mock(Output::class);
  189. $output->shouldReceive('write')->times(3);
  190. $progressBar = new ProgressBar($output, 100, 0.5);
  191. $progressBar->draw();
  192. $progressBar->advance(); // Should redraw
  193. $progressBar->advance(); // Should not redraw
  194. usleep(500000);
  195. $progressBar->advance(); // Should redraw
  196. }
  197. /**
  198. *
  199. */
  200. public function testProgressWith100ItemsAndCustomMinTimeBetweenRedraw(): void
  201. {
  202. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  203. $output = Mockery::mock(Output::class);
  204. $output->shouldReceive('write');
  205. $progressBar = new class ($output, 100, 1) extends ProgressBar
  206. {
  207. public $drawn = 0;
  208. protected function getMicrotime(): float
  209. {
  210. static $time = 0;
  211. return $time += 0.5; // Half of the default minTimeBetweenRedraw value
  212. }
  213. public function draw(): void
  214. {
  215. $this->drawn++;
  216. parent::draw();
  217. }
  218. };
  219. $progressBar->draw();
  220. for($i = 0; $i < 100; $i++)
  221. {
  222. $progressBar->advance();
  223. }
  224. $this->assertThat($progressBar->drawn, $this->logicalAnd($this->greaterThan(50), $this->lessThan(55)));
  225. }
  226. /**
  227. *
  228. */
  229. public function testRemoveIncomplete(): void
  230. {
  231. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  232. $output = Mockery::mock(Output::class);
  233. $output->shouldReceive('write')->once()->with("\r00/10 -------------------- 0% ");
  234. $output->shouldReceive('clearLines')->once()->with(1);
  235. $progressBar = new ProgressBar($output, 10);
  236. $progressBar->draw();
  237. $progressBar->remove();
  238. }
  239. /**
  240. *
  241. */
  242. public function testRemoveComplete(): void
  243. {
  244. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  245. $output = Mockery::mock(Output::class);
  246. $output->shouldReceive('write')->once()->with("\r00/10 -------------------- 0% ");
  247. $output->shouldReceive('write')->once()->with("\r01/10 ==------------------ 10% ");
  248. $output->shouldReceive('write')->once()->with("\r02/10 ====---------------- 20% ");
  249. $output->shouldReceive('write')->once()->with("\r03/10 ======-------------- 30% ");
  250. $output->shouldReceive('write')->once()->with("\r04/10 ========------------ 40% ");
  251. $output->shouldReceive('write')->once()->with("\r05/10 ==========---------- 50% ");
  252. $output->shouldReceive('write')->once()->with("\r06/10 ============-------- 60% ");
  253. $output->shouldReceive('write')->once()->with("\r07/10 ==============------ 70% ");
  254. $output->shouldReceive('write')->once()->with("\r08/10 ================---- 80% ");
  255. $output->shouldReceive('write')->once()->with("\r09/10 ==================-- 90% ");
  256. $output->shouldReceive('write')->once()->with("\r10/10 ==================== 100% ");
  257. $output->shouldReceive('write')->once()->with(PHP_EOL);
  258. $output->shouldReceive('clearLines')->once()->with(2);
  259. $progressBar = new class ($output, 10) extends ProgressBar
  260. {
  261. protected function shouldRedraw(): bool
  262. {
  263. return ($this->progress % 1) === 0;
  264. }
  265. };
  266. $progressBar->draw();
  267. for($i = 0; $i < 10; $i++)
  268. {
  269. $progressBar->advance();
  270. }
  271. $progressBar->remove();
  272. }
  273. /**
  274. *
  275. */
  276. public function testProgressPast100Percent(): void
  277. {
  278. $this->expectException(CliException::class);
  279. /** @var \mako\cli\output\Output|\Mockery\MockInterface $output */
  280. $output = Mockery::mock(Output::class);
  281. $output->shouldReceive('write')->times(12);
  282. $progressBar = new class ($output, 10) extends ProgressBar
  283. {
  284. protected function shouldRedraw(): bool
  285. {
  286. return ($this->progress % 1) === 0;
  287. }
  288. };
  289. $progressBar->draw();
  290. for($i = 0; $i < 11; $i++)
  291. {
  292. $progressBar->advance();
  293. }
  294. }
  295. }