From 644e35ec2e47ba5cb0eaa13973e2967d7ad58bfd Mon Sep 17 00:00:00 2001 From: corgab Date: Tue, 8 Sep 2026 19:15:41 +0000 Subject: [PATCH 1/3] refactor(manager): resolve the pinned driver name through driverAlias() circuit() and batch() re-implemented the null-to-default half of driverAlias() inline as $driver ?? $this->getDefaultDriver(). Both now call driverAlias(), so one method knows how an absent driver name resolves. Closes #61 --- src/QuantumManager.php | 8 +++++--- tests/Feature/QuantumManagerTest.php | 9 +++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/QuantumManager.php b/src/QuantumManager.php index b288eaa..844276e 100644 --- a/src/QuantumManager.php +++ b/src/QuantumManager.php @@ -50,7 +50,9 @@ public function driver($driver = null) /** * The string alias for a driver argument, which Manager also accepts as an - * enum; the fake reports this on the events it dispatches. + * enum. The one place that knows how an absent name resolves to the + * default: the fake reports it on the events it dispatches, and circuit() + * and batch() pin it onto the builders they create. */ private function driverAlias(string|UnitEnum|null $driver): string { @@ -73,7 +75,7 @@ public function circuit(?string $driver = null): CircuitBuilder { return new CircuitBuilder( $this->driver($driver), - $driver ?? $this->getDefaultDriver(), + $this->driverAlias($driver), ); } @@ -87,7 +89,7 @@ public function batch(array $circuits, ?string $driver = null): BatchBuilder return new BatchBuilder( $this->driver($driver), array_values($circuits), - $driver ?? $this->getDefaultDriver(), + $this->driverAlias($driver), ); } diff --git a/tests/Feature/QuantumManagerTest.php b/tests/Feature/QuantumManagerTest.php index 0f99548..4a3443f 100644 --- a/tests/Feature/QuantumManagerTest.php +++ b/tests/Feature/QuantumManagerTest.php @@ -119,3 +119,12 @@ expect($manager->circuit()->driverName())->toBe('local'); }); + +it('pins the resolved default driver name on batches when no driver is requested', function () { + config()->set('aether.default', 'local'); + + $manager = app(QuantumManager::class); + $batch = $manager->batch([$manager->circuit()->qubits(1)->h(0)->measure()]); + + expect((new ReflectionProperty($batch, 'driverName'))->getValue($batch))->toBe('local'); +}); From 357b91104a6c5806ac7dc568e449233f0a7c2f9d Mon Sep 17 00:00:00 2001 From: corgab Date: Tue, 8 Sep 2026 19:19:12 +0000 Subject: [PATCH 2/3] refactor(manager): resolve the alias once per builder and let the jobs ask the manager for the default circuit() and batch() resolve the driver name first and hand the same string to driver(), so the pinned name and the resolved device agree by construction. SubmitQuantumCircuit and PollQuantumTask no longer repeat the 'local' literal: they take the default from QuantumManager::getDefaultDriver(). The pinning tests now set a non-default driver so a hardcoded fallback could not pass them. --- src/Jobs/PollQuantumTask.php | 2 +- src/Jobs/SubmitQuantumCircuit.php | 2 +- src/QuantumManager.php | 22 ++++++++++------------ tests/Feature/QuantumManagerTest.php | 8 ++++---- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Jobs/PollQuantumTask.php b/src/Jobs/PollQuantumTask.php index 9a4c0b2..a20f4ef 100644 --- a/src/Jobs/PollQuantumTask.php +++ b/src/Jobs/PollQuantumTask.php @@ -71,7 +71,7 @@ public function tries(): int */ public function handle(QuantumManager $manager, Dispatcher $events): void { - $driverName = $this->driver ?? config('aether.default', 'local'); + $driverName = $this->driver ?? $manager->getDefaultDriver(); $device = $manager->driver($this->driver); if (! $device instanceof AsynchronousDevice || ! $device instanceof QuantumDevice) { diff --git a/src/Jobs/SubmitQuantumCircuit.php b/src/Jobs/SubmitQuantumCircuit.php index 539ded3..2d44d62 100644 --- a/src/Jobs/SubmitQuantumCircuit.php +++ b/src/Jobs/SubmitQuantumCircuit.php @@ -52,7 +52,7 @@ public function __construct( */ public function handle(QuantumManager $manager): void { - $driverName = $this->driver ?? config('aether.default', 'local'); + $driverName = $this->driver ?? $manager->getDefaultDriver(); $device = $manager->driver($this->driver); if (! $device instanceof AsynchronousDevice || ! $device instanceof QuantumDevice) { diff --git a/src/QuantumManager.php b/src/QuantumManager.php index 844276e..0e3c3f6 100644 --- a/src/QuantumManager.php +++ b/src/QuantumManager.php @@ -50,9 +50,10 @@ public function driver($driver = null) /** * The string alias for a driver argument, which Manager also accepts as an - * enum. The one place that knows how an absent name resolves to the - * default: the fake reports it on the events it dispatches, and circuit() - * and batch() pin it onto the builders they create. + * enum. The one place in the manager that knows how an absent name + * resolves to the default: the fake reports it on the events it + * dispatches, and circuit() and batch() pin it onto the builders they + * create. The queue jobs ask getDefaultDriver() for the same answer. */ private function driverAlias(string|UnitEnum|null $driver): string { @@ -73,10 +74,9 @@ private function driverAlias(string|UnitEnum|null $driver): string */ public function circuit(?string $driver = null): CircuitBuilder { - return new CircuitBuilder( - $this->driver($driver), - $this->driverAlias($driver), - ); + $name = $this->driverAlias($driver); + + return new CircuitBuilder($this->driver($name), $name); } /** @@ -86,11 +86,9 @@ public function circuit(?string $driver = null): CircuitBuilder */ public function batch(array $circuits, ?string $driver = null): BatchBuilder { - return new BatchBuilder( - $this->driver($driver), - array_values($circuits), - $this->driverAlias($driver), - ); + $name = $this->driverAlias($driver); + + return new BatchBuilder($this->driver($name), array_values($circuits), $name); } /** diff --git a/tests/Feature/QuantumManagerTest.php b/tests/Feature/QuantumManagerTest.php index 4a3443f..3d019c4 100644 --- a/tests/Feature/QuantumManagerTest.php +++ b/tests/Feature/QuantumManagerTest.php @@ -113,18 +113,18 @@ }); it('pins the resolved default driver name when no driver is requested', function () { - config()->set('aether.default', 'local'); + config()->set('aether.default', 'aws'); $manager = app(QuantumManager::class); - expect($manager->circuit()->driverName())->toBe('local'); + expect($manager->circuit()->driverName())->toBe('aws'); }); it('pins the resolved default driver name on batches when no driver is requested', function () { - config()->set('aether.default', 'local'); + config()->set('aether.default', 'aws'); $manager = app(QuantumManager::class); $batch = $manager->batch([$manager->circuit()->qubits(1)->h(0)->measure()]); - expect((new ReflectionProperty($batch, 'driverName'))->getValue($batch))->toBe('local'); + expect((new ReflectionProperty($batch, 'driverName'))->getValue($batch))->toBe('aws'); }); From a231200638247783492d3d56934d9e5778dfdcfe Mon Sep 17 00:00:00 2001 From: corgab Date: Thu, 10 Sep 2026 13:15:40 +0200 Subject: [PATCH 3/3] Apply review feedback: expose driverName and use driverAlias in jobs --- src/Circuit/BatchBuilder.php | 8 ++++++++ src/Jobs/PollQuantumTask.php | 4 ++-- src/Jobs/SubmitQuantumCircuit.php | 4 ++-- src/QuantumManager.php | 2 +- tests/Feature/QuantumManagerTest.php | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Circuit/BatchBuilder.php b/src/Circuit/BatchBuilder.php index 97bf8e3..87ef558 100644 --- a/src/Circuit/BatchBuilder.php +++ b/src/Circuit/BatchBuilder.php @@ -52,4 +52,12 @@ public function run(): BatchResult return $this->device->executeBatch($this->circuits); } + + /** + * Get the name of the driver this batch is pinned to. + */ + public function driverName(): string + { + return $this->driverName; + } } diff --git a/src/Jobs/PollQuantumTask.php b/src/Jobs/PollQuantumTask.php index a20f4ef..c994044 100644 --- a/src/Jobs/PollQuantumTask.php +++ b/src/Jobs/PollQuantumTask.php @@ -71,8 +71,8 @@ public function tries(): int */ public function handle(QuantumManager $manager, Dispatcher $events): void { - $driverName = $this->driver ?? $manager->getDefaultDriver(); - $device = $manager->driver($this->driver); + $driverName = $manager->driverAlias($this->driver); + $device = $manager->driver($driverName); if (! $device instanceof AsynchronousDevice || ! $device instanceof QuantumDevice) { throw QuantumExecutionException::asynchronousUnsupported($driverName); diff --git a/src/Jobs/SubmitQuantumCircuit.php b/src/Jobs/SubmitQuantumCircuit.php index 2d44d62..9ed8080 100644 --- a/src/Jobs/SubmitQuantumCircuit.php +++ b/src/Jobs/SubmitQuantumCircuit.php @@ -52,8 +52,8 @@ public function __construct( */ public function handle(QuantumManager $manager): void { - $driverName = $this->driver ?? $manager->getDefaultDriver(); - $device = $manager->driver($this->driver); + $driverName = $manager->driverAlias($this->driver); + $device = $manager->driver($driverName); if (! $device instanceof AsynchronousDevice || ! $device instanceof QuantumDevice) { throw QuantumExecutionException::asynchronousUnsupported($driverName); diff --git a/src/QuantumManager.php b/src/QuantumManager.php index 0e3c3f6..10b7194 100644 --- a/src/QuantumManager.php +++ b/src/QuantumManager.php @@ -55,7 +55,7 @@ public function driver($driver = null) * dispatches, and circuit() and batch() pin it onto the builders they * create. The queue jobs ask getDefaultDriver() for the same answer. */ - private function driverAlias(string|UnitEnum|null $driver): string + public function driverAlias(string|UnitEnum|null $driver): string { return match (true) { $driver === null => $this->getDefaultDriver(), diff --git a/tests/Feature/QuantumManagerTest.php b/tests/Feature/QuantumManagerTest.php index 3d019c4..4642272 100644 --- a/tests/Feature/QuantumManagerTest.php +++ b/tests/Feature/QuantumManagerTest.php @@ -126,5 +126,5 @@ $manager = app(QuantumManager::class); $batch = $manager->batch([$manager->circuit()->qubits(1)->h(0)->measure()]); - expect((new ReflectionProperty($batch, 'driverName'))->getValue($batch))->toBe('aws'); + expect($batch->driverName())->toBe('aws'); });