diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-04-28 11:02:51 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-04-28 17:38:19 +0900 |
| commit | 88a77bc5846541e5d6009bc103da378650a649f3 (patch) | |
| tree | ef4d3a57cc16bf230c3ac25068001f747e45b35e /tools | |
| parent | c809cd661bba388d531f24c2ac578fbe6594f45c (diff) | |
| download | php-waddiwasi-88a77bc5846541e5d6009bc103da378650a649f3.tar.gz php-waddiwasi-88a77bc5846541e5d6009bc103da378650a649f3.tar.zst php-waddiwasi-88a77bc5846541e5d6009bc103da378650a649f3.zip | |
test: generate PHPUnit classes from WAST files
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/json2phpunit.php | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/tools/json2phpunit.php b/tools/json2phpunit.php new file mode 100644 index 0000000..648f6fd --- /dev/null +++ b/tools/json2phpunit.php @@ -0,0 +1,252 @@ +<?php + +declare(strict_types=1); + +namespace Nsfsisis\Waddiwasi\Tools; + +use function array_is_list; +use function array_keys; +use function array_map; +use function basename; +use function count; +use function explode; +use function fclose; +use function file_get_contents; +use function fopen; +use function fwrite; +use function glob; +use function implode; +use function is_array; +use function is_int; +use function is_null; +use function is_string; +use function json_decode; +use function strtr; +use function ucfirst; + +$wastJsonBaseDir = __DIR__ . '/../tests/fixtures/spec_testsuites/core'; +$phpUnitBaseDir = __DIR__ . '/../tests/src/SpecTestsuites/Core'; + +$wastJsonFiles = glob("$wastJsonBaseDir/*.json", GLOB_ERR); + +foreach ($wastJsonFiles as $wastJsonFile) { + $wastJsonFileContent = file_get_contents($wastJsonFile); + $wastJson = json_decode($wastJsonFileContent, associative: true); + $sourceFilename = $wastJson['source_filename'] ?? null; + $commands = $wastJson['commands'] ?? null; + + $className = wastJsonFileToPascalCase($wastJsonFile) . 'Test'; + + $fp = fopen("$phpUnitBaseDir/$className.php", 'w'); + + fwrite($fp, "<?php\n\n"); + fwrite($fp, "declare(strict_types=1);\n\n"); + fwrite($fp, "namespace Nsfisis\\Waddiwasi\\Tests\\SpecTestsuites\\Core;\n\n"); + fwrite($fp, "use Nsfisis\\Waddiwasi\\Tests\\SpecTestsuites\\SpecTestsuiteBase;\n"); + fwrite($fp, "use PHPUnit\\Framework\\Attributes\\Depends;\n"); + fwrite($fp, "use PHPUnit\\Framework\\Attributes\\DoesNotPerformAssertions;\n\n"); + fwrite($fp, "final class $className extends SpecTestsuiteBase\n"); + fwrite($fp, "{\n"); + + $prevMethodName = null; + foreach ($commands as $i => $command) { + $type = $command['type']; + $line = $command['line']; + $methodName = 'test' . implode('', array_map(ucfirst(...), explode('_', $type))) . $i; + + $commandTest = match ($type) { + 'module' => buildModuleCommandTest($command), + 'assert_return' => buildAssertReturnCommandTest($command), + 'assert_trap' => buildAssertTrapCommandTest($command), + 'assert_malformed' => buildAssertMalformedCommandTest($command), + 'assert_invalid' => buildAssertInvalidCommandTest($command), + 'assert_exhaustion' => buildAssertExhaustionCommandTest($command), + 'assert_uninstantiable' => buildAssertUninstantiableCommandTest($command), + 'assert_unlinkable' => buildAssertUnlinkableCommandTest($command), + 'action' => buildActionCommandTest($command), + 'register' => buildRegisterCommandTest($command), + }; + if ($commandTest === null) { + fwrite($fp, " #[DoesNotPerformAssertions]\n"); + } + if ($prevMethodName !== null) { + fwrite($fp, " #[Depends('$prevMethodName')]\n"); + } + fwrite($fp, " public function $methodName(): void\n"); + fwrite($fp, " {\n"); + + if ($commandTest !== null) { + fwrite($fp, " \$this->{$commandTest['method']}(\n"); + foreach ($commandTest['args'] as $argName => $argValue) { + $argValue = toPhpLiteral($argValue); + fwrite($fp, " $argName: $argValue,\n"); + } + fwrite($fp, " line: $line,\n"); + fwrite($fp, " );\n"); + } + + fwrite($fp, " }\n"); + if ($i !== count($commands) - 1) { + fwrite($fp, "\n"); + } + $prevMethodName = $methodName; + } + + fwrite($fp, "}\n"); + fclose($fp); +} + +function wastJsonFileToPascalCase(string $s): string +{ + $s = strtr(basename($s), ['.json' => '', '-' => '_']); + return implode('', array_map(ucfirst(...), explode('_', $s))); +} + +function buildModuleCommandTest(array $command): array +{ + return [ + 'method' => 'runModuleCommand', + 'args' => [ + 'filename' => $command['filename'], + 'name' => $command['name'] ?? null, + ], + ]; +} + +function buildAssertReturnCommandTest(array $command): array +{ + return [ + 'method' => 'runAssertReturnCommand', + 'args' => [ + 'module' => $command['module'] ?? null, + 'action' => $command['action'], + 'expected' => $command['expected'], + ], + ]; +} + +function buildAssertTrapCommandTest(array $command): array +{ + return [ + 'method' => 'runAssertTrapCommand', + 'args' => [ + 'module' => $command['module'] ?? null, + 'action' => $command['action'], + 'text' => $command['text'], + ], + ]; +} + +function buildAssertMalformedCommandTest(array $command): ?array +{ + $moduleType = $command['module_type']; + if ($moduleType === 'text') { + // Our interpreter does not support text format (.wat format). + return null; + } + return [ + 'method' => 'runAssertMalformedCommand', + 'args' => [ + 'filename' => $command['filename'], + 'text' => $command['text'], + ], + ]; +} + +function buildAssertInvalidCommandTest(array $command): ?array +{ + $moduleType = $command['module_type']; + if ($moduleType === 'text') { + // Our interpreter does not support text format (.wat format). + return null; + } + return [ + 'method' => 'runAssertInvalidCommand', + 'args' => [ + 'filename' => $command['filename'], + 'text' => $command['text'], + ], + ]; +} + +function buildAssertExhaustionCommandTest(array $command): array +{ + return [ + 'method' => 'runAssertExhaustionCommand', + 'args' => [ + 'action' => $command['action'], + 'text' => $command['text'], + ], + ]; +} + +function buildAssertUninstantiableCommandTest(array $command): ?array +{ + $moduleType = $command['module_type']; + if ($moduleType === 'text') { + // Our interpreter does not support text format (.wat format). + return null; + } + return [ + 'method' => 'runAssertUninstantiableCommand', + 'args' => [ + 'filename' => $command['filename'], + 'text' => $command['text'], + ], + ]; +} + +function buildAssertUnlinkableCommandTest(array $command): ?array +{ + $moduleType = $command['module_type']; + if ($moduleType === 'text') { + // Our interpreter does not support text format (.wat format). + return null; + } + return [ + 'method' => 'runAssertUnlinkableCommand', + 'args' => [ + 'filename' => $command['filename'], + 'text' => $command['text'], + ], + ]; +} + +function buildActionCommandTest(array $command): array +{ + return [ + 'method' => 'runActionCommand', + 'args' => [ + 'action' => $command['action'], + ], + ]; +} + +function buildRegisterCommandTest(array $command): array +{ + return [ + 'method' => 'runRegisterCommand', + 'args' => [ + 'name' => $command['name'] ?? null, + 'as' => $command['as'], + ], + ]; +} + +function toPhpLiteral(mixed $value): string +{ + if (is_null($value)) { + return 'null'; + } elseif (is_int($value)) { + return $value; + } elseif (is_string($value)) { + $value = strtr($value, ["\\" => "\\\\", "'" => "\\'"]); + return "'$value'"; + } elseif (is_array($value) && array_is_list($value)) { + return '[' . implode(', ', array_map(toPhpLiteral(...), $value)) . ']'; + } elseif (is_array($value)) { + return '[' . implode(', ', array_map(fn ($k) => "'$k' => " . toPhpLiteral($value[$k]), array_keys($value))) . ']'; + } else { + return 'ERROR'; + } +} |
