bug #16196 [Console] Fix progress bar formatting when max is set on start() and some other edge cases (vsychov, fabpot)

This PR was merged into the 2.7 branch.

Discussion
----------

[Console] Fix progress bar formatting when max is set on start() and some other edge cases

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Besides what #16149 fixed, it also fixes the case where `setFormat()` is called before `start()`.

From #16149

When I set max count, by call "ProgressBar::start()", I got invalid progress bar format.

Example code:
```php
$bar = new ProgressBar($output, 100);
$bar->start();
$bar->advance(100);
$bar->finish();
```
Output:
 100/100 [============================] 100%

Example code:
```php
$bar = new ProgressBar($output);
$bar->start(100);
$bar->advance(100);
$bar->finish();
```
Output:
 100 [============================]

Commits
-------

e651da4 [Console] fixed progress bar format on edge cases
3cbfa63 fix bug with set max count, by start method in progress bar
This commit is contained in:
Fabien Potencier 2015-10-11 11:14:05 +02:00
commit cd97d41881
2 changed files with 78 additions and 13 deletions

View File

@ -27,7 +27,8 @@ class ProgressBar
private $barChar;
private $emptyBarChar = '-';
private $progressChar = '>';
private $format = null;
private $format;
private $internalFormat;
private $redrawFreq = 1;
/**
@ -72,8 +73,6 @@ class ProgressBar
}
}
$this->setFormat($this->determineBestFormat());
$this->startTime = time();
}
@ -310,16 +309,8 @@ class ProgressBar
*/
public function setFormat($format)
{
// try to use the _nomax variant if available
if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
$this->format = self::getFormatDefinition($format.'_nomax');
} elseif (null !== self::getFormatDefinition($format)) {
$this->format = self::getFormatDefinition($format);
} else {
$this->format = $format;
}
$this->formatLineCount = substr_count($this->format, "\n");
$this->format = null;
$this->internalFormat = $format;
}
/**
@ -441,6 +432,10 @@ class ProgressBar
return;
}
if (null === $this->format) {
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
}
// these 3 variables can be removed in favor of using $this in the closure when support for PHP 5.3 will be dropped.
$self = $this;
$output = $this->output;
@ -475,9 +470,32 @@ class ProgressBar
return;
}
if (null === $this->format) {
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
}
$this->overwrite(str_repeat("\n", $this->formatLineCount));
}
/**
* Sets the progress bar format.
*
* @param string $format The format
*/
private function setRealFormat($format)
{
// try to use the _nomax variant if available
if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
$this->format = self::getFormatDefinition($format.'_nomax');
} elseif (null !== self::getFormatDefinition($format)) {
$this->format = self::getFormatDefinition($format);
} else {
$this->format = $format;
}
$this->formatLineCount = substr_count($this->format, "\n");
}
/**
* Sets the progress bar maximal steps.
*

View File

@ -106,6 +106,53 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
);
}
public function testFormat()
{
$expected =
$this->generateOutput(' 0/10 [>---------------------------] 0%').
$this->generateOutput(' 10/10 [============================] 100%').
$this->generateOutput(' 10/10 [============================] 100%')
;
// max in construct, no format
$bar = new ProgressBar($output = $this->getOutputStream(), 10);
$bar->start();
$bar->advance(10);
$bar->finish();
rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));
// max in start, no format
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->start(10);
$bar->advance(10);
$bar->finish();
rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));
// max in construct, explicit format before
$bar = new ProgressBar($output = $this->getOutputStream(), 10);
$bar->setFormat('normal');
$bar->start();
$bar->advance(10);
$bar->finish();
rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));
// max in start, explicit format before
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->setFormat('normal');
$bar->start(10);
$bar->advance(10);
$bar->finish();
rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));
}
public function testCustomizations()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 10);