diff --git a/src/Progressable.php b/src/Progressable.php index 4492077..d53f833 100644 --- a/src/Progressable.php +++ b/src/Progressable.php @@ -292,23 +292,33 @@ public function isOverallComplete(): bool { * Get the estimated time remaining in seconds for the overall progress. */ public function getOverallEstimatedTimeRemaining(): ?int { - $overallProgress = $this->getOverallProgress(); - - if ($overallProgress >= 100) { - return 0; - } - $progressData = $this->getOverallProgressData(); if (empty($progressData)) { return null; } + $totalProgress = 0; + $allComplete = true; + + foreach ($progressData as $data) { + $progress = $data['progress'] ?? 0; + $totalProgress += $progress; + + if ($progress < 100) { + $allComplete = false; + } + } + + if ($allComplete) { + return 0; + } + $startTimes = array_filter(array_column($progressData, 'start_time'), function ($time) { return $time !== null; }); - if (empty($startTimes) || $overallProgress <= 0) { + if (empty($startTimes) || $totalProgress <= 0) { return null; } @@ -319,6 +329,12 @@ public function getOverallEstimatedTimeRemaining(): ?int { return null; } + $overallProgress = $totalProgress / count($progressData); + + if ($overallProgress <= 0) { + return null; + } + $rate = $overallProgress / $elapsed; $remainingProgress = 100 - $overallProgress; diff --git a/tests/IsCompleteBugTest.php b/tests/IsCompleteBugTest.php new file mode 100644 index 0000000..d371f7b --- /dev/null +++ b/tests/IsCompleteBugTest.php @@ -0,0 +1,26 @@ +setPrecision(0); + $a->setOverallUniqueName('test_complete_bug'); + $a->setLocalKey('a'); + $a->setLocalProgress(99.6); // getLocalProgress() will return 100 + + $this->assertEquals(100, $a->getLocalProgress()); + $this->assertFalse($a->isComplete(), 'isComplete should return false when progress < 100, even if rounded to 100.'); + + $a->setLocalProgress(100); + $this->assertTrue($a->isComplete(), 'isComplete should return true when progress is 100.'); + } +} diff --git a/tests/OverallEtaBugTest.php b/tests/OverallEtaBugTest.php new file mode 100644 index 0000000..728b695 --- /dev/null +++ b/tests/OverallEtaBugTest.php @@ -0,0 +1,46 @@ +setPrecision(0); + $a->setOverallUniqueName($uniqueName); + $a->setLocalKey('a'); + $a->setLocalProgress(100); + + Carbon::setTestNow(Carbon::now()->addSeconds(1000)); + + $b = new DummyProgressableOverallEtaBug; + $b->setPrecision(0); + $b->setOverallUniqueName($uniqueName); + $b->setLocalKey('b'); + // We want average progress to round to 100 with PHP_ROUND_HALF_ODD. + // 99.6 rounds to 100. + // a=100. Let b=99.2. Average = 99.6. getOverallProgress(0) = 100. + // Unrounded average = 99.6. + // Rate = 99.6 / 1000 = 0.0996. + // Remaining = 100 - 99.6 = 0.4. + // ETA = 0.4 / 0.0996 = 4.016 -> rounds to 4. + $b->setLocalProgress(99.2); + + $this->assertEquals(100, $a->getOverallProgress()); + $this->assertFalse($a->isOverallComplete()); + + $eta = $a->getOverallEstimatedTimeRemaining(); + $this->assertEquals(4, $eta, 'ETA should calculate correctly from unrounded progress, yielding 4 seconds.'); + } +}