From 770b9141da0a03fc9494d20d5ae8e52ef9981f7c Mon Sep 17 00:00:00 2001 From: insign <1113045+insign@users.noreply.github.com> Date: Sat, 14 Feb 2026 03:46:38 +0000 Subject: [PATCH] Add step-based progress tracking to Progressable trait - Added `setTotalSteps`, `incrementStep`, `setStep` methods. - Added `totalSteps` and `currentStep` properties. - Added tests for step-based progress tracking. --- src/Progressable.php | 68 ++++++++++++++++++++++++++++++++++++++ tests/ProgressableTest.php | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/src/Progressable.php b/src/Progressable.php index 0997237..fc9517e 100644 --- a/src/Progressable.php +++ b/src/Progressable.php @@ -17,6 +17,16 @@ trait Progressable { */ protected float $progress = 0; + /** + * Total steps for the process. + */ + protected ?int $totalSteps = null; + + /** + * Current step of the process. + */ + protected int $currentStep = 0; + /** * The callback function for saving cache data. * @@ -90,6 +100,64 @@ trait Progressable { */ protected mixed $onComplete = null; + /** + * Set the total number of steps. + * + * @return $this + */ + public function setTotalSteps(int $steps): static { + if ($steps <= 0) { + throw new \InvalidArgumentException('Total steps must be greater than 0'); + } + $this->totalSteps = $steps; + + return $this; + } + + /** + * Increment the current step. + * + * @return $this + */ + public function incrementStep(int $amount = 1): static { + if ($this->totalSteps === null) { + throw new \LogicException('Total steps not set. Call setTotalSteps() first.'); + } + $this->currentStep += $amount; + $progress = ($this->currentStep / $this->totalSteps) * 100; + + return $this->setLocalProgress($progress); + } + + /** + * Set the current step. + * + * @return $this + */ + public function setStep(int $step): static { + if ($this->totalSteps === null) { + throw new \LogicException('Total steps not set. Call setTotalSteps() first.'); + } + $this->currentStep = $step; + $progress = ($this->currentStep / $this->totalSteps) * 100; + + return $this->setLocalProgress($progress); + } + + /** + * Get the total number of steps. + */ + public function getTotalSteps(): ?int { + return $this->totalSteps; + } + + /** + * Get the current step. + */ + public function getCurrentStep(): int { + return $this->currentStep; + } + /** * Set the callback function for saving cache data. * diff --git a/tests/ProgressableTest.php b/tests/ProgressableTest.php index 40f5003..3d211a3 100644 --- a/tests/ProgressableTest.php +++ b/tests/ProgressableTest.php @@ -485,4 +485,61 @@ public function test_merge_metadata(): void { $this->assertEquals('new_value1', $storedMetadata['key1']); $this->assertEquals('value2', $storedMetadata['key2']); } + + public function test_set_total_steps(): void { + $this->setOverallUniqueName('test_steps_'.$this->testId); + $this->setTotalSteps(10); + $this->assertEquals(10, $this->getTotalSteps()); + } + + public function test_set_total_steps_exception(): void { + $this->expectException(\InvalidArgumentException::class); + $this->setTotalSteps(0); + } + + public function test_increment_step(): void { + $this->setOverallUniqueName('test_inc_step_'.$this->testId); + $this->setTotalSteps(10); + + $this->incrementStep(); + $this->assertEquals(1, $this->getCurrentStep()); + $this->assertEquals(10, $this->getLocalProgress()); + + $this->incrementStep(2); + $this->assertEquals(3, $this->getCurrentStep()); + $this->assertEquals(30, $this->getLocalProgress()); + } + + public function test_set_step(): void { + $this->setOverallUniqueName('test_set_step_'.$this->testId); + $this->setTotalSteps(10); + + $this->setStep(5); + $this->assertEquals(5, $this->getCurrentStep()); + $this->assertEquals(50, $this->getLocalProgress()); + } + + public function test_increment_step_without_total_steps(): void { + $this->setOverallUniqueName('test_no_total_'.$this->testId); + $this->expectException(\LogicException::class); + $this->incrementStep(); + } + + public function test_step_progress_calculation(): void { + $this->setOverallUniqueName('test_step_calc_'.$this->testId); + $this->setTotalSteps(3); + + $this->incrementStep(); + // 1/3 = 33.333... + $this->assertEquals(33.33, $this->getLocalProgress(2)); + } + + public function test_step_exceeds_total(): void { + $this->setOverallUniqueName('test_step_exceed_'.$this->testId); + $this->setTotalSteps(10); + + $this->setStep(11); + $this->assertEquals(11, $this->getCurrentStep()); + $this->assertEquals(100, $this->getLocalProgress()); + } }