From 64f66ac87f61a2c85b9c723d768acc4a03ed2fc3 Mon Sep 17 00:00:00 2001 From: insign <1113045+insign@users.noreply.github.com> Date: Fri, 27 Feb 2026 03:24:28 +0000 Subject: [PATCH] feat: Add toArray method to Progressable trait This commit adds a `toArray()` method to the `Progressable` trait. This method aggregates all relevant progress data (local progress, overall progress, status message, metadata, steps, ETA, and completion status) into a single array. This is useful for easily exporting the progress state, for example, in API responses. Tests were added to `tests/ProgressableTest.php` to verify the structure and values of the returned array in both populated and minimal states. --- src/Progressable.php | 17 ++++++++++++ tests/ProgressableTest.php | 55 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/Progressable.php b/src/Progressable.php index 64786bf..cc03314 100644 --- a/src/Progressable.php +++ b/src/Progressable.php @@ -644,4 +644,21 @@ public function incrementStep(int $amount = 1): static { return $this->setStep($current + $amount); } + + /** + * Get the progress data as an array. + */ + public function toArray(): array { + return [ + 'progress' => $this->getLocalProgress(), + 'overall_progress' => $this->getOverallProgress(), + 'message' => $this->getStatusMessage(), + 'metadata' => $this->getMetadata(), + 'current_step' => $this->getStep(), + 'total_steps' => $this->getTotalSteps(), + 'estimated_time_remaining' => $this->getEstimatedTimeRemaining(), + 'is_complete' => $this->isComplete(), + 'is_overall_complete' => $this->isOverallComplete(), + ]; + } } diff --git a/tests/ProgressableTest.php b/tests/ProgressableTest.php index 2187c6b..e0263ea 100644 --- a/tests/ProgressableTest.php +++ b/tests/ProgressableTest.php @@ -2,6 +2,7 @@ namespace Verseles\Progressable\Tests; +use Illuminate\Support\Carbon; use Orchestra\Testbench\TestCase; use Verseles\Progressable\Exceptions\UniqueNameAlreadySetException; use Verseles\Progressable\Exceptions\UniqueNameNotSetException; @@ -553,4 +554,58 @@ public function test_set_step_without_total_steps(): void { $this->assertEquals(5, $this->getStep()); $this->assertEquals(0, $this->getLocalProgress()); } + + public function test_to_array_structure(): void { + Carbon::setTestNow(Carbon::now()); + $this->setOverallUniqueName('test_to_array_' . $this->testId); + + // Setup state + $this->setTotalSteps(100); + $this->setStep(50); // Sets progress to 50% + $this->setStatusMessage('Halfway there'); + $this->setMetadata(['foo' => 'bar']); + + // Advance time to allow ETA calculation + Carbon::setTestNow(Carbon::now()->addSeconds(10)); + // Progress 0 -> 50 in 10 seconds. Rate 5% / sec. Remaining 50%. ETA 10s. + $this->setLocalProgress(50); + + $array = $this->toArray(); + + $this->assertIsArray($array); + $this->assertArrayHasKey('progress', $array); + $this->assertArrayHasKey('overall_progress', $array); + $this->assertArrayHasKey('message', $array); + $this->assertArrayHasKey('metadata', $array); + $this->assertArrayHasKey('current_step', $array); + $this->assertArrayHasKey('total_steps', $array); + $this->assertArrayHasKey('estimated_time_remaining', $array); + $this->assertArrayHasKey('is_complete', $array); + $this->assertArrayHasKey('is_overall_complete', $array); + + $this->assertEquals(50, $array['progress']); + $this->assertEquals(50, $array['overall_progress']); + $this->assertEquals('Halfway there', $array['message']); + $this->assertEquals(['foo' => 'bar'], $array['metadata']); + $this->assertEquals(50, $array['current_step']); + $this->assertEquals(100, $array['total_steps']); + // ETA calculation might vary slightly depending on exact timing, but should be around 10 + $this->assertEquals(10, $array['estimated_time_remaining']); + $this->assertFalse($array['is_complete']); + } + + public function test_to_array_minimal(): void { + $this->setOverallUniqueName('test_to_array_minimal_' . $this->testId); + + $array = $this->toArray(); + + $this->assertEquals(0, $array['progress']); + $this->assertEquals(0, $array['overall_progress']); + $this->assertNull($array['message']); + $this->assertEmpty($array['metadata']); + $this->assertNull($array['current_step']); + $this->assertNull($array['total_steps']); + $this->assertNull($array['estimated_time_remaining']); + $this->assertFalse($array['is_complete']); + } }