aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/src/SpecTestsuites/CoreTest.php
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-04-27 18:53:27 +0900
committernsfisis <nsfisis@gmail.com>2024-04-28 01:02:35 +0900
commitd8da7b5db06e28e55b52a3b46e920ea3be64f120 (patch)
tree8a1772f2b4d5c9c35146e7a8f19341e7fa0a7798 /tests/src/SpecTestsuites/CoreTest.php
parent25ad2004c1d786a1dbe42d24c08f228c870210a4 (diff)
downloadphp-waddiwasi-d8da7b5db06e28e55b52a3b46e920ea3be64f120.tar.gz
php-waddiwasi-d8da7b5db06e28e55b52a3b46e920ea3be64f120.tar.zst
php-waddiwasi-d8da7b5db06e28e55b52a3b46e920ea3be64f120.zip
feat: introduce PHPUnit
Diffstat (limited to 'tests/src/SpecTestsuites/CoreTest.php')
-rw-r--r--tests/src/SpecTestsuites/CoreTest.php531
1 files changed, 531 insertions, 0 deletions
diff --git a/tests/src/SpecTestsuites/CoreTest.php b/tests/src/SpecTestsuites/CoreTest.php
new file mode 100644
index 0000000..75d4c2f
--- /dev/null
+++ b/tests/src/SpecTestsuites/CoreTest.php
@@ -0,0 +1,531 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Nsfisis\Waddiwasi\Tests\SpecTestsuites;
+
+use Nsfisis\Waddiwasi\BinaryFormat\Decoder;
+use Nsfisis\Waddiwasi\Execution\Runtime;
+use Nsfisis\Waddiwasi\Execution\Store;
+use PHPUnit\Framework\TestCase;
+use function count;
+
+final class CoreTest extends TestCase
+{
+ public function testAddress(): void
+ {
+ $this->runSpecTestsuite('address');
+ }
+
+ public function testAlign(): void
+ {
+ $this->runSpecTestsuite('align');
+ }
+
+ public function testBinaryLeb128(): void
+ {
+ $this->runSpecTestsuite('binary-leb128');
+ }
+
+ public function testBinary(): void
+ {
+ $this->runSpecTestsuite('binary');
+ }
+
+ public function testBlock(): void
+ {
+ $this->runSpecTestsuite('block');
+ }
+
+ public function testBr(): void
+ {
+ $this->runSpecTestsuite('br');
+ }
+
+ public function testBrIf(): void
+ {
+ $this->runSpecTestsuite('br_if');
+ }
+
+ public function testBrTable(): void
+ {
+ $this->runSpecTestsuite('br_table');
+ }
+
+ public function testBulk(): void
+ {
+ $this->runSpecTestsuite('bulk');
+ }
+
+ public function testCall(): void
+ {
+ $this->runSpecTestsuite('call');
+ }
+
+ public function testCallIndirect(): void
+ {
+ $this->runSpecTestsuite('call_indirect');
+ }
+
+ public function testConst(): void
+ {
+ $this->runSpecTestsuite('const');
+ }
+
+ public function testConversions(): void
+ {
+ $this->runSpecTestsuite('conversions');
+ }
+
+ public function testCustom(): void
+ {
+ $this->runSpecTestsuite('custom');
+ }
+
+ public function testData(): void
+ {
+ $this->runSpecTestsuite('data');
+ }
+
+ public function testElem(): void
+ {
+ $this->runSpecTestsuite('elem');
+ }
+
+ public function testEndianness(): void
+ {
+ $this->runSpecTestsuite('endianness');
+ }
+
+ public function testExports(): void
+ {
+ $this->runSpecTestsuite('exports');
+ }
+
+ public function testF32(): void
+ {
+ $this->runSpecTestsuite('f32');
+ }
+
+ public function testF32Bitwise(): void
+ {
+ $this->runSpecTestsuite('f32_bitwise');
+ }
+
+ public function testF32Cmp(): void
+ {
+ $this->runSpecTestsuite('f32_cmp');
+ }
+
+ public function testF64(): void
+ {
+ $this->runSpecTestsuite('f64');
+ }
+
+ public function testF64Bitwise(): void
+ {
+ $this->runSpecTestsuite('f64_bitwise');
+ }
+
+ public function testF64Cmp(): void
+ {
+ $this->runSpecTestsuite('f64_cmp');
+ }
+
+ public function testFac(): void
+ {
+ $this->runSpecTestsuite('fac');
+ }
+
+ public function testFloatExprs(): void
+ {
+ $this->runSpecTestsuite('float_exprs');
+ }
+
+ public function testFloatLiterals(): void
+ {
+ $this->runSpecTestsuite('float_literals');
+ }
+
+ public function testFloatMemory(): void
+ {
+ $this->runSpecTestsuite('float_memory');
+ }
+
+ public function testFloatMisc(): void
+ {
+ $this->runSpecTestsuite('float_misc');
+ }
+
+ public function testForward(): void
+ {
+ $this->runSpecTestsuite('forward');
+ }
+
+ public function testFunc(): void
+ {
+ $this->runSpecTestsuite('func');
+ }
+
+ public function testFuncPtrs(): void
+ {
+ $this->runSpecTestsuite('func_ptrs');
+ }
+
+ public function testGlobal(): void
+ {
+ $this->runSpecTestsuite('global');
+ }
+
+ public function testI32(): void
+ {
+ $this->runSpecTestsuite('i32');
+ }
+
+ public function testI64(): void
+ {
+ $this->runSpecTestsuite('i64');
+ }
+
+ public function testIf(): void
+ {
+ $this->runSpecTestsuite('if');
+ }
+
+ public function testImports(): void
+ {
+ $this->runSpecTestsuite('imports');
+ }
+
+ public function testInlineModule(): void
+ {
+ $this->runSpecTestsuite('inline-module');
+ }
+
+ public function testIntExprs(): void
+ {
+ $this->runSpecTestsuite('int_exprs');
+ }
+
+ public function testIntLiterals(): void
+ {
+ $this->runSpecTestsuite('int_literals');
+ }
+
+ public function testLabels(): void
+ {
+ $this->runSpecTestsuite('labels');
+ }
+
+ public function testLeftToRight(): void
+ {
+ $this->runSpecTestsuite('left-to-right');
+ }
+
+ public function testLinking(): void
+ {
+ $this->runSpecTestsuite('linking');
+ }
+
+ public function testLoad(): void
+ {
+ $this->runSpecTestsuite('load');
+ }
+
+ public function testLocalGet(): void
+ {
+ $this->runSpecTestsuite('local_get');
+ }
+
+ public function testLocalSet(): void
+ {
+ $this->runSpecTestsuite('local_set');
+ }
+
+ public function testLocalTee(): void
+ {
+ $this->runSpecTestsuite('local_tee');
+ }
+
+ public function testLoop(): void
+ {
+ $this->runSpecTestsuite('loop');
+ }
+
+ public function testMemory(): void
+ {
+ $this->runSpecTestsuite('memory');
+ }
+
+ public function testMemoryCopy(): void
+ {
+ $this->runSpecTestsuite('memory_copy');
+ }
+
+ public function testMemoryFill(): void
+ {
+ $this->runSpecTestsuite('memory_fill');
+ }
+
+ public function testMemoryGrow(): void
+ {
+ $this->runSpecTestsuite('memory_grow');
+ }
+
+ public function testMemoryInit(): void
+ {
+ $this->runSpecTestsuite('memory_init');
+ }
+
+ public function testMemoryRedundancy(): void
+ {
+ $this->runSpecTestsuite('memory_redundancy');
+ }
+
+ public function testMemorySize(): void
+ {
+ $this->runSpecTestsuite('memory_size');
+ }
+
+ public function testMemoryTrap(): void
+ {
+ $this->runSpecTestsuite('memory_trap');
+ }
+
+ public function testNames(): void
+ {
+ $this->runSpecTestsuite('names');
+ }
+
+ public function testNop(): void
+ {
+ $this->runSpecTestsuite('nop');
+ }
+
+ public function testObsoleteKeywords(): void
+ {
+ $this->runSpecTestsuite('obsolete-keywords');
+ }
+
+ public function testRefFunc(): void
+ {
+ $this->runSpecTestsuite('ref_func');
+ }
+
+ public function testRefIsNull(): void
+ {
+ $this->runSpecTestsuite('ref_is_null');
+ }
+
+ public function testRefNull(): void
+ {
+ $this->runSpecTestsuite('ref_null');
+ }
+
+ public function testReturn(): void
+ {
+ $this->runSpecTestsuite('return');
+ }
+
+ public function testSelect(): void
+ {
+ $this->runSpecTestsuite('select');
+ }
+
+ public function testSkipStackGuardPage(): void
+ {
+ $this->runSpecTestsuite('skip-stack-guard-page');
+ }
+
+ public function testStack(): void
+ {
+ $this->runSpecTestsuite('stack');
+ }
+
+ public function testStart(): void
+ {
+ $this->runSpecTestsuite('start');
+ }
+
+ public function testStore(): void
+ {
+ $this->runSpecTestsuite('store');
+ }
+
+ public function testSwitch(): void
+ {
+ $this->runSpecTestsuite('switch');
+ }
+
+ public function testTableSub(): void
+ {
+ $this->runSpecTestsuite('table-sub');
+ }
+
+ public function testTable(): void
+ {
+ $this->runSpecTestsuite('table');
+ }
+
+ public function testTableCopy(): void
+ {
+ $this->runSpecTestsuite('table_copy');
+ }
+
+ public function testTableFill(): void
+ {
+ $this->runSpecTestsuite('table_fill');
+ }
+
+ public function testTableGet(): void
+ {
+ $this->runSpecTestsuite('table_get');
+ }
+
+ public function testTableGrow(): void
+ {
+ $this->runSpecTestsuite('table_grow');
+ }
+
+ public function testTableInit(): void
+ {
+ $this->runSpecTestsuite('table_init');
+ }
+
+ public function testTableSet(): void
+ {
+ $this->runSpecTestsuite('table_set');
+ }
+
+ public function testTableSize(): void
+ {
+ $this->runSpecTestsuite('table_size');
+ }
+
+ public function testToken(): void
+ {
+ $this->runSpecTestsuite('token');
+ }
+
+ public function testTraps(): void
+ {
+ $this->runSpecTestsuite('traps');
+ }
+
+ public function testType(): void
+ {
+ $this->runSpecTestsuite('type');
+ }
+
+ public function testUnreachable(): void
+ {
+ $this->runSpecTestsuite('unreachable');
+ }
+
+ public function testUnreachedInvalid(): void
+ {
+ $this->runSpecTestsuite('unreached-invalid');
+ }
+
+ public function testUnreachedValid(): void
+ {
+ $this->runSpecTestsuite('unreached-valid');
+ }
+
+ public function testUnwind(): void
+ {
+ $this->runSpecTestsuite('unwind');
+ }
+
+ public function testUtf8CustomSectionId(): void
+ {
+ $this->runSpecTestsuite('utf8-custom-section-id');
+ }
+
+ public function testUtf8ImportField(): void
+ {
+ $this->runSpecTestsuite('utf8-import-field');
+ }
+
+ public function testUtf8ImportModule(): void
+ {
+ $this->runSpecTestsuite('utf8-import-module');
+ }
+
+ public function testUtf8InvalidEncoding(): void
+ {
+ $this->runSpecTestsuite('utf8-invalid-encoding');
+ }
+
+ private function runSpecTestsuite(string $testsuiteName): void
+ {
+ $baseDir = __DIR__ . '/../../fixtures/spec_testsuites/core';
+ $testsuiteDefinitionFileContent = file_get_contents("$baseDir/$testsuiteName.json");
+ $testsuiteDefinition = json_decode($testsuiteDefinitionFileContent, true);
+
+ $commands = $testsuiteDefinition['commands'];
+ $modules = [];
+ $runtimes = [];
+ foreach ($commands as $command) {
+ switch ($command['type']) {
+ case 'module':
+ $filename = $command['filename'];
+ $moduleName = $command['name'] ?? '_';
+ $filePath = "$baseDir/$filename";
+ $wasmBinary = file_get_contents($filePath);
+ $module = (new Decoder($wasmBinary))->decode();
+ $modules[$moduleName] = $module;
+ $runtime = Runtime::instantiate(Store::empty(), $module, []);
+ $runtimes[$moduleName] = $runtime;
+ break;
+ case 'action':
+ break;
+ case 'assert_exhaustion':
+ break;
+ case 'assert_invalid':
+ break;
+ case 'assert_malformed':
+ break;
+ case 'assert_return':
+ $targetModuleName = $command['module'] ?? '_';
+ $targetModule = $modules[$targetModuleName];
+ $expectedResults = $command['expected'];
+ $action = $command['action'];
+ $actionType = $action['type'];
+ $actionField = $action['field'];
+ if ($actionType === 'invoke') {
+ $actionArgs = $action['args'];
+ $runtime = $runtimes[$targetModuleName];
+ if (count($actionArgs) === 0) {
+ $actualResults = $runtime->invoke($actionField, []);
+ $this->assertCount(count($expectedResults), $actualResults, "at $command[line]");
+ for ($i = 0; $i < count($expectedResults); $i++) {
+ $expectedResult = $expectedResults[$i];
+ $actualResult = $actualResults[$i];
+ if ($expectedResult['type'] === 'f32') {
+ $expectedValue = unpack('g', pack('l', (int)$expectedResult['value']))[1];
+ $this->assertSame($expectedValue, $actualResult, "at $command[line]");
+ } elseif ($expectedResult['type'] === 'f64') {
+ $expectedValue = unpack('e', pack('q', (int)$expectedResult['value']))[1];
+ $this->assertSame($expectedValue, $actualResult, "at $command[line]");
+ } else {
+ $expectedValue = (int)$expectedResult['value'];
+ $this->assertSame($expectedValue, $actualResult, "at $command[line]");
+ }
+ }
+ }
+ } else {
+ }
+ break;
+ case 'assert_trap':
+ break;
+ case 'assert_uninstantiable':
+ break;
+ case 'assert_unlinkable':
+ break;
+ case 'register':
+ break;
+ }
+ }
+ }
+}