Skip to content

Commit bfcd9d8

Browse files
authored
Fix possible division by zero error (#22)
* Fix division by zero error * Fix failing tests and correct percentage at zero progress * Apply php-cs-fixer changes
1 parent 11a51b5 commit bfcd9d8

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

src/ProgressBar.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ final class ProgressBar
3131
/** Time when progress bar starts displaying */
3232
private int $startTime;
3333

34+
/**
35+
* Indicator whether maxProgress was truly set as zero.
36+
* MaxProgress must always be at least one to be displayed.
37+
*/
38+
private bool $maxProgressIsZero = false;
39+
3440
/**
3541
* Initialize and set progress and maxProgress when available.
3642
* Use separate setProgress() and setMaxProgress() methods when undetermined during initialization.
@@ -204,7 +210,7 @@ private function setEstimatedTime(): ProgressBar
204210
$this->estimatedTime = round(
205211
(
206212
time() - $this->startTime
207-
) / $this->progress * ($this->maxProgress - $this->progress)
213+
) / max(1, $this->progress) * ($this->maxProgress - $this->progress)
208214
);
209215

210216
return $this;
@@ -215,6 +221,10 @@ private function setEstimatedTime(): ProgressBar
215221
*/
216222
public function setMaxProgress(int|float $maxProgress): ProgressBar
217223
{
224+
if ($maxProgress == 0) {
225+
$this->maxProgressIsZero = true;
226+
}
227+
218228
$this->maxProgress = max(1, $maxProgress);
219229

220230
return $this;
@@ -274,6 +284,12 @@ public function start(): void
274284
*/
275285
public function tick(int $progress = 1): void
276286
{
287+
if ($progress == 0 && $this->maxProgressIsZero) {
288+
$this->finish();
289+
290+
return;
291+
}
292+
277293
$this->setProgress($this->progress + $progress)
278294
->setEstimatedTime();
279295

tests/ProgressBarTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,18 @@ public function it_cannot_set_incorrect_max_progress()
148148

149149
$this->assertEquals(1, $progressBar->getMaxProgress());
150150
}
151+
152+
/**
153+
* @test
154+
*/
155+
public function it_can_gracefully_handle_zero_progress()
156+
{
157+
$progressBar = new ProgressBar(maxProgress: 0);
158+
$this->assertEquals(1, $progressBar->getMaxProgress());
159+
160+
$progressBar->tick(0);
161+
$this->assertEquals(1, $progressBar->getProgress());
162+
163+
$this->assertEquals(100, $progressBar->getPercentage());
164+
}
151165
}

0 commit comments

Comments
 (0)