From 30116859e6b847ed85bda6e18928e9209b084a0f Mon Sep 17 00:00:00 2001 From: Gilles Doge Date: Mon, 7 Jul 2014 17:02:57 +0200 Subject: [PATCH] [Console][ProgressBar] Allow to advance past max. --- .../Component/Console/Helper/ProgressBar.php | 33 ++++++++++++++----- .../Console/Tests/Helper/ProgressBarTest.php | 16 +++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/ProgressBar.php b/src/Symfony/Component/Console/Helper/ProgressBar.php index 09cb5690ea..da8e44757b 100644 --- a/src/Symfony/Component/Console/Helper/ProgressBar.php +++ b/src/Symfony/Component/Console/Helper/ProgressBar.php @@ -52,17 +52,14 @@ class ProgressBar * * @param OutputInterface $output An OutputInterface instance * @param int $max Maximum steps (0 if unknown) + * + * @throws \InvalidArgumentException */ public function __construct(OutputInterface $output, $max = 0) { - if (!is_integer($max) || $max < 0) { - throw new \InvalidArgumentException('Max steps should be a positive integer, 0 or null. Got "%s".', $max); - } - // Disabling output when it does not support ANSI codes as it would result in a broken display anyway. $this->output = $output->isDecorated() ? $output : new NullOutput(); - $this->max = (int) $max; - $this->stepWidth = $this->max > 0 ? Helper::strlen($this->max) : 4; + $this->setMaxSteps($max); if (!self::$formatters) { self::$formatters = self::initPlaceholderFormatters(); @@ -167,6 +164,25 @@ class ProgressBar return $this->startTime; } + /** + * Sets the progress bar maximal steps. + * + * @param int The progress bar max steps + * + * @throws \InvalidArgumentException + */ + public function setMaxSteps($max) + { + $max = (int) $max; + + if ($max < 0) { + throw new \InvalidArgumentException('Max steps should be a positive integer, 0 or null. Got "%s".', $max); + } + + $this->max = $max; + $this->stepWidth = $this->max > 0 ? Helper::strlen($this->max) : 4; + } + /** * Gets the progress bar maximal steps. * @@ -338,8 +354,7 @@ class ProgressBar public function start($max = 0) { if (0 !== $max) { - $this->max = $max; - $this->stepWidth = $this->max > 0 ? Helper::strlen($this->max) : 4; + $this->setMaxSteps($max); } if (!$this->max) { @@ -377,7 +392,7 @@ class ProgressBar } if ($this->max > 0 && $step > $this->max) { - throw new \LogicException('You can\'t advance the progress bar past the max value.'); + $this->max = $step; } $prevPeriod = intval($this->step / $this->redrawFreq); diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php index 53ab6105a7..5dc606c910 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php @@ -71,6 +71,22 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase ); } + public function testAdvanceOverMax() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 10); + $bar->setCurrent(9); + $bar->advance(); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + $this->generateOutput(' 9/10 [=========================>--] 90%'). + $this->generateOutput(' 10/10 [============================] 100%'). + $this->generateOutput(' 11/11 [============================] 100%'), + stream_get_contents($output->getStream()) + ); + } + public function testCustomizations() { $bar = new ProgressBar($output = $this->getOutputStream(), 10);