pdftract/templates/sdk-skeleton/php/tests/Codegen/ConformanceTest.php.tera
jedarden 11257e7706 feat(pdftract-l993m): complete per-language Tera template scaffolding
Complete the Tera template scaffolding for all 8 subprocess-based SDKs
under templates/sdk-skeleton/<lang>/: node, go, java, dotnet, ruby,
php, swift, python-subprocess.

Each template directory contains:
- Package metadata template (package.json, go.mod, pom.xml, etc.)
- Method stubs template (methods.ts, client.go, Methods.java, etc.)
- Error stubs template (errors.ts, errors.go, Errors.java, etc.)
- Conformance runner template (conformance.test.ts, etc.)
- README template with {{ version }} variable substitution
- GENERATED.tera marker file

New files for python-subprocess:
- pdftract_subprocess/codegen/errors.py.tera
- tests/codegen/conformance_test.py.tera
- README.md.tera
- GENERATED.tera

All 8 language template directories are now complete and ready for
consumption by the `pdftract sdk codegen` subcommand.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-05-18 02:01:46 -04:00

176 lines
5.8 KiB
Text

<?php
namespace Pdftract\Tests\Codegen;
use PHPUnit\Framework\TestCase;
use Pdftract\Codegen\Client;
use Pdftract\Codegen\PathSource;
/**
* Conformance test suite for pdftract PHP SDK
* Auto-generated - do not edit manually
*/
class ConformanceTest extends TestCase
{
private Client $client;
private ?array $suite = null;
protected function setUp(): void
{
$this->client = new Client();
$suitePath = getenv('CONFORMANCE_SUITE') ?: 'tests/sdk-conformance/cases.json';
if (file_exists($suitePath)) {
$content = file_get_contents($suitePath);
$this->suite = json_decode($content, true);
}
}
public function testBinaryAvailable(): void
{
$result = null;
$exitCode = 1;
exec('pdftract --version 2>&1', $result, $exitCode);
$this->assertEquals(0, $exitCode, 'pdftract binary not found on PATH');
}
/**
* @dataProvider conformanceCases
*/
public function testConformance(array $testCase): void
{
$fixturePath = 'fixtures/' . $testCase['fixture'];
$this->runTestCase($testCase, $fixturePath);
}
public static function conformanceCases(): array
{
$suitePath = getenv('CONFORMANCE_SUITE') ?: 'tests/sdk-conformance/cases.json';
if (!file_exists($suitePath)) {
return [];
}
$content = file_get_contents($suitePath);
$suite = json_decode($content, true);
$cases = [];
foreach ($suite['cases'] as $tc) {
$cases[$tc['id'] . ':' . $tc['method']] = [$tc];
}
return $cases;
}
private function runTestCase(array $testCase, string $fixturePath): void
{
switch ($testCase['method']) {
case 'extract':
$this->testExtract($fixturePath, $testCase['assertions'] ?? null);
break;
case 'extract_text':
$this->testExtractText($fixturePath, $testCase['assertions'] ?? null);
break;
case 'extract_markdown':
$this->testExtractMarkdown($fixturePath, $testCase['assertions'] ?? null);
break;
case 'get_metadata':
$this->testGetMetadata($fixturePath, $testCase['assertions'] ?? null);
break;
case 'hash':
$this->testHash($fixturePath, $testCase['assertions'] ?? null);
break;
case 'classify':
$this->testClassify($fixturePath, $testCase['assertions'] ?? null);
break;
case 'verify_receipt':
$this->testVerifyReceipt($fixturePath, $testCase['assertions'] ?? null);
break;
default:
$this->markTestSkipped("Method not yet implemented: {$testCase['method']}");
}
}
private function testExtract(string $fixturePath, ?array $assertions): void
{
$doc = $this->client->extract(new PathSource($fixturePath));
if ($assertions !== null && isset($assertions['page_count'])) {
$this->assertEquals($assertions['page_count'], count($doc['pages']));
}
if ($assertions !== null && ($assertions['has_title'] ?? false)) {
$this->assertNotEmpty($doc['metadata']['title'] ?? '');
}
}
private function testExtractText(string $fixturePath, ?array $assertions): void
{
$text = $this->client->extractText(new PathSource($fixturePath));
if ($assertions !== null && isset($assertions['min_length'])) {
$this->assertGreaterThanOrEqual($assertions['min_length'], strlen($text));
}
if ($assertions !== null && isset($assertions['contains'])) {
foreach ($assertions['contains'] as $substr) {
$this->assertStringContainsString($substr, $text);
}
}
}
private function testExtractMarkdown(string $fixturePath, ?array $assertions): void
{
$md = $this->client->extractMarkdown(new PathSource($fixturePath));
if ($assertions !== null && isset($assertions['min_length'])) {
$this->assertGreaterThanOrEqual($assertions['min_length'], strlen($md));
}
}
private function testGetMetadata(string $fixturePath, ?array $assertions): void
{
$metadata = $this->client->getMetadata(new PathSource($fixturePath));
if ($assertions !== null && isset($assertions['page_count'])) {
$this->assertEquals($assertions['page_count'], $metadata['page_count']);
}
}
private function testHash(string $fixturePath, ?array $assertions): void
{
$fingerprint = $this->client->hash(new PathSource($fixturePath));
$this->assertEquals(64, strlen($fingerprint['hash']));
$this->assertEquals(64, strlen($fingerprint['fast_hash']));
if ($assertions !== null && isset($assertions['page_count'])) {
$this->assertEquals($assertions['page_count'], $fingerprint['page_count']);
}
}
private function testClassify(string $fixturePath, ?array $assertions): void
{
$classification = $this->client->classify(new PathSource($fixturePath));
$this->assertNotEmpty($classification['category']);
$this->assertGreaterThanOrEqual(0, $classification['confidence']);
$this->assertLessThanOrEqual(1, $classification['confidence']);
}
private function testVerifyReceipt(string $fixturePath, ?array $assertions): void
{
if ($assertions === null || !isset($assertions['receipt'])) {
$this->markTestSkipped('Receipt not provided in assertions');
return;
}
$valid = $this->client->verifyReceipt($fixturePath, $assertions['receipt']);
if (isset($assertions['valid'])) {
$this->assertEquals($assertions['valid'], $valid);
}
}
}