PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/phpspec/phpspec/src/PhpSpec/Formatter/ProgressFormatter.php

https://gitlab.com/judielsm/Handora
PHP | 183 lines | 121 code | 29 blank | 33 comment | 16 complexity | 4083a90c70c27b93bde8910a69c072bc MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of PhpSpec, A php toolset to drive emergent
  4. * design by specification.
  5. *
  6. * (c) Marcello Duarte <marcello.duarte@gmail.com>
  7. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8. *
  9. * For the full copyright and license information, please view the LICENSE
  10. * file that was distributed with this source code.
  11. */
  12. namespace PhpSpec\Formatter;
  13. use PhpSpec\Console\IO;
  14. use PhpSpec\Event\SuiteEvent;
  15. use PhpSpec\Event\ExampleEvent;
  16. use PhpSpec\Listener\StatisticsCollector;
  17. class ProgressFormatter extends ConsoleFormatter
  18. {
  19. const FPS = 10;
  20. private $lastDraw;
  21. public function afterExample(ExampleEvent $event)
  22. {
  23. $this->printException($event);
  24. $now = microtime(true);
  25. if (!$this->lastDraw || ($now - $this->lastDraw) > 1/self::FPS) {
  26. $this->lastDraw = $now;
  27. $this->drawStats();
  28. }
  29. }
  30. public function afterSuite(SuiteEvent $event)
  31. {
  32. $this->drawStats();
  33. $io = $this->getIO();
  34. $stats = $this->getStatisticsCollector();
  35. $io->freezeTemp();
  36. $io->writeln();
  37. $io->writeln(sprintf("%d specs", $stats->getTotalSpecs()));
  38. $counts = array();
  39. foreach ($stats->getCountsHash() as $type => $count) {
  40. if ($count) {
  41. $counts[] = sprintf('<%s>%d %s</%s>', $type, $count, $type, $type);
  42. }
  43. }
  44. $count = $stats->getEventsCount();
  45. $plural = $count !== 1 ? 's' : '';
  46. $io->write(sprintf("%d example%s ", $count, $plural));
  47. if (count($counts)) {
  48. $io->write(sprintf("(%s)", implode(', ', $counts)));
  49. }
  50. $io->writeln(sprintf("\n%sms", round($event->getTime() * 1000)));
  51. $io->writeln();
  52. }
  53. /**
  54. * @param $total
  55. * @param $counts
  56. * @return array
  57. */
  58. private function getPercentages($total, $counts)
  59. {
  60. return array_map(
  61. function ($count) use ($total) {
  62. if (0 == $total) {
  63. return 0;
  64. }
  65. $percent = ($count == $total) ? 100 : $count / ($total / 100);
  66. return $percent == 0 || $percent > 1 ? floor($percent) : 1;
  67. },
  68. $counts
  69. );
  70. }
  71. /**
  72. * @param array $counts
  73. * @return array
  74. */
  75. private function getBarLengths($counts)
  76. {
  77. $stats = $this->getStatisticsCollector();
  78. $totalSpecsCount = $stats->getTotalSpecsCount();
  79. $specProgress = ($totalSpecsCount == 0) ? 1 : ($stats->getTotalSpecs() / $totalSpecsCount);
  80. $targetWidth = ceil($this->getIO()->getBlockWidth() * $specProgress);
  81. asort($counts);
  82. $barLengths = array_map(function ($count) use ($targetWidth, $counts) {
  83. return $count ? max(1, round($targetWidth * $count / array_sum($counts))) : 0;
  84. }, $counts);
  85. return $barLengths;
  86. }
  87. /**
  88. * @param array $barLengths
  89. * @param array $percents
  90. * @param boolean $isDecorated
  91. * @return array
  92. */
  93. private function formatProgressOutput($barLengths, $percents, $isDecorated)
  94. {
  95. $size = $this->getIO()->getBlockWidth();
  96. $progress = array();
  97. foreach ($barLengths as $status => $length) {
  98. $percent = $percents[$status];
  99. $text = $percent.'%';
  100. $length = ($size - $length) >= 0 ? $length : $size;
  101. $size = $size - $length;
  102. if ($isDecorated) {
  103. if ($length > strlen($text) + 2) {
  104. $text = str_pad($text, $length, ' ', STR_PAD_BOTH);
  105. } else {
  106. $text = str_pad('', $length, ' ');
  107. }
  108. $progress[$status] = sprintf("<$status-bg>%s</$status-bg>", $text);
  109. } else {
  110. $progress[$status] = str_pad(
  111. sprintf('%s: %s', $status, $text),
  112. 15,
  113. ' ',
  114. STR_PAD_BOTH
  115. );
  116. }
  117. }
  118. krsort($progress);
  119. return $progress;
  120. }
  121. /**
  122. * @param IO $io
  123. * @param array $progress
  124. * @param int $total
  125. */
  126. private function updateProgressBar(IO $io, array $progress, $total)
  127. {
  128. if ($io->isDecorated()) {
  129. $progressBar = implode('', $progress);
  130. $pad = $this->getIO()->getBlockWidth() - strlen(strip_tags($progressBar));
  131. $io->writeTemp($progressBar.str_repeat(' ', $pad + 1).$total);
  132. } else {
  133. $io->writeTemp('/'.implode('/', $progress).'/ '.$total.' examples');
  134. }
  135. }
  136. private function drawStats()
  137. {
  138. $io = $this->getIO();
  139. $stats = $this->getStatisticsCollector();
  140. $percents = $this->getPercentages($stats->getEventsCount(), $stats->getCountsHash());
  141. $barLengths = $this->getBarLengths($stats->getCountsHash());
  142. $progress = $this->formatProgressOutput($barLengths, $percents, $io->isDecorated());
  143. $this->updateProgressBar($io, $progress, $stats->getEventsCount());
  144. }
  145. /**
  146. * @return float
  147. */
  148. private function getSpecProgress()
  149. {
  150. $stats = $this->getStatisticsCollector();
  151. $specProgress = $stats->getTotalSpecsCount() ? ($stats->getTotalSpecs() + 1) / $stats->getTotalSpecsCount() : 0;
  152. return $specProgress;
  153. }
  154. }