v0.2.0 (5/N): close audit sweep — BridgeOp contract test + PLAN.md status

The audit's substantive items shipped in chunks 1–4. Two remaining
loose ends inspected and parked:

- Generated controller findOr404 boilerplate. MapEntity changes the
  404 response shape away from problem+json unless framework-level
  RFC 7807 error config is updated; a private helper is net-zero
  on lines. Parking until either (a) skeleton-level RFC 7807 error
  wiring, or (b) --with-dto flipping to default-on and the legacy
  template's polish becoming irrelevant.
- ModelPublisher::extractId reflection branch. Looks dead because
  every maker-output entity has getId(), but it remains a safety net
  for hand-written entities that don't. Keeping.

This commit ships:

- BridgeOpTest — locks the enum case values against accidental
  rename. Every case value is a documented wire-format token QML
  clients hardcode, so renaming a `value` is a wire-protocol break
  and this fails the build before it ships.

- PLAN.md §13 v0.2.0 status block with what's shipped on dev
  (interfaces / BridgeOp / BridgeBundleInfo / Maker DRY / --with-dto)
  and what's still open (findOr404 polish, --with-dto default flip).

Test count 23 → 24, all passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-03 20:15:16 +02:00
parent 5498c3c91e
commit f2d931e0a5
3 changed files with 41 additions and 8 deletions

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace PhpQml\Bridge\Tests;
use PhpQml\Bridge\BridgeOp;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
#[CoversClass(BridgeOp::class)]
final class BridgeOpTest extends TestCase
{
/**
* The four cases are the bridge's wire-format envelope `op` tokens
* (PLAN.md §4). QML clients hardcode the strings — renaming an enum
* case is a backwards-compatible PHP-side refactor, but renaming a
* `value` is not. This test fails the build before such a rename
* ships.
*/
public function testWireFormatValuesMatchDocumentedTokens(): void
{
self::assertSame('upsert', BridgeOp::Upsert->value);
self::assertSame('delete', BridgeOp::Delete->value);
self::assertSame('replace', BridgeOp::Replace->value);
self::assertSame('event', BridgeOp::Event->value);
}
}