From 9e493d90d4e9d0032ee4f5d41bc9e5e358a24ad6 Mon Sep 17 00:00:00 2001 From: dimarik82 Date: Wed, 27 May 2026 15:16:34 +0000 Subject: [PATCH] refactor(tools): adopt list contract from core ^1.1 Bump dbschemix/core and dbschemix/pdo to ^1.1, which changes EventSubscriberInterface::subscriptions() from array to list. Update PrettyConsoleOutput and TraceConsoleOutput to emit Subscription objects, and rewrite the related tests to look up callbacks by iterating over the list instead of indexing by event value. Co-Authored-By: Claude Opus 4.7 (1M context) --- composer.json | 4 +-- src/tools/PrettyConsoleOutput.php | 23 ++++++++-------- src/tools/TraceConsoleOutput.php | 14 +++++----- tests/tools/PrettyConsoleOutputTest.php | 35 ++++++++++++++++++------- tests/tools/TraceConsoleOutputTest.php | 31 +++++++++++++++++----- 5 files changed, 70 insertions(+), 37 deletions(-) diff --git a/composer.json b/composer.json index 941bf8a..d90f262 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,8 @@ "require": { "php": "^8.3", "symfony/console": "^7.4", - "dbschemix/core": "^1.0", - "dbschemix/pdo": "^1.0", + "dbschemix/core": "^1.1", + "dbschemix/pdo": "^1.1", "league/climate": "^3.10" }, "require-dev": { diff --git a/src/tools/PrettyConsoleOutput.php b/src/tools/PrettyConsoleOutput.php index affb4b6..d39f72d 100644 --- a/src/tools/PrettyConsoleOutput.php +++ b/src/tools/PrettyConsoleOutput.php @@ -11,6 +11,7 @@ use dbschemix\core\event\EventSubscriberInterface; use dbschemix\core\event\MigrateErrorEvent; use dbschemix\core\event\MigrateSuccessEvent; +use dbschemix\core\event\Subscription; /** * @api @@ -28,26 +29,24 @@ public function subscriptions(): array { $subscriptions = []; foreach (Event::cases() as $event) { - $subscriptions[$event->value] = match ($event) { - Event::MigrateSuccess => $this->success(...), - Event::MigrateError => $this->error(...), - Event::FilesystemNotice => $this->notice(...), - default => $this->failure(...), + $subscriptions[] = match ($event) { + Event::MigrateSuccess => new Subscription($event, $this->success(...)), + Event::MigrateError => new Subscription($event, $this->error(...)), + Event::FilesystemNotice => new Subscription($event, $this->notice(...)), + default => new Subscription($event, $this->failure(...)), }; } - /** - * @var non-empty-array $subscriptions - * @phpstan-ignore varTag.nativeType - */ return $subscriptions; } /** * @noinspection PhpUnusedParameterInspection */ - public function success(Event $name, MigrateSuccessEvent $event): void + public function success(Event $name, EventInterface $event): void { + assert($event instanceof MigrateSuccessEvent); + $this->output->out( match ($event->action) { "up", @@ -74,8 +73,10 @@ public function success(Event $name, MigrateSuccessEvent $event): void /** * @noinspection PhpUnusedParameterInspection */ - public function error(Event $name, MigrateErrorEvent $event): void + public function error(Event $name, EventInterface $event): void { + assert($event instanceof MigrateErrorEvent); + $this->output->out( sprintf( '[%s] %s: %s error', diff --git a/src/tools/TraceConsoleOutput.php b/src/tools/TraceConsoleOutput.php index ad34d7a..d835f21 100644 --- a/src/tools/TraceConsoleOutput.php +++ b/src/tools/TraceConsoleOutput.php @@ -10,6 +10,7 @@ use dbschemix\core\event\EventInterface; use dbschemix\core\event\EventSubscriberInterface; use dbschemix\core\event\MigrateSuccessEvent; +use dbschemix\core\event\Subscription; /** * @api @@ -25,24 +26,21 @@ public function subscriptions(): array { $subscriptions = []; foreach (Event::cases() as $event) { - $subscriptions[$event->value] = match ($event) { - Event::MigrateSuccess => $this->success(...), - default => $this->error(...), + $subscriptions[] = match ($event) { + Event::MigrateSuccess => new Subscription($event, $this->success(...)), + default => new Subscription($event, $this->error(...)), }; } - /** - * @var non-empty-array $subscriptions - * @phpstan-ignore varTag.nativeType - */ return $subscriptions; } /** * @noinspection PhpUnusedParameterInspection */ - public function success(Event $name, MigrateSuccessEvent $event): void + public function success(Event $name, EventInterface $event): void { + assert($event instanceof MigrateSuccessEvent); $this->stdout($event->getMessage()); } diff --git a/tests/tools/PrettyConsoleOutputTest.php b/tests/tools/PrettyConsoleOutputTest.php index 1ac46fa..232697b 100644 --- a/tests/tools/PrettyConsoleOutputTest.php +++ b/tests/tools/PrettyConsoleOutputTest.php @@ -4,6 +4,7 @@ namespace dbschemix\migrator\tests\tools; +use Closure; use League\CLImate\CLImate; use League\CLImate\Util\Writer\Buffer; use PHPUnit\Framework\Attributes\CoversClass; @@ -15,6 +16,7 @@ use dbschemix\core\event\MigrateErrorEvent; use dbschemix\core\event\MigrateSuccessEvent; use dbschemix\core\event\ExceptionEvent; +use dbschemix\core\event\Subscription; use dbschemix\migrator\tools\PrettyConsoleOutput; use RuntimeException; @@ -42,6 +44,21 @@ private function makeBufferedClimate(): array return [$climate, $buffer->get(...)]; } + /** + * @param list $subscriptions + * @return Closure(Event, \dbschemix\core\event\EventInterface): void + */ + private static function callbackFor(array $subscriptions, Event $event): Closure + { + foreach ($subscriptions as $subscription) { + if ($subscription->event === $event) { + return $subscription->callback; + } + } + + self::fail("No subscription registered for event {$event->value}"); + } + // ----------------------------------------------------------------------- // subscriptions() // ----------------------------------------------------------------------- @@ -56,13 +73,13 @@ public function subscriptions_covers_every_event_case(): void $subscriptions = $pretty->subscriptions(); // Then - $expectedKeys = array_map(static fn(Event $e): string => $e->value, Event::cases()); - sort($expectedKeys); + $expected = Event::cases(); + sort($expected); - $actualKeys = array_keys($subscriptions); - sort($actualKeys); + $actual = array_map(static fn(Subscription $s): Event => $s->event, $subscriptions); + sort($actual); - self::assertSame($expectedKeys, $actualKeys); + self::assertSame($expected, $actual); } #[Test] @@ -76,7 +93,7 @@ public function subscriptions_maps_migrate_success_to_success_handler(): void // When $subscriptions = $pretty->subscriptions(); - ($subscriptions[Event::MigrateSuccess->value])(Event::MigrateSuccess, $event); + (self::callbackFor($subscriptions, Event::MigrateSuccess))(Event::MigrateSuccess, $event); // Then self::assertStringContainsString('db', $readBuffer()); @@ -97,7 +114,7 @@ public function subscriptions_maps_migrate_error_to_error_handler(): void // When $subscriptions = $pretty->subscriptions(); - ($subscriptions[Event::MigrateError->value])(Event::MigrateError, $event); + (self::callbackFor($subscriptions, Event::MigrateError))(Event::MigrateError, $event); // Then self::assertStringContainsString('error', $readBuffer()); @@ -113,7 +130,7 @@ public function subscriptions_maps_filesystem_notice_to_notice_handler(): void // When $subscriptions = $pretty->subscriptions(); - ($subscriptions[Event::FilesystemNotice->value])(Event::FilesystemNotice, $event); + (self::callbackFor($subscriptions, Event::FilesystemNotice))(Event::FilesystemNotice, $event); // Then self::assertStringContainsString('notice', $readBuffer()); @@ -144,7 +161,7 @@ public function subscriptions_maps_remaining_events_to_failure_handler(): void $subscriptions2 = $pretty2->subscriptions(); // When - ($subscriptions2[$case->value])($case, $event); + (self::callbackFor($subscriptions2, $case))($case, $event); // Then — failure() format contains "error:" $msg = "Event {$case->value} should use failure handler"; diff --git a/tests/tools/TraceConsoleOutputTest.php b/tests/tools/TraceConsoleOutputTest.php index 17d4231..e874c33 100644 --- a/tests/tools/TraceConsoleOutputTest.php +++ b/tests/tools/TraceConsoleOutputTest.php @@ -4,6 +4,7 @@ namespace dbschemix\migrator\tests\tools; +use Closure; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; @@ -11,6 +12,7 @@ use dbschemix\core\event\Event; use dbschemix\core\event\MigrateSuccessEvent; use dbschemix\core\event\MigrateErrorEvent; +use dbschemix\core\event\Subscription; use dbschemix\migrator\tests\Fakes\FakeConsoleOutput; use dbschemix\migrator\tools\TraceConsoleOutput; use RuntimeException; @@ -18,6 +20,21 @@ #[CoversClass(TraceConsoleOutput::class)] final class TraceConsoleOutputTest extends TestCase { + /** + * @param list $subscriptions + * @return Closure(Event, \dbschemix\core\event\EventInterface): void + */ + private static function callbackFor(array $subscriptions, Event $event): Closure + { + foreach ($subscriptions as $subscription) { + if ($subscription->event === $event) { + return $subscription->callback; + } + } + + self::fail("No subscription registered for event {$event->value}"); + } + // ----------------------------------------------------------------------- // subscriptions() // ----------------------------------------------------------------------- @@ -33,13 +50,13 @@ public function subscriptions_covers_every_event_case(): void $subscriptions = $trace->subscriptions(); // Then — every Event case must have a subscription - $expectedKeys = array_map(static fn(Event $e): string => $e->value, Event::cases()); - sort($expectedKeys); + $expected = Event::cases(); + sort($expected); - $actualKeys = array_keys($subscriptions); - sort($actualKeys); + $actual = array_map(static fn(Subscription $s): Event => $s->event, $subscriptions); + sort($actual); - self::assertSame($expectedKeys, $actualKeys); + self::assertSame($expected, $actual); } #[Test] @@ -56,7 +73,7 @@ public function subscriptions_maps_migrate_success_to_success_handler(): void $context = new Context(dbName: 'testdb', filename: 'V1__init.sql', query: 'SELECT 1'); $event = new MigrateSuccessEvent(action: 'up', context: $context); - ($subscriptions[Event::MigrateSuccess->value])(Event::MigrateSuccess, $event); + (self::callbackFor($subscriptions, Event::MigrateSuccess))(Event::MigrateSuccess, $event); self::assertCount(1, $output->lines); // success() writes event->getMessage() which is "[testdb] up: V1__init.sql, vers: 0" @@ -84,7 +101,7 @@ public function subscriptions_maps_non_success_events_to_error_handler(): void $output = new FakeConsoleOutput(); $subscriptions = (new TraceConsoleOutput($output))->subscriptions(); - ($subscriptions[$case->value])($case, $error); + (self::callbackFor($subscriptions, $case))($case, $error); self::assertCount(1, $output->lines, "Expected one writeln for event {$case->value}"); self::assertStringContainsString($error->getName(), $output->lines[0]); self::assertStringContainsString($error->getMessage(), $output->lines[0]);