From 23f1a1eef9a2118dd943f58604847702237a7d1a Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sat, 27 Jun 2026 09:25:46 +0800 Subject: [PATCH] =?UTF-8?q?test(aot):=20=E6=B7=BB=E5=8A=A0=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=B0=83=E7=94=A8=E7=9B=B8=E5=85=B3=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E5=B9=B6=E4=BF=AE=E5=A4=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E6=96=B9=E6=B3=95=E9=87=8D=E5=86=99=E6=A3=80?= =?UTF-8?q?=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除测试文件中不必要的 use native_types 语句 - 新增 call-interface-method.phpt 测试接口方法调用功能 - 新增 call-magic-fallback-typed-object.phpt 测试魔法方法回调功能 - 新增 call-multilevel-override.phpt 测试多层级继承方法重写功能 - 新增 call-parent-sibling-dispatch.phpt 测试父类参数分发到兄弟类方法功能 - 新增 call-protected-override.phpt 测试受保护方法重写功能 - 添加命名空间重写键名使用完整类名的单元测试 - 添加 static 属性 array_pop 操作的调试测试用例 --- debug/ref.php | 60 +++++++++++++++++++ phpunit/src/ClassMethodOverrideTest.php | 20 +++++++ .../dynamic_call/call-abstract-method.phpt | 2 - .../dynamic_call/call-interface-method.phpt | 32 ++++++++++ .../call-magic-fallback-typed-object.phpt | 29 +++++++++ .../call-multilevel-override.phpt | 41 +++++++++++++ .../call-namespaced-parent-override.phpt | 2 - .../call-parent-return-override.phpt | 2 - .../call-parent-sibling-dispatch.phpt | 48 +++++++++++++++ .../dynamic_call/call-protected-override.phpt | 41 +++++++++++++ 10 files changed, 271 insertions(+), 6 deletions(-) create mode 100644 debug/ref.php create mode 100644 tests/aot/dynamic_call/call-interface-method.phpt create mode 100644 tests/aot/dynamic_call/call-magic-fallback-typed-object.phpt create mode 100644 tests/aot/dynamic_call/call-multilevel-override.phpt create mode 100644 tests/aot/dynamic_call/call-parent-sibling-dispatch.phpt create mode 100644 tests/aot/dynamic_call/call-protected-override.phpt diff --git a/debug/ref.php b/debug/ref.php new file mode 100644 index 00000000..9463b731 --- /dev/null +++ b/debug/ref.php @@ -0,0 +1,60 @@ +assertFalse($classMethodOverride[$childMethodLower], 'ChildOverride::bar should not be marked as overridden'); } + + public function testNamespacedOverrideKeysUseFullClassName(): void + { + $compiler = CompilerTest::create(ROOT_PATH); + $testFile = __DIR__ . '/../code/class-method-override-namespace.php'; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + + $ref = new ReflectionClass($compiler); + $prop = $ref->getProperty('classMethodOverride'); + $classMethodOverride = $prop->getValue($compiler); + + $parentMethodLower = strtolower('Demo\\Dispatch\\ParentBaseNs::bar'); + $childMethodLower = strtolower('Demo\\Dispatch\\ChildOverrideNs::bar'); + + $this->assertArrayHasKey($parentMethodLower, $classMethodOverride, 'Namespaced parent method should be registered with full class name'); + $this->assertArrayHasKey($childMethodLower, $classMethodOverride, 'Namespaced child method should be registered with full class name'); + $this->assertTrue($classMethodOverride[$parentMethodLower], 'Namespaced parent method should be marked as overridden'); + $this->assertFalse($classMethodOverride[$childMethodLower], 'Namespaced child method should not be marked as overridden'); + } } diff --git a/tests/aot/dynamic_call/call-abstract-method.phpt b/tests/aot/dynamic_call/call-abstract-method.phpt index 266ab369..9596d1c2 100644 --- a/tests/aot/dynamic_call/call-abstract-method.phpt +++ b/tests/aot/dynamic_call/call-abstract-method.phpt @@ -2,8 +2,6 @@ call abstract base method through concrete object --FILE-- run(); +} + +function main(): int +{ + $r = invoke(new FastRunner()); + echo "result: $r\n"; + return $r === 'fast' ? 0 : 1; +} +?> +--EXPECT-- +result: fast diff --git a/tests/aot/dynamic_call/call-magic-fallback-typed-object.phpt b/tests/aot/dynamic_call/call-magic-fallback-typed-object.phpt new file mode 100644 index 00000000..515b2292 --- /dev/null +++ b/tests/aot/dynamic_call/call-magic-fallback-typed-object.phpt @@ -0,0 +1,29 @@ +--TEST-- +missing method on typed object dispatches to __call +--FILE-- +missing('a', 'b'); +} + +function main(): int +{ + $r = invoke(new DynamicHandler()); + echo "result: $r\n"; + return $r === 'missing:a,b' ? 0 : 1; +} +?> +--EXPECT-- +result: missing:a,b diff --git a/tests/aot/dynamic_call/call-multilevel-override.phpt b/tests/aot/dynamic_call/call-multilevel-override.phpt new file mode 100644 index 00000000..0cb7fda4 --- /dev/null +++ b/tests/aot/dynamic_call/call-multilevel-override.phpt @@ -0,0 +1,41 @@ +--TEST-- +call method overridden in grandchild through base parameter +--FILE-- +value(); +} + +function main(): int +{ + $r = readValue(new Leaf()); + echo "result: $r\n"; + return $r === 'leaf' ? 0 : 1; +} +?> +--EXPECT-- +result: leaf diff --git a/tests/aot/dynamic_call/call-namespaced-parent-override.phpt b/tests/aot/dynamic_call/call-namespaced-parent-override.phpt index 91318641..0bf1dacb 100644 --- a/tests/aot/dynamic_call/call-namespaced-parent-override.phpt +++ b/tests/aot/dynamic_call/call-namespaced-parent-override.phpt @@ -3,8 +3,6 @@ call overridden method through namespaced parent type --FILE-- name(); +} + +function main(): int +{ + $left = readName(new Left()); + $right = readName(new Right()); + echo "left: $left\n"; + echo "right: $right\n"; + return $left === 'left' && $right === 'right' ? 0 : 1; +} +?> +--EXPECT-- +left: left +right: right diff --git a/tests/aot/dynamic_call/call-protected-override.phpt b/tests/aot/dynamic_call/call-protected-override.phpt new file mode 100644 index 00000000..2f794f4a --- /dev/null +++ b/tests/aot/dynamic_call/call-protected-override.phpt @@ -0,0 +1,41 @@ +--TEST-- +protected overridden method remains virtual through parent wrapper +--FILE-- +token(); + } +} + +class Child extends Base +{ + protected function token(): string + { + return 'child'; + } +} + +function main(): int +{ + $base = new Base(); + $child = new Child(); + $a = $base->expose(); + $b = $child->expose(); + echo "base: $a\n"; + echo "child: $b\n"; + return $a === 'base' && $b === 'child' ? 0 : 1; +} +?> +--EXPECT-- +base: base +child: child