diff --git a/src/ProgressBar.php b/src/ProgressBar.php index 74114f7..d4a1824 100644 --- a/src/ProgressBar.php +++ b/src/ProgressBar.php @@ -31,6 +31,12 @@ final class ProgressBar /** Time when progress bar starts displaying */ private int $startTime; + /** + * Indicator whether maxProgress was truly set as zero. + * MaxProgress must always be at least one to be displayed. + */ + private bool $maxProgressIsZero = false; + /** * Initialize and set progress and maxProgress when available. * Use separate setProgress() and setMaxProgress() methods when undetermined during initialization. @@ -204,7 +210,7 @@ private function setEstimatedTime(): ProgressBar $this->estimatedTime = round( ( time() - $this->startTime - ) / $this->progress * ($this->maxProgress - $this->progress) + ) / max(1, $this->progress) * ($this->maxProgress - $this->progress) ); return $this; @@ -215,6 +221,10 @@ private function setEstimatedTime(): ProgressBar */ public function setMaxProgress(int|float $maxProgress): ProgressBar { + if ($maxProgress == 0) { + $this->maxProgressIsZero = true; + } + $this->maxProgress = max(1, $maxProgress); return $this; @@ -274,6 +284,12 @@ public function start(): void */ public function tick(int $progress = 1): void { + if ($progress == 0 && $this->maxProgressIsZero) { + $this->finish(); + + return; + } + $this->setProgress($this->progress + $progress) ->setEstimatedTime(); diff --git a/tests/ProgressBarTest.php b/tests/ProgressBarTest.php index 55f6516..90551ed 100644 --- a/tests/ProgressBarTest.php +++ b/tests/ProgressBarTest.php @@ -148,4 +148,18 @@ public function it_cannot_set_incorrect_max_progress() $this->assertEquals(1, $progressBar->getMaxProgress()); } + + /** + * @test + */ + public function it_can_gracefully_handle_zero_progress() + { + $progressBar = new ProgressBar(maxProgress: 0); + $this->assertEquals(1, $progressBar->getMaxProgress()); + + $progressBar->tick(0); + $this->assertEquals(1, $progressBar->getProgress()); + + $this->assertEquals(100, $progressBar->getPercentage()); + } }