Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Rxn/Framework/Codegen/PolyparityExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Rxn\Framework\Http\Attribute\Required;
use Rxn\Framework\Http\Attribute\Url;
use Rxn\Framework\Http\Binding\RequestDto;
use Rxn\Framework\Http\Binding\Validates;

/**
* Emit a polyparity YAML spec from a Rxn `RequestDto`. The same
Expand Down Expand Up @@ -212,6 +213,15 @@ private function refuse(string $attrName, string $propName): ?string
. 'Add a mapping or document the DTO as PHP-only.',
);
}

if (is_subclass_of($attrName, Validates::class)) {
throw new \RuntimeException(
"PolyparityExporter: $attrName on property '$propName' is a custom validator. "
. 'Refusing to emit silently-divergent spec. '
. 'Add a polyparity mapping or keep this DTO PHP-only.'
);
}

return null;
}

Expand Down
8 changes: 8 additions & 0 deletions src/Rxn/Framework/Tests/Codegen/PolyparityExporterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@ public function testRefusesUnsupportedAttribute(): void
$exporter->emit(Fixture\UnsupportedDto::class);
}


public function testRefusesCustomValidatesAttribute(): void
{
$exporter = new PolyparityExporter();
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageMatches('/CustomValidatesAttribute.*custom validator/i');
$exporter->emit(Fixture\CustomUnsupportedDto::class);
}
public function testRejectsNonRequestDto(): void
{
$exporter = new PolyparityExporter();
Expand Down
Loading