From 4ca0c595b7100dcc1e9acd37e7d69a1f5aa591ba Mon Sep 17 00:00:00 2001 From: Matheus Martins Date: Fri, 24 Jul 2026 10:13:53 +0000 Subject: [PATCH] test: make compile-fixture verify files explicit typed closures Each executable verify file under test/fixture/compile/*/verify/ relied on an implicit, untyped $fixture variable being in the enclosing test method's scope at the point of `require`. The dependency was invisible from the file, untyped, and enforced only by a docblock convention across 26 driver methods. Each verify file now returns a `function (CompiledFixture $fixture): void` that runs its assertions when invoked, and each driver calls it explicitly: $runtime = require __DIR__ . '/.../verify/runtime.php'; $runtime($fixture); The fixture dependency is now an explicit typed parameter. Behavior is unchanged: the inner `require $fixture->targetDir . '/Use.php'` still runs in the closure scope (so locals like $result are produced as before), assertion failures still propagate through the invocation, and the try/finally still cleans up the temp dir. Also drop the decorative `echo "OK\n"` lines from the 11 files that had them: stdout is never inspected, so the `Assert::` calls already signal pass/fail. Co-Authored-By: Claude Opus 4.8 (1M context) --- test/TestSupport/CompiledFixture.php | 15 +++- .../ArraySugarIntegrationTest.php | 6 +- .../Monomorphize/ArrowSpecializationTest.php | 21 +++-- .../BoundedGenericIntegrationTest.php | 3 +- .../BuiltinInterfaceViaUseIntegrationTest.php | 3 +- .../Monomorphize/ClosureArrowDefaultsTest.php | 12 ++- .../ClosureConformanceIntegrationTest.php | 36 +++++--- .../ClosureDispatcherIntegrationTest.php | 9 +- .../DefaultedGenericIntegrationTest.php | 3 +- .../DispatcherFixtureIntegrationTest.php | 9 +- .../EnclosingParamBoundIntegrationTest.php | 42 ++++++--- .../Monomorphize/FreeSymbolRequalifyTest.php | 12 ++- .../GenericExceptionCatchIntegrationTest.php | 3 +- .../GenericFunctionIntegrationTest.php | 6 +- .../GenericInterfaceIntegrationTest.php | 3 +- .../GenericMethodIntegrationTest.php | 24 +++-- .../GenericTraitAdaptationTest.php | 6 +- .../GroupImportClassRequalifyTest.php | 3 +- .../KeywordNamedGenericMethodTest.php | 6 +- .../MarkerAlignmentIntegrationTest.php | 12 ++- .../MultiTypeGenericsIntegrationTest.php | 3 +- .../NestedGenericsIntegrationTest.php | 3 +- .../QualifiedCallSiteIntegrationTest.php | 9 +- .../UseClosureSpecializationTest.php | 15 ++-- .../UseImportGenericClauseTest.php | 3 +- .../VarianceEdgeIntegrationTest.php | 12 ++- .../array_sugar/verify/nullable_return.php | 47 +++++----- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 9 +- .../verify/runtime.php | 7 +- .../arrow_defaults_single/verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 7 +- .../arrow_no_captures/verify/runtime.php | 7 +- .../verify/runtime.php | 7 +- .../verify/runtime.php | 7 +- .../verify/runtime.php | 17 ++-- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 87 ++++++++++--------- .../verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 25 +++--- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 23 ++--- .../verify/runtime.php | 9 +- .../verify/runtime.php | 25 +++--- .../verify/runtime.php | 9 +- .../verify/runtime.php | 9 +- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 23 ++--- .../verify/runtime.php | 15 ++-- .../verify/runtime.php | 23 ++--- .../closure_use_by_ref/verify/runtime.php | 11 ++- .../closure_use_by_value/verify/runtime.php | 11 ++- .../verify/runtime.php | 9 +- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 12 +-- .../verify/runtime.php | 16 ++-- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 10 ++- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 9 +- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 9 +- .../verify/runtime.php | 10 ++- .../verify/runtime.php | 10 ++- .../verify/runtime.php | 12 +-- .../verify/runtime.php | 10 ++- .../verify/runtime.php | 11 ++- .../free_symbol_requalify/verify/runtime.php | 17 ++-- .../free_symbol_use_import/verify/runtime.php | 11 ++- .../verify/runtime.php | 43 ++++----- .../verify/runtime.php | 69 ++++++++------- .../verify/catch_runtime.php | 71 +++++++-------- .../verify/runtime_execution.php | 23 ++--- .../verify/runtime.php | 13 +-- .../verify/specialized_interface_runtime.php | 37 ++++---- .../compile/generic_method/verify/runtime.php | 27 +++--- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 23 ++--- .../verify/runtime.php | 23 ++--- .../verify/runtime.php | 25 +++--- .../verify/runtime.php | 13 +-- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 15 ++-- .../verify/runtime.php | 15 ++-- .../verify/runtime.php | 15 ++-- .../verify/runtime.php | 17 ++-- .../verify/runtime.php | 11 ++- .../verify/runtime.php | 13 +-- .../verify/type_error_on_wrong_slot.php | 47 +++++----- .../verify/runtime.php | 17 ++-- .../verify/nested_specialization_runtime.php | 45 +++++----- .../verify/runtime.php | 33 +++---- .../verify/runtime.php | 29 ++++--- .../verify/runtime.php | 25 +++--- .../same_line_marker_pairs/verify/runtime.php | 33 +++---- .../verify/runtime.php | 21 +++-- .../verify/runtime.php | 19 ++-- .../turbofish_fcc_closure/verify/runtime.php | 21 +++-- .../use_trait_generic/verify/runtime.php | 9 +- .../verify/runtime.php | 11 ++- 114 files changed, 1100 insertions(+), 748 deletions(-) diff --git a/test/TestSupport/CompiledFixture.php b/test/TestSupport/CompiledFixture.php index da94f7e2..3c21b423 100644 --- a/test/TestSupport/CompiledFixture.php +++ b/test/TestSupport/CompiledFixture.php @@ -31,16 +31,23 @@ * `#[RunInSeparateProcess]` (or use `setUpBeforeClass` for an entire * `TestCase` that shares one fixture across methods). * - * Failure attribution: when a verify file calls `Assert::*` and it - * fails, the exception's throw site is the verify file (`path:line`), - * and the `require` frame is the calling `testFoo` method — PHPUnit + * Verify contract: a verify file `return`s a + * `function (CompiledFixture $fixture): void` that runs its `Assert::*` + * calls when invoked, so the fixture dependency is an explicit typed + * parameter rather than an implicit in-scope variable. The driver + * loads the closure with `require` and calls it with the fixture. + * + * Failure attribution: when a verify file's `Assert::*` fails, the + * exception's throw site is the verify file (`path:line`), and the + * closure-invocation frame is the calling `testFoo` method — PHPUnit * reports both. * * Usage: * $fixture = CompiledFixture::compile($sourceDir, 'array-sugar'); * $fixture->registerAutoload('App\\ArraySugar\\'); * try { - * require __DIR__ . '/../../fixture/compile/array_sugar/verify/foo.php'; + * $runtime = require __DIR__ . '/../../fixture/compile/array_sugar/verify/foo.php'; + * $runtime($fixture); * } finally { * $fixture->cleanup(); * } diff --git a/test/Transpiler/Monomorphize/ArraySugarIntegrationTest.php b/test/Transpiler/Monomorphize/ArraySugarIntegrationTest.php index 2891da61..62a04f74 100644 --- a/test/Transpiler/Monomorphize/ArraySugarIntegrationTest.php +++ b/test/Transpiler/Monomorphize/ArraySugarIntegrationTest.php @@ -84,7 +84,8 @@ public function testNullableReturnEnforcesConcreteType(): void $fixture = CompiledFixture::compile($this->sourceDir, 'array-sugar-verify'); $fixture->registerAutoload('App\\ArraySugar\\'); try { - require __DIR__ . '/../../fixture/compile/array_sugar/verify/nullable_return.php'; + $runtime = require __DIR__ . '/../../fixture/compile/array_sugar/verify/nullable_return.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -104,7 +105,8 @@ public function testSugarBeforeGenericClosureStillSpecializes(): void ?: throw new RuntimeException('Fixture missing'); $fixture = CompiledFixture::compile($source, 'array-sugar-marker-offset'); try { - require __DIR__ . '/../../fixture/compile/array_sugar_before_generic_closure/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/array_sugar_before_generic_closure/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/ArrowSpecializationTest.php b/test/Transpiler/Monomorphize/ArrowSpecializationTest.php index a556447b..5ac16b78 100644 --- a/test/Transpiler/Monomorphize/ArrowSpecializationTest.php +++ b/test/Transpiler/Monomorphize/ArrowSpecializationTest.php @@ -94,7 +94,8 @@ public function testArrowSpecializationEndToEndSingleCapture(): void 'arrow-capture', ); try { - require __DIR__ . '/../../fixture/compile/arrow_capture_at_declaration/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_capture_at_declaration/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -108,7 +109,8 @@ public function testArrowSpecializationEndToEndMultipleCaptures(): void 'arrow-multi', ); try { - require __DIR__ . '/../../fixture/compile/arrow_multiple_captures/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_multiple_captures/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -122,7 +124,8 @@ public function testArrowSpecializationEndToEndNoCaptures(): void 'arrow-empty', ); try { - require __DIR__ . '/../../fixture/compile/arrow_no_captures/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_no_captures/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -138,7 +141,8 @@ public function testArrowSpecializationCaptureShadowingParamName(): void 'arrow-shadow', ); try { - require __DIR__ . '/../../fixture/compile/arrow_capture_shadowing/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_capture_shadowing/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -164,7 +168,8 @@ public function testArrowSpecializationMultipleArgTuples(): void $out, ); - require __DIR__ . '/../../fixture/compile/arrow_multiple_arg_tuples/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_multiple_arg_tuples/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -218,7 +223,8 @@ public function testArrowSpecializationReservedArgsCaptureAlsoTriggersRename(): $out, ); - require __DIR__ . '/../../fixture/compile/arrow_reserved_args_capture/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_reserved_args_capture/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -250,7 +256,8 @@ public function testArrowSpecializationReservedCaptureAutoRenamesDispatcherParam $out, ); - require __DIR__ . '/../../fixture/compile/arrow_reserved_tag_capture/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_reserved_tag_capture/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/BoundedGenericIntegrationTest.php b/test/Transpiler/Monomorphize/BoundedGenericIntegrationTest.php index cd88684c..a5f6dfbe 100644 --- a/test/Transpiler/Monomorphize/BoundedGenericIntegrationTest.php +++ b/test/Transpiler/Monomorphize/BoundedGenericIntegrationTest.php @@ -428,7 +428,8 @@ public function testScalarAliasClassTypeArgumentsResolveAndRunAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/scalar_alias_class_resolves/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/scalar_alias_class_resolves/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/BuiltinInterfaceViaUseIntegrationTest.php b/test/Transpiler/Monomorphize/BuiltinInterfaceViaUseIntegrationTest.php index 0981453b..df4db297 100644 --- a/test/Transpiler/Monomorphize/BuiltinInterfaceViaUseIntegrationTest.php +++ b/test/Transpiler/Monomorphize/BuiltinInterfaceViaUseIntegrationTest.php @@ -139,7 +139,8 @@ public function testSpecializedClassLoadsAndResolvesBuiltinsAtRuntime(): void $fixture = CompiledFixture::compile($this->sourceDir, 'builtin-via-use-runtime'); $fixture->registerAutoload('App\\BuiltinViaUse\\'); try { - require __DIR__ . '/../../fixture/compile/builtin_interface_via_use/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/builtin_interface_via_use/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/ClosureArrowDefaultsTest.php b/test/Transpiler/Monomorphize/ClosureArrowDefaultsTest.php index 78c3bccb..a41b97c3 100644 --- a/test/Transpiler/Monomorphize/ClosureArrowDefaultsTest.php +++ b/test/Transpiler/Monomorphize/ClosureArrowDefaultsTest.php @@ -29,7 +29,8 @@ public function testClosureWithSingleDefaultUsesPadding(): void 'cdef-single', ); try { - require __DIR__ . '/../../fixture/compile/closure_defaults_single/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_defaults_single/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -43,7 +44,8 @@ public function testArrowWithSingleDefaultUsesPadding(): void 'adef-single', ); try { - require __DIR__ . '/../../fixture/compile/arrow_defaults_single/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_defaults_single/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -135,7 +137,8 @@ public function testDefaultOnClosureWithUseClause(): void 'cdef-use', ); try { - require __DIR__ . '/../../fixture/compile/closure_defaults_with_use/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_defaults_with_use/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -150,7 +153,8 @@ public function testDefaultOnArrowWithImplicitCapture(): void 'adef-cap', ); try { - require __DIR__ . '/../../fixture/compile/arrow_defaults_with_implicit_capture/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/arrow_defaults_with_implicit_capture/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/ClosureConformanceIntegrationTest.php b/test/Transpiler/Monomorphize/ClosureConformanceIntegrationTest.php index 6c563967..a0e44f69 100644 --- a/test/Transpiler/Monomorphize/ClosureConformanceIntegrationTest.php +++ b/test/Transpiler/Monomorphize/ClosureConformanceIntegrationTest.php @@ -25,7 +25,8 @@ public function testConformingClosuresCompileEraseAndRun(): void 'closure-conformance-run', ); try { - require __DIR__ . '/../../fixture/compile/closure_conformance_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_conformance_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -43,7 +44,8 @@ public function testDnfGroupedSignaturesCompileEraseAndRun(): void 'closure-conformance-dnf', ); try { - require __DIR__ . '/../../fixture/compile/closure_conformance_dnf_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_conformance_dnf_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -61,7 +63,8 @@ public function testUserFunctionNamedClosureInExpressionColonsExecutes(): void 'closure-named-user-fn', ); try { - require __DIR__ . '/../../fixture/compile/closure_named_user_function_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_named_user_function_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -78,7 +81,8 @@ public function testArraySugarSignaturesCompileEraseAndRun(): void 'closure-conformance-sugar', ); try { - require __DIR__ . '/../../fixture/compile/closure_conformance_array_sugar_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_conformance_array_sugar_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -96,7 +100,8 @@ public function testExceptionFactoryAgainstBuiltinThrowableTargetCompilesAndRuns ); $fixture->registerAutoload('App\\ClosureBuiltinOk\\'); try { - require __DIR__ . '/../../fixture/compile/closure_conformance_builtin_ok/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_conformance_builtin_ok/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -124,7 +129,8 @@ public function testConformingClosureArgumentCompilesEraseAndRuns(): void ); $fixture->registerAutoload('App\\ClosureArgRun\\'); try { - require __DIR__ . '/../../fixture/compile/closure_arg_instance_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_arg_instance_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -152,7 +158,8 @@ public function testConformingStaticClosureArgumentCompilesEraseAndRuns(): void ); $fixture->registerAutoload('App\\ClosureArgStaticRun\\'); try { - require __DIR__ . '/../../fixture/compile/closure_arg_static_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_arg_static_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -180,7 +187,8 @@ public function testConformingFreeFunctionClosureArgumentCompilesEraseAndRuns(): ); $fixture->registerAutoload('App\\ClosureArgFnRun\\'); try { - require __DIR__ . '/../../fixture/compile/closure_arg_free_fn_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_arg_free_fn_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -208,7 +216,8 @@ public function testConformingPlainMethodClosureArgumentCompilesEraseAndRuns(): ); $fixture->registerAutoload('App\\PlainArgRun\\'); try { - require __DIR__ . '/../../fixture/compile/closure_arg_plain_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_arg_plain_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -236,7 +245,8 @@ public function testConformingPlainFreeFunctionClosureArgumentCompilesEraseAndRu ); $fixture->registerAutoload('App\\PlainFnArgRun\\'); try { - require __DIR__ . '/../../fixture/compile/closure_arg_plain_fn_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_arg_plain_fn_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -265,7 +275,8 @@ public function testBucket3SelfCallClosureArgumentCompilesEraseAndRuns(): void ); $fixture->registerAutoload('App\\Bucket3Run\\'); try { - require __DIR__ . '/../../fixture/compile/closure_arg_bucket3_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_arg_bucket3_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -295,7 +306,8 @@ public function testGroundedGenericClosureConformsWhenTypeParameterResolves(): v ); $fixture->registerAutoload('App\\ClosureGroundRuntime\\'); try { - require __DIR__ . '/../../fixture/compile/closure_conformance_grounded_runtime/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_conformance_grounded_runtime/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/ClosureDispatcherIntegrationTest.php b/test/Transpiler/Monomorphize/ClosureDispatcherIntegrationTest.php index 715316fb..6da5eef2 100644 --- a/test/Transpiler/Monomorphize/ClosureDispatcherIntegrationTest.php +++ b/test/Transpiler/Monomorphize/ClosureDispatcherIntegrationTest.php @@ -126,7 +126,8 @@ public function testRuntimeRoutingThroughDispatcher(): void 'disp-routing', ); try { - require __DIR__ . '/../../fixture/compile/closure_dispatcher_runtime_routing/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_dispatcher_runtime_routing/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -142,7 +143,8 @@ public function testUnknownTagAtRuntimeThrows(): void 'disp-unknown', ); try { - require __DIR__ . '/../../fixture/compile/closure_dispatcher_unknown_tag/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_dispatcher_unknown_tag/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -291,7 +293,8 @@ public function testFirstClassCallableTurbofishClosureEmitsValidForwardingClosur 'fcc-closure', ); try { - require __DIR__ . '/../../fixture/compile/turbofish_fcc_closure/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/turbofish_fcc_closure/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/DefaultedGenericIntegrationTest.php b/test/Transpiler/Monomorphize/DefaultedGenericIntegrationTest.php index 49eec68f..fb1a15a3 100644 --- a/test/Transpiler/Monomorphize/DefaultedGenericIntegrationTest.php +++ b/test/Transpiler/Monomorphize/DefaultedGenericIntegrationTest.php @@ -102,7 +102,8 @@ public function testBareNewSelfInNonDefaultsGenericBodyIsNotRejectedAndRuns(): v ); try { $fixture->registerAutoload('App\\BareNewSelfInGenericBody'); - require __DIR__ . '/../../fixture/compile/bare_new_self_in_generic_body/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/bare_new_self_in_generic_body/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/DispatcherFixtureIntegrationTest.php b/test/Transpiler/Monomorphize/DispatcherFixtureIntegrationTest.php index 5d7a7a36..723a12c5 100644 --- a/test/Transpiler/Monomorphize/DispatcherFixtureIntegrationTest.php +++ b/test/Transpiler/Monomorphize/DispatcherFixtureIntegrationTest.php @@ -68,7 +68,8 @@ public function testArrowFixtureSynthesizesUseClauseFromImplicitCapture(): void $out, ); - require __DIR__ . '/../../fixture/compile/closure_dispatcher_arrow/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_dispatcher_arrow/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -100,7 +101,8 @@ public function testUseClauseFixturePropagatesByRefThroughDispatcher(): void preg_match_all('/function closure_f_T_[0-9a-f]+\(/', $out, $matches); self::assertCount(2, $matches[0]); - require __DIR__ . '/../../fixture/compile/closure_dispatcher_use_clause/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_dispatcher_use_clause/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -131,7 +133,8 @@ public function testDefaultsFixturePadsEmptyTurbofish(): void preg_match_all('/function closure_f_T_[0-9a-f]+\(/', $out, $fMatches); self::assertCount(2, $fMatches[0]); - require __DIR__ . '/../../fixture/compile/closure_dispatcher_defaults/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_dispatcher_defaults/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/EnclosingParamBoundIntegrationTest.php b/test/Transpiler/Monomorphize/EnclosingParamBoundIntegrationTest.php index d2e6104b..8a4f2683 100644 --- a/test/Transpiler/Monomorphize/EnclosingParamBoundIntegrationTest.php +++ b/test/Transpiler/Monomorphize/EnclosingParamBoundIntegrationTest.php @@ -732,7 +732,8 @@ public function testErasableForwardingRunsAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_forwarding/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_forwarding/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -749,7 +750,8 @@ public function testTwoEnclosingBoundedParamsEraseAndRunAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_two_params/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_two_params/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -766,7 +768,8 @@ public function testMultiClassParamErasureMangleKeysOnTheBoundsReferentAtRuntime ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_map_multiparam/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_map_multiparam/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -783,7 +786,8 @@ public function testTwoTurbofishTypesCollapseToOneWidenedMemberAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_param_widening/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_param_widening/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -801,7 +805,8 @@ public function testInheritedErasableMemberResolvesAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_inherited/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_inherited/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -819,7 +824,8 @@ public function testErasureIsVarianceSafeOnTheCovariantChainAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_covariant_chain/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_erasure_covariant_chain/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -839,7 +845,8 @@ public function testCovariantInterfaceUpcastResolvesTheErasedMemberAtRuntime(): ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_interface_upcast/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_interface_upcast/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -859,7 +866,8 @@ public function testSubInterfaceMethodDirectEmittedUnderUpcastRunsAtRuntime(): v ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_subinterface_direct_emit/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_subinterface_direct_emit/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -878,7 +886,8 @@ public function testDirectEmittedBodyResolvesTheClassParamToTheUpcastSourceAtRun ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_subinterface_structural_class_param/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_subinterface_structural_class_param/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -896,7 +905,8 @@ public function testMultiParamCovariantInterfaceUpcastResolvesAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/enclosing_bound_interface_upcast_map/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/enclosing_bound_interface_upcast_map/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -916,7 +926,8 @@ public function testVarianceEdgeDoesNotOverwriteASourceParentAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/variance_edge_preserves_source_parent/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/variance_edge_preserves_source_parent/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -1264,7 +1275,8 @@ public function testNestedGenericDiamondCovariantUpcastCompilesAndRuns(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/covariant_upcast_nested_generic_diamond/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/covariant_upcast_nested_generic_diamond/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -1287,7 +1299,8 @@ public function testMultiPathDiamondClosureSuppliesEverySiblingAcrossInterfacesA ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/covariant_upcast_multipath_diamond/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/covariant_upcast_multipath_diamond/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -1307,7 +1320,8 @@ public function testReturnEnclosingParamOnParentlessBaseSurvivesPlainUpcast(): v ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/covariant_upcast_return_enclosing_inherited/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/covariant_upcast_return_enclosing_inherited/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/FreeSymbolRequalifyTest.php b/test/Transpiler/Monomorphize/FreeSymbolRequalifyTest.php index 1953ce66..a0e69dd2 100644 --- a/test/Transpiler/Monomorphize/FreeSymbolRequalifyTest.php +++ b/test/Transpiler/Monomorphize/FreeSymbolRequalifyTest.php @@ -31,7 +31,8 @@ public function testBareQualifiedConstAndBuiltinReferencesBindCorrectlyAtRuntime ); try { $fixture->registerAutoload('App\\FreeSym'); - require __DIR__ . '/../../fixture/compile/free_symbol_requalify/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/free_symbol_requalify/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -49,7 +50,8 @@ public function testUseFunctionAndUseConstImportsBindTheImportedNamespaceAtRunti ); try { $fixture->registerAutoload('App', 'Vendor'); - require __DIR__ . '/../../fixture/compile/free_symbol_use_import/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/free_symbol_use_import/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -67,7 +69,8 @@ public function testGroupUseFunctionAndConstImportsBindTheImportedNamespaceAtRun ); try { $fixture->registerAutoload('App', 'Vendor'); - require __DIR__ . '/../../fixture/compile/free_symbol_group_use_import/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/free_symbol_group_use_import/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -86,7 +89,8 @@ public function testGapFilledCovariantMembersReQualifyTheirFreeSymbolsAtRuntime( ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/covariant_gapfill_free_symbol/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/covariant_gapfill_free_symbol/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/GenericExceptionCatchIntegrationTest.php b/test/Transpiler/Monomorphize/GenericExceptionCatchIntegrationTest.php index a93e805b..f3048b64 100644 --- a/test/Transpiler/Monomorphize/GenericExceptionCatchIntegrationTest.php +++ b/test/Transpiler/Monomorphize/GenericExceptionCatchIntegrationTest.php @@ -57,7 +57,8 @@ public function testGenericCatchDiscriminatesBySpecializationAtRuntime(): void $fixture = CompiledFixture::compile($this->sourceDir, 'generic-catch-runtime'); $fixture->registerAutoload('App\\GenericExceptionCatch\\'); try { - require __DIR__ . '/../../fixture/compile/generic_exception_catch/verify/catch_runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_exception_catch/verify/catch_runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/GenericFunctionIntegrationTest.php b/test/Transpiler/Monomorphize/GenericFunctionIntegrationTest.php index 56e42176..d95b5250 100644 --- a/test/Transpiler/Monomorphize/GenericFunctionIntegrationTest.php +++ b/test/Transpiler/Monomorphize/GenericFunctionIntegrationTest.php @@ -84,7 +84,8 @@ public function testRuntimeExecutionOfSpecializedFunctions(): void { $fixture = CompiledFixture::compile($this->sourceDir, 'genfn-runtime'); try { - require __DIR__ . '/../../fixture/compile/generic_function/verify/runtime_execution.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_function/verify/runtime_execution.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -269,7 +270,8 @@ public function testBareTopLevelStripPreservesAllNonTemplateStatements(): void $funcsOut, ); - require __DIR__ . '/../../fixture/compile/generic_function_bare_top_level/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_function_bare_top_level/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/GenericInterfaceIntegrationTest.php b/test/Transpiler/Monomorphize/GenericInterfaceIntegrationTest.php index 9766ab42..1b9493c3 100644 --- a/test/Transpiler/Monomorphize/GenericInterfaceIntegrationTest.php +++ b/test/Transpiler/Monomorphize/GenericInterfaceIntegrationTest.php @@ -119,7 +119,8 @@ public function testSpecializedClassIsInstanceOfSpecializedInterfaceAtRuntime(): $fixture = CompiledFixture::compile($this->sourceDir, 'generic-interface-runtime'); $fixture->registerAutoload('App\\GenericInterface\\'); try { - require __DIR__ . '/../../fixture/compile/generic_interface/verify/specialized_interface_runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_interface/verify/specialized_interface_runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/GenericMethodIntegrationTest.php b/test/Transpiler/Monomorphize/GenericMethodIntegrationTest.php index 981bedee..42aff925 100644 --- a/test/Transpiler/Monomorphize/GenericMethodIntegrationTest.php +++ b/test/Transpiler/Monomorphize/GenericMethodIntegrationTest.php @@ -92,7 +92,8 @@ public function testRuntimeExecutionPreservesGenericMethodSemantics(): void 'genmethod-runtime', ); try { - require __DIR__ . '/../../fixture/compile/generic_method/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_method/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -240,7 +241,8 @@ public function testSelfWithTypeArgsCompilesEndToEnd(): void ); $fixture->registerAutoload('App\\GenericMethodSelfReturnTypeArgs'); - require __DIR__ . '/../../fixture/compile/generic_method_self_with_type_args/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_method_self_with_type_args/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -271,7 +273,8 @@ public function testInstanceMethodGenericThisReceiverSpecializes(): void $util, ); - require __DIR__ . '/../../fixture/compile/generic_method_this_receiver/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_method_this_receiver/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -342,7 +345,8 @@ public function testInstanceMethodGenericLocalVariableReceiverSpecializes(): voi $use, ); - require __DIR__ . '/../../fixture/compile/generic_method_local_variable_receiver/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_method_local_variable_receiver/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -1185,7 +1189,8 @@ public function testNewSelfTurbofishCompilesEndToEnd(): void ); $fixture->registerAutoload('App\\GenericMethodNewSelfTurbofish'); - require __DIR__ . '/../../fixture/compile/generic_method_new_self_turbofish/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_method_new_self_turbofish/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -1217,7 +1222,8 @@ public function testNewStaticTurbofishCompilesEndToEnd(): void ); $fixture->registerAutoload('App\\GenericMethodNewStaticTurbofish'); - require __DIR__ . '/../../fixture/compile/generic_method_new_static_turbofish/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_method_new_static_turbofish/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -1327,7 +1333,8 @@ public function testGenericMethodResolvesThroughInheritance(): void ); $fixture->registerAutoload('App\\GenericMethodThroughInheritance'); - require __DIR__ . '/../../fixture/compile/generic_method_through_inheritance/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_method_through_inheritance/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -1353,7 +1360,8 @@ public function testStaticGenericMethodResolvesThroughInheritance(): void self::assertSame(2, preg_match_all('/function make_T_[0-9a-f]+\(/', $base)); self::assertStringNotContainsString('make_T_', $derived); - require __DIR__ . '/../../fixture/compile/generic_static_method_through_inheritance/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_static_method_through_inheritance/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/GenericTraitAdaptationTest.php b/test/Transpiler/Monomorphize/GenericTraitAdaptationTest.php index 7c158d02..035de8e9 100644 --- a/test/Transpiler/Monomorphize/GenericTraitAdaptationTest.php +++ b/test/Transpiler/Monomorphize/GenericTraitAdaptationTest.php @@ -28,7 +28,8 @@ public function testCrossStatementInsteadofAndAliasResolveAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/generic_trait_adaptation/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_trait_adaptation/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -46,7 +47,8 @@ public function testMixedGenericAndPlainTraitAdaptationResolvesAtRuntime(): void ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/generic_trait_adaptation_mixed/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_trait_adaptation_mixed/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/GroupImportClassRequalifyTest.php b/test/Transpiler/Monomorphize/GroupImportClassRequalifyTest.php index 9925dd0e..142165cf 100644 --- a/test/Transpiler/Monomorphize/GroupImportClassRequalifyTest.php +++ b/test/Transpiler/Monomorphize/GroupImportClassRequalifyTest.php @@ -29,7 +29,8 @@ public function testGroupImportedClassReQualifiesInARelocatedBodyAtRuntime(): vo ); try { $fixture->registerAutoload('App', 'Vendor'); - require __DIR__ . '/../../fixture/compile/group_import_class_requalify/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/group_import_class_requalify/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/KeywordNamedGenericMethodTest.php b/test/Transpiler/Monomorphize/KeywordNamedGenericMethodTest.php index 793b2e47..0c1b8bd4 100644 --- a/test/Transpiler/Monomorphize/KeywordNamedGenericMethodTest.php +++ b/test/Transpiler/Monomorphize/KeywordNamedGenericMethodTest.php @@ -30,7 +30,8 @@ public function testKeywordNamedGenericMethodSpecializesAndRunsViaBothCallSites( ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/keyword_named_generic_method/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/keyword_named_generic_method/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -49,7 +50,8 @@ public function testKeywordNamedNonGenericMethodsAndListDestructuringPassThrough ); try { $fixture->registerAutoload('App'); - require __DIR__ . '/../../fixture/compile/keyword_nongeneric_passthrough/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/keyword_nongeneric_passthrough/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/MarkerAlignmentIntegrationTest.php b/test/Transpiler/Monomorphize/MarkerAlignmentIntegrationTest.php index 6e1dd392..13439aa1 100644 --- a/test/Transpiler/Monomorphize/MarkerAlignmentIntegrationTest.php +++ b/test/Transpiler/Monomorphize/MarkerAlignmentIntegrationTest.php @@ -26,7 +26,8 @@ public function testDeclarationsAfterMultiLineSpansStillSpecializeAndRun(): void ); $fixture->registerAutoload('App\\MultilineMarkers'); try { - require __DIR__ . '/../../fixture/compile/multiline_generic_markers/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/multiline_generic_markers/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -41,7 +42,8 @@ public function testAttributedAndStaticGenericClosuresSpecializeAndRun(): void ); $fixture->registerAutoload('App\\AttributedClosures'); try { - require __DIR__ . '/../../fixture/compile/attributed_generic_closures/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/attributed_generic_closures/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -56,7 +58,8 @@ public function testSameLineSameSpellingPairsBindTheirOwnMarkersAndRun(): void ); $fixture->registerAutoload('App\\SameLinePairs'); try { - require __DIR__ . '/../../fixture/compile/same_line_marker_pairs/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/same_line_marker_pairs/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -71,7 +74,8 @@ public function testSplitDeclarationHeadersSpecializeAndRun(): void ); $fixture->registerAutoload('App\\SplitHeaders'); try { - require __DIR__ . '/../../fixture/compile/split_declaration_headers/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/split_declaration_headers/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/MultiTypeGenericsIntegrationTest.php b/test/Transpiler/Monomorphize/MultiTypeGenericsIntegrationTest.php index 2b0d6c00..1e28e615 100644 --- a/test/Transpiler/Monomorphize/MultiTypeGenericsIntegrationTest.php +++ b/test/Transpiler/Monomorphize/MultiTypeGenericsIntegrationTest.php @@ -197,7 +197,8 @@ public function testRuntimeTypeErrorOnWrongSlotType(): void $fixture = CompiledFixture::compile($this->sourceDir, 'multi-type-runtime'); $fixture->registerAutoload('App\\MultiType\\'); try { - require __DIR__ . '/../../fixture/compile/multi_type/verify/type_error_on_wrong_slot.php'; + $runtime = require __DIR__ . '/../../fixture/compile/multi_type/verify/type_error_on_wrong_slot.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/NestedGenericsIntegrationTest.php b/test/Transpiler/Monomorphize/NestedGenericsIntegrationTest.php index df6363da..5028271c 100644 --- a/test/Transpiler/Monomorphize/NestedGenericsIntegrationTest.php +++ b/test/Transpiler/Monomorphize/NestedGenericsIntegrationTest.php @@ -148,7 +148,8 @@ public function testRuntimeReflectionAndTypeErrorOnNestedSpecialization(): void $fixture = CompiledFixture::compile($sourceDir, 'nested-runtime'); $fixture->registerAutoload('App\\NestedTypehint\\'); try { - require __DIR__ . '/../../fixture/compile/nested_typehint/verify/nested_specialization_runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/nested_typehint/verify/nested_specialization_runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/QualifiedCallSiteIntegrationTest.php b/test/Transpiler/Monomorphize/QualifiedCallSiteIntegrationTest.php index 85a2fe04..c2e3aa5b 100644 --- a/test/Transpiler/Monomorphize/QualifiedCallSiteIntegrationTest.php +++ b/test/Transpiler/Monomorphize/QualifiedCallSiteIntegrationTest.php @@ -26,7 +26,8 @@ public function testQualifiedSpellingsSpecializeAndRun(): void ); $fixture->registerAutoload('App\\QualifiedCalls'); try { - require __DIR__ . '/../../fixture/compile/qualified_generic_call_sites/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/qualified_generic_call_sites/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -41,7 +42,8 @@ public function testRelativeNamesInTemplatesBindToTheCurrentNamespaceAndRun(): v ); $fixture->registerAutoload('App\\RelativeTemplates', 'Other'); try { - require __DIR__ . '/../../fixture/compile/relative_names_in_templates/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/relative_names_in_templates/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -56,7 +58,8 @@ public function testQualifiedBareNewsSynthesizeDefaultsAndRun(): void ); $fixture->registerAutoload('App\\QualifiedDefaults', 'Other'); try { - require __DIR__ . '/../../fixture/compile/qualified_bare_new_defaults/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/qualified_bare_new_defaults/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/UseClosureSpecializationTest.php b/test/Transpiler/Monomorphize/UseClosureSpecializationTest.php index 77f31283..89045994 100644 --- a/test/Transpiler/Monomorphize/UseClosureSpecializationTest.php +++ b/test/Transpiler/Monomorphize/UseClosureSpecializationTest.php @@ -31,7 +31,8 @@ public function testUseClauseByValueRuntimeContract(): void 'use-byval', ); try { - require __DIR__ . '/../../fixture/compile/closure_use_by_value/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_use_by_value/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -45,7 +46,8 @@ public function testUseClauseByRefCaptureMutatesOuter(): void 'use-byref', ); try { - require __DIR__ . '/../../fixture/compile/closure_use_by_ref/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_use_by_ref/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -83,7 +85,8 @@ public function testUseClauseMultipleMixedRefAndValueCaptures(): void 'use-mixed', ); try { - require __DIR__ . '/../../fixture/compile/closure_use_multiple_mixed_captures/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_use_multiple_mixed_captures/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -109,7 +112,8 @@ public function testUseClauseMultipleArgTuples(): void $out, ); - require __DIR__ . '/../../fixture/compile/closure_use_multiple_arg_tuples/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_use_multiple_arg_tuples/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -173,7 +177,8 @@ public function testUseClauseCaptureNamedXphpArgsAutoRenames(): void 'use-reserved', ); try { - require __DIR__ . '/../../fixture/compile/closure_use_capture_named_xphp_args/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/closure_use_capture_named_xphp_args/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/UseImportGenericClauseTest.php b/test/Transpiler/Monomorphize/UseImportGenericClauseTest.php index af3e50f4..d17dc5d9 100644 --- a/test/Transpiler/Monomorphize/UseImportGenericClauseTest.php +++ b/test/Transpiler/Monomorphize/UseImportGenericClauseTest.php @@ -138,7 +138,8 @@ public function testGenericTraitUseStillSpecializesAndRuns(): void ); try { $fixture->registerAutoload('App\\UseTraitGeneric'); - require __DIR__ . '/../../fixture/compile/use_trait_generic/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/use_trait_generic/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/Transpiler/Monomorphize/VarianceEdgeIntegrationTest.php b/test/Transpiler/Monomorphize/VarianceEdgeIntegrationTest.php index 2bc8a125..1e0a2e9f 100644 --- a/test/Transpiler/Monomorphize/VarianceEdgeIntegrationTest.php +++ b/test/Transpiler/Monomorphize/VarianceEdgeIntegrationTest.php @@ -84,7 +84,8 @@ public function testCovariantImmutableCollectionTakesTypedConstructorInput(): vo self::assertStringNotContainsString('final class', $combined); $fixture->registerAutoload('App\\CovariantConstructor'); - require __DIR__ . '/../../fixture/compile/generic_covariant_immutable_constructor/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_covariant_immutable_constructor/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -135,7 +136,8 @@ public function testCovariantPrivatePropertyStoresRealTypeAndIsRuntimeChecked(): self::assertStringNotContainsString('final class', $combined); $fixture->registerAutoload('App\\CovariantPrivateProperty'); - require __DIR__ . '/../../fixture/compile/generic_covariant_private_property/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/generic_covariant_private_property/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -181,7 +183,8 @@ public function testCrossTemplateGenericArgUpcastEmitsEdgeAndRunsAtRuntime(): vo ); $fixture->registerAutoload('App\\'); - require __DIR__ . '/../../fixture/compile/cross_template_generic_arg_upcast/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/cross_template_generic_arg_upcast/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } @@ -202,7 +205,8 @@ public function testComparatorParamOnCovariantClassCompilesAndRunsUnderUpcast(): ); try { $fixture->registerAutoload('App\\'); - require __DIR__ . '/../../fixture/compile/comparator_param_covariant_upcast/verify/runtime.php'; + $runtime = require __DIR__ . '/../../fixture/compile/comparator_param_covariant_upcast/verify/runtime.php'; + $runtime($fixture); } finally { $fixture->cleanup(); } diff --git a/test/fixture/compile/array_sugar/verify/nullable_return.php b/test/fixture/compile/array_sugar/verify/nullable_return.php index 874a4622..533458f6 100644 --- a/test/fixture/compile/array_sugar/verify/nullable_return.php +++ b/test/fixture/compile/array_sugar/verify/nullable_return.php @@ -15,29 +15,32 @@ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -$collectionFqn = Registry::generatedFqn( - 'App\\ArraySugar\\Containers\\Collection', - [new TypeRef('App\\ArraySugar\\Models\\User')], -); +return function (CompiledFixture $fixture): void { + $collectionFqn = Registry::generatedFqn( + 'App\\ArraySugar\\Containers\\Collection', + [new TypeRef('App\\ArraySugar\\Models\\User')], + ); -// Non-empty: first() returns the concrete typed instance, all() is an array. -$collection = new $collectionFqn( - new \App\ArraySugar\Models\User('alice'), - new \App\ArraySugar\Models\User('bob'), -); -Assert::assertInstanceOf(\App\ArraySugar\Models\User::class, $collection->first()); -$all = $collection->all(); -Assert::assertIsArray($all); -Assert::assertCount(2, $all); + // Non-empty: first() returns the concrete typed instance, all() is an array. + $collection = new $collectionFqn( + new \App\ArraySugar\Models\User('alice'), + new \App\ArraySugar\Models\User('bob'), + ); + Assert::assertInstanceOf(\App\ArraySugar\Models\User::class, $collection->first()); + $all = $collection->all(); + Assert::assertIsArray($all); + Assert::assertCount(2, $all); -// Empty: first() returns null (the nullable arm of `?T`). -$empty = new $collectionFqn(); -Assert::assertNull($empty->first()); + // Empty: first() returns null (the nullable arm of `?T`). + $empty = new $collectionFqn(); + Assert::assertNull($empty->first()); -// Reflection: the `?T` return type must lower to the concrete class, -// not survive as a literal `T` or be widened to `mixed`. -$returnType = (new \ReflectionMethod($collectionFqn, 'first'))->getReturnType(); -Assert::assertInstanceOf(\ReflectionNamedType::class, $returnType); -Assert::assertSame('App\\ArraySugar\\Models\\User', $returnType->getName()); -Assert::assertTrue($returnType->allowsNull()); + // Reflection: the `?T` return type must lower to the concrete class, + // not survive as a literal `T` or be widened to `mixed`. + $returnType = (new \ReflectionMethod($collectionFqn, 'first'))->getReturnType(); + Assert::assertInstanceOf(\ReflectionNamedType::class, $returnType); + Assert::assertSame('App\\ArraySugar\\Models\\User', $returnType->getName()); + Assert::assertTrue($returnType->allowsNull()); +}; diff --git a/test/fixture/compile/array_sugar_before_generic_closure/verify/runtime.php b/test/fixture/compile/array_sugar_before_generic_closure/verify/runtime.php index 64bf4823..d73c7297 100644 --- a/test/fixture/compile/array_sugar_before_generic_closure/verify/runtime.php +++ b/test/fixture/compile/array_sugar_before_generic_closure/verify/runtime.php @@ -7,13 +7,16 @@ * `VeryLongRecordName[]` rewrite shortens the file before the generic * closure; the closure must still specialize and route both calls. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(1, $n); -Assert::assertSame(42, $a); -Assert::assertSame('hello', $b); + Assert::assertSame(1, $n); + Assert::assertSame(42, $a); + Assert::assertSame('hello', $b); +}; diff --git a/test/fixture/compile/arrow_capture_at_declaration/verify/runtime.php b/test/fixture/compile/arrow_capture_at_declaration/verify/runtime.php index f88734c7..f36892cd 100644 --- a/test/fixture/compile/arrow_capture_at_declaration/verify/runtime.php +++ b/test/fixture/compile/arrow_capture_at_declaration/verify/runtime.php @@ -3,8 +3,11 @@ declare(strict_types=1); use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(43, $result); -Assert::assertSame(2, $y); + Assert::assertSame(43, $result); + Assert::assertSame(2, $y); +}; diff --git a/test/fixture/compile/arrow_capture_shadowing/verify/runtime.php b/test/fixture/compile/arrow_capture_shadowing/verify/runtime.php index 2d40a161..5925b0eb 100644 --- a/test/fixture/compile/arrow_capture_shadowing/verify/runtime.php +++ b/test/fixture/compile/arrow_capture_shadowing/verify/runtime.php @@ -3,7 +3,10 @@ declare(strict_types=1); use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(7, $result); + Assert::assertSame(7, $result); +}; diff --git a/test/fixture/compile/arrow_defaults_single/verify/runtime.php b/test/fixture/compile/arrow_defaults_single/verify/runtime.php index f632a917..07e680fa 100644 --- a/test/fixture/compile/arrow_defaults_single/verify/runtime.php +++ b/test/fixture/compile/arrow_defaults_single/verify/runtime.php @@ -5,11 +5,14 @@ /** * Runtime verify for `arrow_defaults_single`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(7, $r); + Assert::assertSame(7, $r); +}; diff --git a/test/fixture/compile/arrow_defaults_with_implicit_capture/verify/runtime.php b/test/fixture/compile/arrow_defaults_with_implicit_capture/verify/runtime.php index 517bb992..c165556e 100644 --- a/test/fixture/compile/arrow_defaults_with_implicit_capture/verify/runtime.php +++ b/test/fixture/compile/arrow_defaults_with_implicit_capture/verify/runtime.php @@ -5,11 +5,14 @@ /** * Runtime verify for `arrow_defaults_with_implicit_capture`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(13, $r); + Assert::assertSame(13, $r); +}; diff --git a/test/fixture/compile/arrow_multiple_arg_tuples/verify/runtime.php b/test/fixture/compile/arrow_multiple_arg_tuples/verify/runtime.php index 59c387b8..01255936 100644 --- a/test/fixture/compile/arrow_multiple_arg_tuples/verify/runtime.php +++ b/test/fixture/compile/arrow_multiple_arg_tuples/verify/runtime.php @@ -3,8 +3,11 @@ declare(strict_types=1); use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(10, $a); -Assert::assertSame('hi', $b); + Assert::assertSame(10, $a); + Assert::assertSame('hi', $b); +}; diff --git a/test/fixture/compile/arrow_multiple_captures/verify/runtime.php b/test/fixture/compile/arrow_multiple_captures/verify/runtime.php index 8cb0eabd..dce850ef 100644 --- a/test/fixture/compile/arrow_multiple_captures/verify/runtime.php +++ b/test/fixture/compile/arrow_multiple_captures/verify/runtime.php @@ -3,7 +3,10 @@ declare(strict_types=1); use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(31, $result); + Assert::assertSame(31, $result); +}; diff --git a/test/fixture/compile/arrow_no_captures/verify/runtime.php b/test/fixture/compile/arrow_no_captures/verify/runtime.php index 1fcaec8a..b4eeb2c3 100644 --- a/test/fixture/compile/arrow_no_captures/verify/runtime.php +++ b/test/fixture/compile/arrow_no_captures/verify/runtime.php @@ -3,7 +3,10 @@ declare(strict_types=1); use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $result); + Assert::assertSame(42, $result); +}; diff --git a/test/fixture/compile/arrow_reserved_args_capture/verify/runtime.php b/test/fixture/compile/arrow_reserved_args_capture/verify/runtime.php index 1b805658..e55a0e21 100644 --- a/test/fixture/compile/arrow_reserved_args_capture/verify/runtime.php +++ b/test/fixture/compile/arrow_reserved_args_capture/verify/runtime.php @@ -3,7 +3,10 @@ declare(strict_types=1); use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(203, $result); + Assert::assertSame(203, $result); +}; diff --git a/test/fixture/compile/arrow_reserved_tag_capture/verify/runtime.php b/test/fixture/compile/arrow_reserved_tag_capture/verify/runtime.php index ff9b10d0..470ddc13 100644 --- a/test/fixture/compile/arrow_reserved_tag_capture/verify/runtime.php +++ b/test/fixture/compile/arrow_reserved_tag_capture/verify/runtime.php @@ -3,7 +3,10 @@ declare(strict_types=1); use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(105, $result); + Assert::assertSame(105, $result); +}; diff --git a/test/fixture/compile/attributed_generic_closures/verify/runtime.php b/test/fixture/compile/attributed_generic_closures/verify/runtime.php index 31f78054..5cec73bf 100644 --- a/test/fixture/compile/attributed_generic_closures/verify/runtime.php +++ b/test/fixture/compile/attributed_generic_closures/verify/runtime.php @@ -7,15 +7,18 @@ * static generic closures and arrows must specialize (not silently keep * raw type-param hints), and the emitted program must execute. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(7, $a); -Assert::assertSame('b', $b); -Assert::assertSame(3, $c); -Assert::assertSame('d', $d); -Assert::assertSame(11, $e); + Assert::assertSame(7, $a); + Assert::assertSame('b', $b); + Assert::assertSame(3, $c); + Assert::assertSame('d', $d); + Assert::assertSame(11, $e); +}; diff --git a/test/fixture/compile/bare_new_self_in_generic_body/verify/runtime.php b/test/fixture/compile/bare_new_self_in_generic_body/verify/runtime.php index f4cf1541..ee37a85d 100644 --- a/test/fixture/compile/bare_new_self_in_generic_body/verify/runtime.php +++ b/test/fixture/compile/bare_new_self_in_generic_body/verify/runtime.php @@ -7,13 +7,16 @@ * non-defaults generic body compiles (not rejected by the WI-06 bare-new guard) and * runs -- `$c` is a copy of `$n` produced by `new self`, carrying the same value. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoloader registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoloader registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(5, $n->v); -Assert::assertSame(5, $c->v); -Assert::assertNotSame($n, $c); + Assert::assertSame(5, $n->v); + Assert::assertSame(5, $c->v); + Assert::assertNotSame($n, $c); +}; diff --git a/test/fixture/compile/builtin_interface_via_use/verify/runtime.php b/test/fixture/compile/builtin_interface_via_use/verify/runtime.php index 1348f74f..afb5a256 100644 --- a/test/fixture/compile/builtin_interface_via_use/verify/runtime.php +++ b/test/fixture/compile/builtin_interface_via_use/verify/runtime.php @@ -12,7 +12,7 @@ * "Interface ... not found" the moment the class autoloaded. This file proves * the class now loads and the built-ins resolve to the real global symbols. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered * for `App\BuiltinViaUse\` + the generated namespace. */ @@ -20,56 +20,59 @@ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -$bagFqn = Registry::generatedFqn( - 'App\\BuiltinViaUse\\ArrayBag', - [new TypeRef('App\\BuiltinViaUse\\Models\\User')], -); +return function (CompiledFixture $fixture): void { + $bagFqn = Registry::generatedFqn( + 'App\\BuiltinViaUse\\ArrayBag', + [new TypeRef('App\\BuiltinViaUse\\Models\\User')], + ); -// Autoloads without a "not found" error — this is the regression under test. -$bag = new $bagFqn(); + // Autoloads without a "not found" error — this is the regression under test. + $bag = new $bagFqn(); -// `extends Countable, IteratorAggregate` (imported, bare) resolved to the real built-ins. -Assert::assertInstanceOf(\Countable::class, $bag); -Assert::assertInstanceOf(\IteratorAggregate::class, $bag); + // `extends Countable, IteratorAggregate` (imported, bare) resolved to the real built-ins. + Assert::assertInstanceOf(\Countable::class, $bag); + Assert::assertInstanceOf(\IteratorAggregate::class, $bag); -$bag->add(new User('alice')); -$bag->add(new User('bob')); + $bag->add(new User('alice')); + $bag->add(new User('bob')); -// Countable::count() via the bare `\count(...)` call (must have stayed bare). -Assert::assertCount(2, $bag); + // Countable::count() via the bare `\count(...)` call (must have stayed bare). + Assert::assertCount(2, $bag); -// `getIterator(): Traversable { return new ArrayIterator(...); }` — return-type -// hint + `new` of an imported built-in, both relocation-proof now. -$iter = $bag->getIterator(); -Assert::assertInstanceOf(\Traversable::class, $iter); -Assert::assertInstanceOf(\ArrayIterator::class, $iter); -Assert::assertCount(2, $iter); + // `getIterator(): Traversable { return new ArrayIterator(...); }` — return-type + // hint + `new` of an imported built-in, both relocation-proof now. + $iter = $bag->getIterator(); + Assert::assertInstanceOf(\Traversable::class, $iter); + Assert::assertInstanceOf(\ArrayIterator::class, $iter); + Assert::assertCount(2, $iter); -// `first()` happy path returns the concrete substituted element type. -Assert::assertInstanceOf(User::class, $bag->first()); -Assert::assertSame('alice', $bag->first()->name); + // `first()` happy path returns the concrete substituted element type. + Assert::assertInstanceOf(User::class, $bag->first()); + Assert::assertSame('alice', $bag->first()->name); -// `extends AbstractBag` (bare, same-namespace) resolved to the real base class. -Assert::assertInstanceOf(\App\BuiltinViaUse\AbstractBag::class, $bag); -Assert::assertTrue((new $bagFqn())->isEmpty([])); + // `extends AbstractBag` (bare, same-namespace) resolved to the real base class. + Assert::assertInstanceOf(\App\BuiltinViaUse\AbstractBag::class, $bag); + Assert::assertTrue((new $bagFqn())->isEmpty([])); -// Param-typed / instanceof / class-const-fetch positions all load and run. -Assert::assertTrue($bag->accepts(new \App\BuiltinViaUse\Errors\EmptyBagError('probe'))); + // Param-typed / instanceof / class-const-fetch positions all load and run. + Assert::assertTrue($bag->accepts(new \App\BuiltinViaUse\Errors\EmptyBagError('probe'))); -// Closure with an imported return type, nested in a relocated method. -$factory = $bag->makeFactory(); -Assert::assertInstanceOf(\Traversable::class, $factory()); + // Closure with an imported return type, nested in a relocated method. + $factory = $bag->makeFactory(); + Assert::assertInstanceOf(\Traversable::class, $factory()); -// Typed (enum) class constant whose type + value reference a same-namespace class. -Assert::assertSame(\App\BuiltinViaUse\Color::Red, $bag::DEFAULT_COLOR); + // Typed (enum) class constant whose type + value reference a same-namespace class. + Assert::assertSame(\App\BuiltinViaUse\Color::Red, $bag::DEFAULT_COLOR); -// `catch (EmptyBagError $e)` + `new EmptyBagError(...)` path on the empty bag. -$empty = new $bagFqn(); -try { - $empty->first(); - Assert::fail('expected RuntimeException from the empty-bag path'); -} catch (\RuntimeException $e) { - Assert::assertSame('bag is empty', $e->getMessage()); - Assert::assertInstanceOf(\App\BuiltinViaUse\Errors\EmptyBagError::class, $e->getPrevious()); -} + // `catch (EmptyBagError $e)` + `new EmptyBagError(...)` path on the empty bag. + $empty = new $bagFqn(); + try { + $empty->first(); + Assert::fail('expected RuntimeException from the empty-bag path'); + } catch (\RuntimeException $e) { + Assert::assertSame('bag is empty', $e->getMessage()); + Assert::assertInstanceOf(\App\BuiltinViaUse\Errors\EmptyBagError::class, $e->getPrevious()); + } +}; diff --git a/test/fixture/compile/closure_arg_bucket3_runtime/verify/runtime.php b/test/fixture/compile/closure_arg_bucket3_runtime/verify/runtime.php index 99a654c6..d35e4948 100644 --- a/test/fixture/compile/closure_arg_bucket3_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_arg_bucket3_runtime/verify/runtime.php @@ -9,11 +9,14 @@ * whose `Closure(E): string` target grounds to `Closure(int): string` under Box, * conforms, erases to `\Closure`, and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('value=42', $result, 'the grounded bucket-3 self-call argument ran'); + Assert::assertSame('value=42', $result, 'the grounded bucket-3 self-call argument ran'); +}; diff --git a/test/fixture/compile/closure_arg_free_fn_runtime/verify/runtime.php b/test/fixture/compile/closure_arg_free_fn_runtime/verify/runtime.php index ad4195ac..ba44725d 100644 --- a/test/fixture/compile/closure_arg_free_fn_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_arg_free_fn_runtime/verify/runtime.php @@ -8,11 +8,14 @@ * A conforming closure literal passed to a grounded `Closure(int $x): int` generic * free-function parameter compiles, erases to `\Closure`, and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $result, 'the conforming free-function closure argument ran'); + Assert::assertSame(42, $result, 'the conforming free-function closure argument ran'); +}; diff --git a/test/fixture/compile/closure_arg_instance_runtime/verify/runtime.php b/test/fixture/compile/closure_arg_instance_runtime/verify/runtime.php index 4fcc4c88..54dc601e 100644 --- a/test/fixture/compile/closure_arg_instance_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_arg_instance_runtime/verify/runtime.php @@ -8,11 +8,14 @@ * A conforming closure literal passed as a call argument to a grounded * `Closure(Book $x): string` parameter compiles, erases to `\Closure`, and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('PHP', $result, 'the conforming closure argument ran'); + Assert::assertSame('PHP', $result, 'the conforming closure argument ran'); +}; diff --git a/test/fixture/compile/closure_arg_plain_fn_runtime/verify/runtime.php b/test/fixture/compile/closure_arg_plain_fn_runtime/verify/runtime.php index cb0f8d44..cd4ea546 100644 --- a/test/fixture/compile/closure_arg_plain_fn_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_arg_plain_fn_runtime/verify/runtime.php @@ -8,11 +8,14 @@ * A conforming closure literal passed to a NON-generic free function's * Closure(Book): string parameter compiles, erases to `\Closure`, and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('PHP', $result, 'the conforming free-function closure argument ran'); + Assert::assertSame('PHP', $result, 'the conforming free-function closure argument ran'); +}; diff --git a/test/fixture/compile/closure_arg_plain_runtime/verify/runtime.php b/test/fixture/compile/closure_arg_plain_runtime/verify/runtime.php index cae159c3..d6acd654 100644 --- a/test/fixture/compile/closure_arg_plain_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_arg_plain_runtime/verify/runtime.php @@ -8,11 +8,14 @@ * A conforming closure literal passed to a NON-generic method's Closure(Book): string * parameter compiles, erases to `\Closure`, and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('PHP', $result, 'the conforming plain-method closure argument ran'); + Assert::assertSame('PHP', $result, 'the conforming plain-method closure argument ran'); +}; diff --git a/test/fixture/compile/closure_arg_static_runtime/verify/runtime.php b/test/fixture/compile/closure_arg_static_runtime/verify/runtime.php index 385d6473..d395249c 100644 --- a/test/fixture/compile/closure_arg_static_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_arg_static_runtime/verify/runtime.php @@ -8,11 +8,14 @@ * A conforming closure literal passed to a grounded `Closure(int $x): int` * static-method parameter compiles, erases to `\Closure`, and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $result, 'the conforming static closure argument ran'); + Assert::assertSame(42, $result, 'the conforming static closure argument ran'); +}; diff --git a/test/fixture/compile/closure_conformance_array_sugar_runtime/verify/runtime.php b/test/fixture/compile/closure_conformance_array_sugar_runtime/verify/runtime.php index 554aa70a..043c0a0c 100644 --- a/test/fixture/compile/closure_conformance_array_sugar_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_conformance_array_sugar_runtime/verify/runtime.php @@ -8,20 +8,23 @@ * Array-sugar leaves in signature parameter and return positions lower to * `array`, the signatures erase, and the compiled output executes. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $sum, 'sugared-parameter factory closure ran'); -Assert::assertSame([40, 2], $list, 'sugared-return factory closure ran'); + Assert::assertSame(42, $sum, 'sugared-parameter factory closure ran'); + Assert::assertSame([40, 2], $list, 'sugared-return factory closure ran'); -// Full erasure: no bracket-pair residue may survive into the emitted output -// (the trailing `[40, 2]` array literal is body code, not a type). -$emitted = file_get_contents($fixture->targetDir . '/Use.php'); -Assert::assertIsString($emitted); -Assert::assertStringContainsString('\\Closure', $emitted); -Assert::assertStringNotContainsString('Item[]', $emitted); -Assert::assertStringNotContainsString('int[]', $emitted); + // Full erasure: no bracket-pair residue may survive into the emitted output + // (the trailing `[40, 2]` array literal is body code, not a type). + $emitted = file_get_contents($fixture->targetDir . '/Use.php'); + Assert::assertIsString($emitted); + Assert::assertStringContainsString('\\Closure', $emitted); + Assert::assertStringNotContainsString('Item[]', $emitted); + Assert::assertStringNotContainsString('int[]', $emitted); +}; diff --git a/test/fixture/compile/closure_conformance_builtin_ok/verify/runtime.php b/test/fixture/compile/closure_conformance_builtin_ok/verify/runtime.php index bb7d61c9..a93ff27c 100644 --- a/test/fixture/compile/closure_conformance_builtin_ok/verify/runtime.php +++ b/test/fixture/compile/closure_conformance_builtin_ok/verify/runtime.php @@ -8,12 +8,15 @@ * The exception factory compiles (no false-reject against the built-in * `\Throwable` target), erases to `\Closure`, and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertInstanceOf(\Throwable::class, $thrown, 'the factory returned a Throwable'); -Assert::assertSame('boom', $thrown->getMessage()); + Assert::assertInstanceOf(\Throwable::class, $thrown, 'the factory returned a Throwable'); + Assert::assertSame('boom', $thrown->getMessage()); +}; diff --git a/test/fixture/compile/closure_conformance_dnf_runtime/verify/runtime.php b/test/fixture/compile/closure_conformance_dnf_runtime/verify/runtime.php index 46d96184..eb9f2c9f 100644 --- a/test/fixture/compile/closure_conformance_dnf_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_conformance_dnf_runtime/verify/runtime.php @@ -8,19 +8,22 @@ * DNF-grouped signature types scan as one gradual leaf, the signatures erase, * and the compiled output executes. Asserts both factories' closures ran. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $count, 'DNF-parameter factory closure ran'); -Assert::assertSame('both', $tag, 'DNF-return factory closure ran'); + Assert::assertSame(42, $count, 'DNF-parameter factory closure ran'); + Assert::assertSame('both', $tag, 'DNF-return factory closure ran'); -// Full erasure: no DNF residue may survive into the emitted output. -$emitted = file_get_contents($fixture->targetDir . '/Use.php'); -Assert::assertIsString($emitted); -Assert::assertStringContainsString('\\Closure', $emitted); -Assert::assertStringNotContainsString('(Tagged&Counted)', $emitted); -Assert::assertStringNotContainsString('|(', $emitted); + // Full erasure: no DNF residue may survive into the emitted output. + $emitted = file_get_contents($fixture->targetDir . '/Use.php'); + Assert::assertIsString($emitted); + Assert::assertStringContainsString('\\Closure', $emitted); + Assert::assertStringNotContainsString('(Tagged&Counted)', $emitted); + Assert::assertStringNotContainsString('|(', $emitted); +}; diff --git a/test/fixture/compile/closure_conformance_grounded_runtime/verify/runtime.php b/test/fixture/compile/closure_conformance_grounded_runtime/verify/runtime.php index cd10a58d..32fb5102 100644 --- a/test/fixture/compile/closure_conformance_grounded_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_conformance_grounded_runtime/verify/runtime.php @@ -8,11 +8,14 @@ * The type parameter grounds to `int`; the conforming factory closure compiles, * its `Closure(...)` target erases to `\Closure`, and it runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $result, 'the grounded factory closure ran'); + Assert::assertSame(42, $result, 'the grounded factory closure ran'); +}; diff --git a/test/fixture/compile/closure_conformance_runtime/verify/runtime.php b/test/fixture/compile/closure_conformance_runtime/verify/runtime.php index d1173436..7ff315b1 100644 --- a/test/fixture/compile/closure_conformance_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_conformance_runtime/verify/runtime.php @@ -9,20 +9,23 @@ * compiles clean and the erased-to-`\Closure` output executes. Asserts the * factories' closures actually ran with the values they were built from. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $scaled, 'stored property closure ran'); -Assert::assertSame(42, $added, 'method-return factory closure ran'); -Assert::assertSame(42, $incremented, 'free-function factory closure ran'); -Assert::assertSame(42, $tripled, 'arrow-body factory closure ran'); + Assert::assertSame(42, $scaled, 'stored property closure ran'); + Assert::assertSame(42, $added, 'method-return factory closure ran'); + Assert::assertSame(42, $incremented, 'free-function factory closure ran'); + Assert::assertSame(42, $tripled, 'arrow-body factory closure ran'); -// The erased output must carry a bare \Closure, never a residual `Closure(int`. -$emitted = file_get_contents($fixture->targetDir . '/Use.php'); -Assert::assertIsString($emitted); -Assert::assertStringContainsString('\\Closure', $emitted); -Assert::assertStringNotContainsString('Closure(int', $emitted); + // The erased output must carry a bare \Closure, never a residual `Closure(int`. + $emitted = file_get_contents($fixture->targetDir . '/Use.php'); + Assert::assertIsString($emitted); + Assert::assertStringContainsString('\\Closure', $emitted); + Assert::assertStringNotContainsString('Closure(int', $emitted); +}; diff --git a/test/fixture/compile/closure_defaults_single/verify/runtime.php b/test/fixture/compile/closure_defaults_single/verify/runtime.php index 1bc0e19f..3704d94b 100644 --- a/test/fixture/compile/closure_defaults_single/verify/runtime.php +++ b/test/fixture/compile/closure_defaults_single/verify/runtime.php @@ -5,11 +5,14 @@ /** * Runtime verify for `closure_defaults_single`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $r); + Assert::assertSame(42, $r); +}; diff --git a/test/fixture/compile/closure_defaults_with_use/verify/runtime.php b/test/fixture/compile/closure_defaults_with_use/verify/runtime.php index 38f172dd..317acef4 100644 --- a/test/fixture/compile/closure_defaults_with_use/verify/runtime.php +++ b/test/fixture/compile/closure_defaults_with_use/verify/runtime.php @@ -5,11 +5,14 @@ /** * Runtime verify for `closure_defaults_with_use`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(105, $r); + Assert::assertSame(105, $r); +}; diff --git a/test/fixture/compile/closure_dispatcher_arrow/verify/runtime.php b/test/fixture/compile/closure_dispatcher_arrow/verify/runtime.php index e263db92..ea33094f 100644 --- a/test/fixture/compile/closure_dispatcher_arrow/verify/runtime.php +++ b/test/fixture/compile/closure_dispatcher_arrow/verify/runtime.php @@ -5,7 +5,7 @@ /** * Runtime verify for `closure_dispatcher_arrow`. * - * Driver contract: `$fixture` (CompiledFixture) must be in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. * Requiring the compiled `Use.php` brings the top-level variables * `$y` and `$resultArrow` into this file's scope, so the assertions * read them directly. The capture moment is the assign site, so the @@ -13,8 +13,11 @@ */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(43, $resultArrow); -Assert::assertSame(2, $y); + Assert::assertSame(43, $resultArrow); + Assert::assertSame(2, $y); +}; diff --git a/test/fixture/compile/closure_dispatcher_defaults/verify/runtime.php b/test/fixture/compile/closure_dispatcher_defaults/verify/runtime.php index a41d4640..fd181031 100644 --- a/test/fixture/compile/closure_dispatcher_defaults/verify/runtime.php +++ b/test/fixture/compile/closure_dispatcher_defaults/verify/runtime.php @@ -5,16 +5,19 @@ /** * Runtime verify for `closure_dispatcher_defaults`. * - * Driver contract: `$fixture` (CompiledFixture) must be in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. * After requiring the compiled `Use.php`, the empty-turbofish and * explicit calls leave their results in `$resultPaddedClosure`, * `$resultExplicitClosure`, and `$resultPaddedArrow`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('#42', $resultPaddedClosure); -Assert::assertSame('#hi', $resultExplicitClosure); -Assert::assertSame('world', $resultPaddedArrow); + Assert::assertSame('#42', $resultPaddedClosure); + Assert::assertSame('#hi', $resultExplicitClosure); + Assert::assertSame('world', $resultPaddedArrow); +}; diff --git a/test/fixture/compile/closure_dispatcher_runtime_routing/verify/runtime.php b/test/fixture/compile/closure_dispatcher_runtime_routing/verify/runtime.php index 7d7824db..b4299154 100644 --- a/test/fixture/compile/closure_dispatcher_runtime_routing/verify/runtime.php +++ b/test/fixture/compile/closure_dispatcher_runtime_routing/verify/runtime.php @@ -7,12 +7,15 @@ * requiring the compiled Use.php, the two top-level vars `$a` and * `$b` hold the values routed through the dispatcher arms. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $a); -Assert::assertSame('hello', $b); + Assert::assertSame(42, $a); + Assert::assertSame('hello', $b); +}; diff --git a/test/fixture/compile/closure_dispatcher_unknown_tag/verify/runtime.php b/test/fixture/compile/closure_dispatcher_unknown_tag/verify/runtime.php index 45261a62..eb7bf490 100644 --- a/test/fixture/compile/closure_dispatcher_unknown_tag/verify/runtime.php +++ b/test/fixture/compile/closure_dispatcher_unknown_tag/verify/runtime.php @@ -9,18 +9,21 @@ * closure) at top level; the verify file then invokes it with a * tag that no real call site emits. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -$caught = null; -try { - $id('T_bogus', 99); -} catch (\RuntimeException $e) { - $caught = $e; -} -Assert::assertInstanceOf(\RuntimeException::class, $caught); -Assert::assertSame('Unknown generic specialization tag: T_bogus', $caught->getMessage()); + $caught = null; + try { + $id('T_bogus', 99); + } catch (\RuntimeException $e) { + $caught = $e; + } + Assert::assertInstanceOf(\RuntimeException::class, $caught); + Assert::assertSame('Unknown generic specialization tag: T_bogus', $caught->getMessage()); +}; diff --git a/test/fixture/compile/closure_dispatcher_use_clause/verify/runtime.php b/test/fixture/compile/closure_dispatcher_use_clause/verify/runtime.php index 060d9d99..c576740a 100644 --- a/test/fixture/compile/closure_dispatcher_use_clause/verify/runtime.php +++ b/test/fixture/compile/closure_dispatcher_use_clause/verify/runtime.php @@ -5,7 +5,7 @@ /** * Runtime verify for `closure_dispatcher_use_clause`. * - * Driver contract: `$fixture` (CompiledFixture) must be in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. * The compiled `Use.php` defines `$base`, `$counter`, and three call * results `$callA`, `$callB`, `$callC` at top level. After require, * each is available here. The by-ref `&$counter` capture mutates @@ -13,10 +13,13 @@ */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame([1, 10, 1], $callA); -Assert::assertSame([2, 10, 2], $callB); -Assert::assertSame(['hi', 10, 3], $callC); -Assert::assertSame(3, $counter); + Assert::assertSame([1, 10, 1], $callA); + Assert::assertSame([2, 10, 2], $callB); + Assert::assertSame(['hi', 10, 3], $callC); + Assert::assertSame(3, $counter); +}; diff --git a/test/fixture/compile/closure_named_user_function_runtime/verify/runtime.php b/test/fixture/compile/closure_named_user_function_runtime/verify/runtime.php index 08f270d9..017bc3ef 100644 --- a/test/fixture/compile/closure_named_user_function_runtime/verify/runtime.php +++ b/test/fixture/compile/closure_named_user_function_runtime/verify/runtime.php @@ -8,19 +8,22 @@ * The user function named `Closure` is CALLED (not erased) in every * expression position that shares a `) :` token pair with return-type slots. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $ternary, 'ternary-else call to App\\...\\Closure() executed'); -Assert::assertSame(20, $alt, 'alt-syntax-if call executed'); -Assert::assertSame(12, $case, 'case-label call executed'); + Assert::assertSame(42, $ternary, 'ternary-else call to App\\...\\Closure() executed'); + Assert::assertSame(20, $alt, 'alt-syntax-if call executed'); + Assert::assertSame(12, $case, 'case-label call executed'); -// The calls survive verbatim — no bare `\Closure` constant fetch anywhere. -$emitted = file_get_contents($fixture->targetDir . '/Use.php'); -Assert::assertIsString($emitted); -Assert::assertStringNotContainsString('\\Closure ', $emitted); -Assert::assertStringContainsString('Closure(HALF)', $emitted); + // The calls survive verbatim — no bare `\Closure` constant fetch anywhere. + $emitted = file_get_contents($fixture->targetDir . '/Use.php'); + Assert::assertIsString($emitted); + Assert::assertStringNotContainsString('\\Closure ', $emitted); + Assert::assertStringContainsString('Closure(HALF)', $emitted); +}; diff --git a/test/fixture/compile/closure_use_by_ref/verify/runtime.php b/test/fixture/compile/closure_use_by_ref/verify/runtime.php index df315e2b..4c7e7d9f 100644 --- a/test/fixture/compile/closure_use_by_ref/verify/runtime.php +++ b/test/fixture/compile/closure_use_by_ref/verify/runtime.php @@ -5,12 +5,15 @@ /** * Runtime verify for `closure_use_by_ref`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(99, $a); -Assert::assertSame(99, $y); + Assert::assertSame(99, $a); + Assert::assertSame(99, $y); +}; diff --git a/test/fixture/compile/closure_use_by_value/verify/runtime.php b/test/fixture/compile/closure_use_by_value/verify/runtime.php index 811b85d4..0150ebfe 100644 --- a/test/fixture/compile/closure_use_by_value/verify/runtime.php +++ b/test/fixture/compile/closure_use_by_value/verify/runtime.php @@ -5,12 +5,15 @@ /** * Runtime verify for `closure_use_by_value`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(43, $result); -Assert::assertSame(2, $y); + Assert::assertSame(43, $result); + Assert::assertSame(2, $y); +}; diff --git a/test/fixture/compile/closure_use_capture_named_xphp_args/verify/runtime.php b/test/fixture/compile/closure_use_capture_named_xphp_args/verify/runtime.php index a5c8cda3..4d9415c6 100644 --- a/test/fixture/compile/closure_use_capture_named_xphp_args/verify/runtime.php +++ b/test/fixture/compile/closure_use_capture_named_xphp_args/verify/runtime.php @@ -5,11 +5,14 @@ /** * Runtime verify for `closure_use_capture_named_xphp_args`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(203, $r); + Assert::assertSame(203, $r); +}; diff --git a/test/fixture/compile/closure_use_multiple_arg_tuples/verify/runtime.php b/test/fixture/compile/closure_use_multiple_arg_tuples/verify/runtime.php index 3f3fec7e..026b1e10 100644 --- a/test/fixture/compile/closure_use_multiple_arg_tuples/verify/runtime.php +++ b/test/fixture/compile/closure_use_multiple_arg_tuples/verify/runtime.php @@ -5,12 +5,15 @@ /** * Runtime verify for `closure_use_multiple_arg_tuples`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('pre:1', $a); -Assert::assertSame('pre:two', $b); + Assert::assertSame('pre:1', $a); + Assert::assertSame('pre:two', $b); +}; diff --git a/test/fixture/compile/closure_use_multiple_mixed_captures/verify/runtime.php b/test/fixture/compile/closure_use_multiple_mixed_captures/verify/runtime.php index 64217bb5..93fc0bbe 100644 --- a/test/fixture/compile/closure_use_multiple_mixed_captures/verify/runtime.php +++ b/test/fixture/compile/closure_use_multiple_mixed_captures/verify/runtime.php @@ -5,13 +5,16 @@ /** * Runtime verify for `closure_use_multiple_mixed_captures`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(36, $r); -Assert::assertSame(10, $a); -Assert::assertSame(25, $b); + Assert::assertSame(36, $r); + Assert::assertSame(10, $a); + Assert::assertSame(25, $b); +}; diff --git a/test/fixture/compile/comparator_param_covariant_upcast/verify/runtime.php b/test/fixture/compile/comparator_param_covariant_upcast/verify/runtime.php index 4141f308..bdda7bbc 100644 --- a/test/fixture/compile/comparator_param_covariant_upcast/verify/runtime.php +++ b/test/fixture/compile/comparator_param_covariant_upcast/verify/runtime.php @@ -15,13 +15,15 @@ * sound; the fix routes the nested `Comparator` verdict through the composing variance pass, which * accepts it. That the program runs and `pick` returns the max Book proves the acceptance is sound. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertInstanceOf(\App\Book::class, $best, 'pick returned a Book element through the upcast'); -Assert::assertSame(3, $best->id, 'pick selected the max-id Book via the Product comparator'); -echo "OK\n"; + Assert::assertInstanceOf(\App\Book::class, $best, 'pick returned a Book element through the upcast'); + Assert::assertSame(3, $best->id, 'pick selected the max-id Book via the Product comparator'); +}; diff --git a/test/fixture/compile/covariant_gapfill_free_symbol/verify/runtime.php b/test/fixture/compile/covariant_gapfill_free_symbol/verify/runtime.php index 7dbef1cc..20fea719 100644 --- a/test/fixture/compile/covariant_gapfill_free_symbol/verify/runtime.php +++ b/test/fixture/compile/covariant_gapfill_free_symbol/verify/runtime.php @@ -10,14 +10,16 @@ * upcast `indexOf` (via Bag) returns -OFFSET + tally(3) = 1 for the absent tuple. A bare reference that * rebinds to the generated namespace would fatal ("undefined function XPHP\Generated\App\Lst\tally"). * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -// Free functions/consts aren't autoloadable, so define them before Use.php runs. -require $fixture->targetDir . '/helpers.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + // Free functions/consts aren't autoloadable, so define them before Use.php runs. + require $fixture->targetDir . '/helpers.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($found, 'the upcast contains-call (via Lst) must bind the App free symbols and report the tuple absent'); -Assert::assertSame(1, $index, 'the upcast indexOf-call (via Bag) must compute -OFFSET + tally(3) = 1 for the absent tuple'); -echo "OK\n"; + Assert::assertTrue($found, 'the upcast contains-call (via Lst) must bind the App free symbols and report the tuple absent'); + Assert::assertSame(1, $index, 'the upcast indexOf-call (via Bag) must compute -OFFSET + tally(3) = 1 for the absent tuple'); +}; diff --git a/test/fixture/compile/covariant_upcast_multipath_diamond/verify/runtime.php b/test/fixture/compile/covariant_upcast_multipath_diamond/verify/runtime.php index be7282d5..e5296d9b 100644 --- a/test/fixture/compile/covariant_upcast_multipath_diamond/verify/runtime.php +++ b/test/fixture/compile/covariant_upcast_multipath_diamond/verify/runtime.php @@ -10,10 +10,13 @@ * `contains` (via Lst) and an upcast `indexOf` (via Bag) both resolve and run proves the gap-fill supplies * every diamond sibling across interfaces and concretes, independent of discovery order. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; -require $fixture->targetDir . '/Use.php'; -Assert::assertFalse($found, 'the upcast contains-call (via Lst) must resolve, run, and report the tuple absent'); -Assert::assertSame(-1, $index, 'the upcast indexOf-call (via Bag) must resolve, run, and report the tuple absent'); -echo "OK\n"; +use XPHP\TestSupport\CompiledFixture; + +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; + Assert::assertFalse($found, 'the upcast contains-call (via Lst) must resolve, run, and report the tuple absent'); + Assert::assertSame(-1, $index, 'the upcast indexOf-call (via Bag) must resolve, run, and report the tuple absent'); +}; diff --git a/test/fixture/compile/covariant_upcast_nested_generic_diamond/verify/runtime.php b/test/fixture/compile/covariant_upcast_nested_generic_diamond/verify/runtime.php index 1d1ad59a..8f0bded4 100644 --- a/test/fixture/compile/covariant_upcast_nested_generic_diamond/verify/runtime.php +++ b/test/fixture/compile/covariant_upcast_nested_generic_diamond/verify/runtime.php @@ -8,9 +8,12 @@ * `contains_>` sibling unimplemented) and fataled at class load. That it loads and * `probe` returns proves the gap-fill supplied every diamond obligation. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; -require $fixture->targetDir . '/Use.php'; -Assert::assertFalse($found, 'the diamond upcast contains-call must resolve, run, and report the tuple absent'); -echo "OK\n"; +use XPHP\TestSupport\CompiledFixture; + +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; + Assert::assertFalse($found, 'the diamond upcast contains-call must resolve, run, and report the tuple absent'); +}; diff --git a/test/fixture/compile/covariant_upcast_return_enclosing_inherited/verify/runtime.php b/test/fixture/compile/covariant_upcast_return_enclosing_inherited/verify/runtime.php index 7dd2b266..410988df 100644 --- a/test/fixture/compile/covariant_upcast_return_enclosing_inherited/verify/runtime.php +++ b/test/fixture/compile/covariant_upcast_return_enclosing_inherited/verify/runtime.php @@ -8,9 +8,12 @@ * emission; the post-edge gap-fill must recognise it as already provided and leave it alone. That this * compiles, loads, and `probe` returns the stored Book proves A3 does not over-emit a return-E member. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; -require $fixture->targetDir . '/Use.php'; -Assert::assertInstanceOf(\App\Book::class, $first, 'firstOr returns the stored Book through the covariant upcast'); -echo "OK\n"; +use XPHP\TestSupport\CompiledFixture; + +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; + Assert::assertInstanceOf(\App\Book::class, $first, 'firstOr returns the stored Book through the covariant upcast'); +}; diff --git a/test/fixture/compile/cross_template_generic_arg_upcast/verify/runtime.php b/test/fixture/compile/cross_template_generic_arg_upcast/verify/runtime.php index ce573390..81d0751f 100644 --- a/test/fixture/compile/cross_template_generic_arg_upcast/verify/runtime.php +++ b/test/fixture/compile/cross_template_generic_arg_upcast/verify/runtime.php @@ -16,12 +16,14 @@ * That the program loads, the call resolves, and `first()` returns the Book proves the cross-template * edge was emitted and the covariance holds at runtime — not just at `check`. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertInstanceOf(\App\Book::class, $first, 'the upcast tuple resolved and yielded its Book element'); -echo "OK\n"; + Assert::assertInstanceOf(\App\Book::class, $first, 'the upcast tuple resolved and yielded its Book element'); +}; diff --git a/test/fixture/compile/enclosing_bound_erasure_covariant_chain/verify/runtime.php b/test/fixture/compile/enclosing_bound_erasure_covariant_chain/verify/runtime.php index bec2d846..088b6830 100644 --- a/test/fixture/compile/enclosing_bound_erasure_covariant_chain/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_erasure_covariant_chain/verify/runtime.php @@ -11,13 +11,16 @@ * Box used where a Box is expected dispatches the inherited `contains_`. * That this loads and runs proves erasure is variance-safe through the real pipeline. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($viaCovariance, 'a Box via the Box view runs the inherited contains_'); -Assert::assertTrue($direct); -Assert::assertTrue($isCovariant, 'Box must be an instanceof the Box marker'); + Assert::assertTrue($viaCovariance, 'a Box via the Box view runs the inherited contains_'); + Assert::assertTrue($direct); + Assert::assertTrue($isCovariant, 'Box must be an instanceof the Box marker'); +}; diff --git a/test/fixture/compile/enclosing_bound_erasure_forwarding/verify/runtime.php b/test/fixture/compile/enclosing_bound_erasure_forwarding/verify/runtime.php index aca06612..774d5bb4 100644 --- a/test/fixture/compile/enclosing_bound_erasure_forwarding/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_erasure_forwarding/verify/runtime.php @@ -11,12 +11,15 @@ * `$this->contains(...)` (the old silent break), this would fatal with "undefined method" the * moment `probe` ran. That it runs and returns the contained-element verdict proves the lowering. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($viaForward, 'forwarded self-call must resolve to the emitted contains_ method'); -Assert::assertTrue($viaDirect, 'a direct erasable call must run too'); + Assert::assertTrue($viaForward, 'forwarded self-call must resolve to the emitted contains_ method'); + Assert::assertTrue($viaDirect, 'a direct erasable call must run too'); +}; diff --git a/test/fixture/compile/enclosing_bound_erasure_inherited/verify/runtime.php b/test/fixture/compile/enclosing_bound_erasure_inherited/verify/runtime.php index 4fffa588..8c92cb4f 100644 --- a/test/fixture/compile/enclosing_bound_erasure_inherited/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_erasure_inherited/verify/runtime.php @@ -11,11 +11,14 @@ * this is the cross-cutting mangling invariant where call-site and Specializer name computation could * silently drift. That the call resolves and runs proves they agree. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($inherited, 'inherited erasable member must resolve via the same E-mangled name'); + Assert::assertTrue($inherited, 'inherited erasable member must resolve via the same E-mangled name'); +}; diff --git a/test/fixture/compile/enclosing_bound_erasure_map_multiparam/verify/runtime.php b/test/fixture/compile/enclosing_bound_erasure_map_multiparam/verify/runtime.php index 33ce0c1e..c6d1c5fc 100644 --- a/test/fixture/compile/enclosing_bound_erasure_map_multiparam/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_erasure_map_multiparam/verify/runtime.php @@ -10,12 +10,15 @@ * V) and the Specializer must agree on that key. That the call resolves and runs proves the * multi-class-param mangle keys on the bound's referent. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($found, 'containsValue mangled on V (Fruit) must resolve and run'); -Assert::assertSame('k', $label); + Assert::assertTrue($found, 'containsValue mangled on V (Fruit) must resolve and run'); + Assert::assertSame('k', $label); +}; diff --git a/test/fixture/compile/enclosing_bound_erasure_param_widening/verify/runtime.php b/test/fixture/compile/enclosing_bound_erasure_param_widening/verify/runtime.php index bbb51c83..f74a2e3a 100644 --- a/test/fixture/compile/enclosing_bound_erasure_param_widening/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_erasure_param_widening/verify/runtime.php @@ -10,12 +10,15 @@ * (Banana, Cherry) both lower to that single member, which accepts each as a Fruit. Both calls * running proves the per-E collapse and the param widening. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($banana, 'contains:: runs on the widened Fruit-typed member'); -Assert::assertTrue($cherry, 'contains:: runs on the SAME widened member'); + Assert::assertTrue($banana, 'contains:: runs on the widened Fruit-typed member'); + Assert::assertTrue($cherry, 'contains:: runs on the SAME widened member'); +}; diff --git a/test/fixture/compile/enclosing_bound_erasure_two_params/verify/runtime.php b/test/fixture/compile/enclosing_bound_erasure_two_params/verify/runtime.php index 1b3f6507..d8eda5fc 100644 --- a/test/fixture/compile/enclosing_bound_erasure_two_params/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_erasure_two_params/verify/runtime.php @@ -9,11 +9,14 @@ * `[E, E]`. Both parameters widen to the bound (Fruit), so `bothAreFruit::` resolves * to the one emitted member and runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($both, 'a two-bounded-param erasable method must resolve and run'); + Assert::assertTrue($both, 'a two-bounded-param erasable method must resolve and run'); +}; diff --git a/test/fixture/compile/enclosing_bound_interface_upcast/verify/runtime.php b/test/fixture/compile/enclosing_bound_interface_upcast/verify/runtime.php index 5c068787..aab27a4a 100644 --- a/test/fixture/compile/enclosing_bound_interface_upcast/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_interface_upcast/verify/runtime.php @@ -15,12 +15,14 @@ * covariant chain inherited it. `probe` looks for a fresh Product in a list holding one Book, so the * expected answer is false — the point is that the call resolves and runs at all. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertFalse($found, 'the upcast contains-call must resolve, run, and report the Product absent'); -echo "OK\n"; + Assert::assertFalse($found, 'the upcast contains-call must resolve, run, and report the Product absent'); +}; diff --git a/test/fixture/compile/enclosing_bound_interface_upcast_map/verify/runtime.php b/test/fixture/compile/enclosing_bound_interface_upcast_map/verify/runtime.php index 5cbde100..75c6df57 100644 --- a/test/fixture/compile/enclosing_bound_interface_upcast_map/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_interface_upcast_map/verify/runtime.php @@ -10,12 +10,14 @@ * — varying only the covariant V to the supertype arg while keeping the invariant K = Id — with NO * explicit `HashMap` anywhere. Executing the output proves the threading is correct. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertFalse($found, 'the multi-param upcast containsValue-call must resolve and run'); -echo "OK\n"; + Assert::assertFalse($found, 'the multi-param upcast containsValue-call must resolve and run'); +}; diff --git a/test/fixture/compile/enclosing_bound_subinterface_direct_emit/verify/runtime.php b/test/fixture/compile/enclosing_bound_subinterface_direct_emit/verify/runtime.php index c0368eba..42b0da70 100644 --- a/test/fixture/compile/enclosing_bound_subinterface_direct_emit/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_subinterface_direct_emit/verify/runtime.php @@ -11,13 +11,15 @@ * `Product` and the body reading the inherited `Book`-typed `$items` (Book <: Product). `contains` still * resolves via the inheritance path. That both calls run proves direct emission and inheritance coexist. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(-1, $idx, 'indexOf via direct emission must resolve, run, and report the fresh Product absent'); -Assert::assertFalse($has, 'contains via inheritance must still resolve'); -echo "OK\n"; + Assert::assertSame(-1, $idx, 'indexOf via direct emission must resolve, run, and report the fresh Product absent'); + Assert::assertFalse($has, 'contains via inheritance must still resolve'); +}; diff --git a/test/fixture/compile/enclosing_bound_subinterface_structural_class_param/verify/runtime.php b/test/fixture/compile/enclosing_bound_subinterface_structural_class_param/verify/runtime.php index 16e5a08c..768958be 100644 --- a/test/fixture/compile/enclosing_bound_subinterface_structural_class_param/verify/runtime.php +++ b/test/fixture/compile/enclosing_bound_subinterface_structural_class_param/verify/runtime.php @@ -11,12 +11,14 @@ * split substitution were wrong and `E` resolved to `Product`, it would be `$value instanceof Product` → * true. The false answer proves the class `E` was substituted with `Book`, not `Product`. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertFalse($result, 'the body class parameter E must substitute to the upcast-source concrete (Book), not the supertype (Product)'); -echo "OK\n"; + Assert::assertFalse($result, 'the body class parameter E must substitute to the upcast-source concrete (Book), not the supertype (Product)'); +}; diff --git a/test/fixture/compile/free_symbol_group_use_import/verify/runtime.php b/test/fixture/compile/free_symbol_group_use_import/verify/runtime.php index 212ea91d..840bdde8 100644 --- a/test/fixture/compile/free_symbol_group_use_import/verify/runtime.php +++ b/test/fixture/compile/free_symbol_group_use_import/verify/runtime.php @@ -7,12 +7,15 @@ * and `use Vendor\{const RATE, const STEP}` imports in the template resolve to Vendor's symbols, and * the relocated specialization still binds them. make(3)=6 + scale(1)=10 + RATE=100 + STEP=7 = 123. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoloader registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoloader registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/lib.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/lib.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(123, $computed); + Assert::assertSame(123, $computed); +}; diff --git a/test/fixture/compile/free_symbol_requalify/verify/runtime.php b/test/fixture/compile/free_symbol_requalify/verify/runtime.php index a05f1651..688e370b 100644 --- a/test/fixture/compile/free_symbol_requalify/verify/runtime.php +++ b/test/fixture/compile/free_symbol_requalify/verify/runtime.php @@ -8,15 +8,18 @@ * builtin and magic constant left to global resolution. * scale(1)=10, BONUS=5, Sub\tweak(2)=3, strlen('ab')=2, true?0 -> 10+5+3+2+0 = 20 * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoloader registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoloader registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -// Free functions/consts aren't autoloadable, so define them before Use.php runs its -// top-level instantiation (the specialized class itself autoloads via PSR-4). -require $fixture->targetDir . '/helpers.php'; -require $fixture->targetDir . '/sub.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + // Free functions/consts aren't autoloadable, so define them before Use.php runs its + // top-level instantiation (the specialized class itself autoloads via PSR-4). + require $fixture->targetDir . '/helpers.php'; + require $fixture->targetDir . '/sub.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(20, $result); + Assert::assertSame(20, $result); +}; diff --git a/test/fixture/compile/free_symbol_use_import/verify/runtime.php b/test/fixture/compile/free_symbol_use_import/verify/runtime.php index c4a8a686..6cb3c936 100644 --- a/test/fixture/compile/free_symbol_use_import/verify/runtime.php +++ b/test/fixture/compile/free_symbol_use_import/verify/runtime.php @@ -7,12 +7,15 @@ * template resolves to another namespace's symbols, and the relocated specialization still * binds them. make(3)=6, RATE=100 -> 106. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoloader registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoloader registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/lib.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/lib.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(106, $computed); + Assert::assertSame(106, $computed); +}; diff --git a/test/fixture/compile/generic_covariant_immutable_constructor/verify/runtime.php b/test/fixture/compile/generic_covariant_immutable_constructor/verify/runtime.php index 8bac4c9f..c4845803 100644 --- a/test/fixture/compile/generic_covariant_immutable_constructor/verify/runtime.php +++ b/test/fixture/compile/generic_covariant_immutable_constructor/verify/runtime.php @@ -10,7 +10,7 @@ * type on each specialization (no erasure), and that real type is enforced by * PHP at construction — passing a non-Banana to `ImmutableList` throws. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use App\CovariantConstructor\Banana; @@ -18,26 +18,29 @@ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(2, $cnt); -Assert::assertSame('banana', $name); + Assert::assertSame(2, $cnt); + Assert::assertSame('banana', $name); -// The constructor element type is REAL (not erased to `mixed`) and runtime-checked: -// an `ImmutableList` rejects a plain `Fruit` at construction. -$bananaListFqn = Registry::generatedFqn( - 'App\\CovariantConstructor\\ImmutableList', - [new TypeRef('App\\CovariantConstructor\\Banana')], -); -$threw = false; -try { - new $bananaListFqn(new Fruit('apple')); -} catch (\TypeError) { - $threw = true; -} -Assert::assertTrue($threw, 'ImmutableList must reject a non-Banana element at construction'); + // The constructor element type is REAL (not erased to `mixed`) and runtime-checked: + // an `ImmutableList` rejects a plain `Fruit` at construction. + $bananaListFqn = Registry::generatedFqn( + 'App\\CovariantConstructor\\ImmutableList', + [new TypeRef('App\\CovariantConstructor\\Banana')], + ); + $threw = false; + try { + new $bananaListFqn(new Fruit('apple')); + } catch (\TypeError) { + $threw = true; + } + Assert::assertTrue($threw, 'ImmutableList must reject a non-Banana element at construction'); -// And it accepts a real Banana. -$ok = new $bananaListFqn(new Banana()); -Assert::assertSame('banana', $ok->get(0)->name); + // And it accepts a real Banana. + $ok = new $bananaListFqn(new Banana()); + Assert::assertSame('banana', $ok->get(0)->name); +}; diff --git a/test/fixture/compile/generic_covariant_private_property/verify/runtime.php b/test/fixture/compile/generic_covariant_private_property/verify/runtime.php index d47479a6..41ecedc9 100644 --- a/test/fixture/compile/generic_covariant_private_property/verify/runtime.php +++ b/test/fixture/compile/generic_covariant_private_property/verify/runtime.php @@ -12,7 +12,7 @@ * (covariant `get(): T`), and the constructor keeps its REAL element type so * construction is runtime-type-checked. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use App\CovariantPrivateProperty\Banana; @@ -20,35 +20,38 @@ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; - -require $fixture->targetDir . '/Use.php'; - -// Covariant use worked: a Box flowed into a Box parameter and the -// element read back through `get(): T`. -Assert::assertSame('banana', $name); - -$bananaBoxFqn = Registry::generatedFqn( - 'App\\CovariantPrivateProperty\\Box', - [new TypeRef('App\\CovariantPrivateProperty\\Banana')], -); -$fruitBoxFqn = Registry::generatedFqn( - 'App\\CovariantPrivateProperty\\Box', - [new TypeRef('App\\CovariantPrivateProperty\\Fruit')], -); - -// The private slot type is REAL (not erased to `mixed`) and runtime-checked at -// construction: a `Box` rejects a plain `Fruit`. -$threw = false; -try { - new $bananaBoxFqn(new Fruit('apple')); -} catch (\TypeError) { - $threw = true; -} -Assert::assertTrue($threw, 'Box must reject a non-Banana element at construction'); - -// And it accepts a real Banana, exposing it through the covariant getter. -$ok = new $bananaBoxFqn(new Banana()); -Assert::assertSame('banana', $ok->get()->name); - -// The covariant edge is real: a Box IS a Box at the type level. -Assert::assertInstanceOf($fruitBoxFqn, $ok); +use XPHP\TestSupport\CompiledFixture; + +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; + + // Covariant use worked: a Box flowed into a Box parameter and the + // element read back through `get(): T`. + Assert::assertSame('banana', $name); + + $bananaBoxFqn = Registry::generatedFqn( + 'App\\CovariantPrivateProperty\\Box', + [new TypeRef('App\\CovariantPrivateProperty\\Banana')], + ); + $fruitBoxFqn = Registry::generatedFqn( + 'App\\CovariantPrivateProperty\\Box', + [new TypeRef('App\\CovariantPrivateProperty\\Fruit')], + ); + + // The private slot type is REAL (not erased to `mixed`) and runtime-checked at + // construction: a `Box` rejects a plain `Fruit`. + $threw = false; + try { + new $bananaBoxFqn(new Fruit('apple')); + } catch (\TypeError) { + $threw = true; + } + Assert::assertTrue($threw, 'Box must reject a non-Banana element at construction'); + + // And it accepts a real Banana, exposing it through the covariant getter. + $ok = new $bananaBoxFqn(new Banana()); + Assert::assertSame('banana', $ok->get()->name); + + // The covariant edge is real: a Box IS a Box at the type level. + Assert::assertInstanceOf($fruitBoxFqn, $ok); +}; diff --git a/test/fixture/compile/generic_exception_catch/verify/catch_runtime.php b/test/fixture/compile/generic_exception_catch/verify/catch_runtime.php index c04b177d..e8564e4c 100644 --- a/test/fixture/compile/generic_exception_catch/verify/catch_runtime.php +++ b/test/fixture/compile/generic_exception_catch/verify/catch_runtime.php @@ -7,7 +7,7 @@ * generic specialization (`HttpError` vs `HttpError`) * discriminates on the concrete monomorphized class, so the right arm fires. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered * for `App\GenericExceptionCatch\` + the generated namespace. */ @@ -15,36 +15,39 @@ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; - -$client = new Client(); - -// Generic type discriminates: the Forbidden throw must skip the textually -// FIRST `HttpError` arm and land on `HttpError`. This is -// the property that would silently break if catch types stopped being -// rewritten to their distinct specialized FQNs. -Assert::assertSame('forbidden:api key revoked', $client->classify('forbidden')); -Assert::assertSame('not-found:missing', $client->classify('notfound')); - -// Bare `catch (HttpError $e)` catches any specialization via the marker -// interface. The caught object is the concrete Forbidden specialization. -$forbiddenFqn = Registry::generatedFqn( - 'App\\GenericExceptionCatch\\Errors\\HttpError', - [new TypeRef('App\\GenericExceptionCatch\\Models\\Forbidden')], -); -Assert::assertSame($forbiddenFqn, $client->catchAny('forbidden')); - -// A union of two specializations matches either thrown error. -Assert::assertSame('union:missing', $client->catchUnion('notfound')); -Assert::assertSame('union:api key revoked', $client->catchUnion('forbidden')); - -// The specialization is a genuine Throwable subtype (so it is catchable at all) -// AND implements the original generic name as a marker interface (so the bare -// catch-all arm above can match it). -Assert::assertTrue( - is_subclass_of($forbiddenFqn, \RuntimeException::class), - 'specialized exception must remain a RuntimeException subtype', -); -Assert::assertTrue( - is_subclass_of($forbiddenFqn, 'App\\GenericExceptionCatch\\Errors\\HttpError'), - 'specialized exception must implement the HttpError marker interface', -); +use XPHP\TestSupport\CompiledFixture; + +return function (CompiledFixture $fixture): void { + $client = new Client(); + + // Generic type discriminates: the Forbidden throw must skip the textually + // FIRST `HttpError` arm and land on `HttpError`. This is + // the property that would silently break if catch types stopped being + // rewritten to their distinct specialized FQNs. + Assert::assertSame('forbidden:api key revoked', $client->classify('forbidden')); + Assert::assertSame('not-found:missing', $client->classify('notfound')); + + // Bare `catch (HttpError $e)` catches any specialization via the marker + // interface. The caught object is the concrete Forbidden specialization. + $forbiddenFqn = Registry::generatedFqn( + 'App\\GenericExceptionCatch\\Errors\\HttpError', + [new TypeRef('App\\GenericExceptionCatch\\Models\\Forbidden')], + ); + Assert::assertSame($forbiddenFqn, $client->catchAny('forbidden')); + + // A union of two specializations matches either thrown error. + Assert::assertSame('union:missing', $client->catchUnion('notfound')); + Assert::assertSame('union:api key revoked', $client->catchUnion('forbidden')); + + // The specialization is a genuine Throwable subtype (so it is catchable at all) + // AND implements the original generic name as a marker interface (so the bare + // catch-all arm above can match it). + Assert::assertTrue( + is_subclass_of($forbiddenFqn, \RuntimeException::class), + 'specialized exception must remain a RuntimeException subtype', + ); + Assert::assertTrue( + is_subclass_of($forbiddenFqn, 'App\\GenericExceptionCatch\\Errors\\HttpError'), + 'specialized exception must implement the HttpError marker interface', + ); +}; diff --git a/test/fixture/compile/generic_function/verify/runtime_execution.php b/test/fixture/compile/generic_function/verify/runtime_execution.php index 5d4fb479..d5858b29 100644 --- a/test/fixture/compile/generic_function/verify/runtime_execution.php +++ b/test/fixture/compile/generic_function/verify/runtime_execution.php @@ -7,7 +7,7 @@ * `identity_T_` free functions execute and return values of * the substituted concrete types. * - * Driver contract: `$fixture` (CompiledFixture) in scope. Free + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. Free * functions aren't autoloadable in PHP, so require funcs.php * explicitly to bring the specialized declarations into scope. */ @@ -15,15 +15,18 @@ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/funcs.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/funcs.php'; -$intMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('int', isScalar: true)]); -$intFqn = 'App\\GenericFunction\\' . $intMangle; -$intResult = $intFqn(42); -Assert::assertSame(42, $intResult); + $intMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('int', isScalar: true)]); + $intFqn = 'App\\GenericFunction\\' . $intMangle; + $intResult = $intFqn(42); + Assert::assertSame(42, $intResult); -$stringMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('string', isScalar: true)]); -$stringFqn = 'App\\GenericFunction\\' . $stringMangle; -$stringResult = $stringFqn('hi'); -Assert::assertSame('hi', $stringResult); + $stringMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('string', isScalar: true)]); + $stringFqn = 'App\\GenericFunction\\' . $stringMangle; + $stringResult = $stringFqn('hi'); + Assert::assertSame('hi', $stringResult); +}; diff --git a/test/fixture/compile/generic_function_bare_top_level/verify/runtime.php b/test/fixture/compile/generic_function_bare_top_level/verify/runtime.php index ceb61746..2f33c0f5 100644 --- a/test/fixture/compile/generic_function_bare_top_level/verify/runtime.php +++ b/test/fixture/compile/generic_function_bare_top_level/verify/runtime.php @@ -7,16 +7,19 @@ * top-level generic function specializes; the non-generic sibling * function survives the strip pass intact; both call sites resolve. * - * Driver contract: `$fixture` (CompiledFixture) in scope. Bare- + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. Bare- * top-level functions aren't autoloadable, so requiring funcs.php * is the only way to bring `identity_T_` and * `nonGenericDouble` into scope. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/funcs.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/funcs.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $asInt); -Assert::assertSame(42, $doubled); + Assert::assertSame(42, $asInt); + Assert::assertSame(42, $doubled); +}; diff --git a/test/fixture/compile/generic_interface/verify/specialized_interface_runtime.php b/test/fixture/compile/generic_interface/verify/specialized_interface_runtime.php index 08875ba5..0b9cbd38 100644 --- a/test/fixture/compile/generic_interface/verify/specialized_interface_runtime.php +++ b/test/fixture/compile/generic_interface/verify/specialized_interface_runtime.php @@ -7,30 +7,33 @@ * implements the specialized interface, and the interface's * `get()` reflection reports the concrete substituted return type. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload * registered for `App\GenericInterface\` + the generated namespace. */ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -$interfaceFqn = Registry::generatedFqn( - 'App\\GenericInterface\\Containers\\Container', - [new TypeRef('App\\GenericInterface\\Models\\Plastic')], -); -$boxFqn = Registry::generatedFqn( - 'App\\GenericInterface\\Containers\\Box', - [new TypeRef('App\\GenericInterface\\Models\\Plastic')], -); +return function (CompiledFixture $fixture): void { + $interfaceFqn = Registry::generatedFqn( + 'App\\GenericInterface\\Containers\\Container', + [new TypeRef('App\\GenericInterface\\Models\\Plastic')], + ); + $boxFqn = Registry::generatedFqn( + 'App\\GenericInterface\\Containers\\Box', + [new TypeRef('App\\GenericInterface\\Models\\Plastic')], + ); -$box = new $boxFqn(new \App\GenericInterface\Models\Plastic('red')); + $box = new $boxFqn(new \App\GenericInterface\Models\Plastic('red')); -Assert::assertInstanceOf($interfaceFqn, $box); -Assert::assertSame('red', $box->get()->color); + Assert::assertInstanceOf($interfaceFqn, $box); + Assert::assertSame('red', $box->get()->color); -// Reflection: the interface's get() return type must be the -// concrete substituted class, not the unspecialized `T`. -$returnType = (new \ReflectionMethod($interfaceFqn, 'get'))->getReturnType(); -Assert::assertInstanceOf(\ReflectionNamedType::class, $returnType); -Assert::assertSame('App\\GenericInterface\\Models\\Plastic', $returnType->getName()); + // Reflection: the interface's get() return type must be the + // concrete substituted class, not the unspecialized `T`. + $returnType = (new \ReflectionMethod($interfaceFqn, 'get'))->getReturnType(); + Assert::assertInstanceOf(\ReflectionNamedType::class, $returnType); + Assert::assertSame('App\\GenericInterface\\Models\\Plastic', $returnType->getName()); +}; diff --git a/test/fixture/compile/generic_method/verify/runtime.php b/test/fixture/compile/generic_method/verify/runtime.php index d3381b25..0464077b 100644 --- a/test/fixture/compile/generic_method/verify/runtime.php +++ b/test/fixture/compile/generic_method/verify/runtime.php @@ -7,24 +7,27 @@ * `Util::identity_T_` static methods round-trip their argument * through the substituted concrete type. * - * Driver contract: `$fixture` (CompiledFixture) in scope. Static + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. Static * methods on user classes load via the registered autoloader. */ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Util.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Util.php'; -$intMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('int', isScalar: true)]); -$intCallable = ['App\\GenericMethod\\Util', $intMangle]; -$intResult = $intCallable(42); -Assert::assertSame(42, $intResult); -Assert::assertSame('integer', gettype($intResult)); + $intMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('int', isScalar: true)]); + $intCallable = ['App\\GenericMethod\\Util', $intMangle]; + $intResult = $intCallable(42); + Assert::assertSame(42, $intResult); + Assert::assertSame('integer', gettype($intResult)); -$stringMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('string', isScalar: true)]); -$stringCallable = ['App\\GenericMethod\\Util', $stringMangle]; -$stringResult = $stringCallable('hello'); -Assert::assertSame('hello', $stringResult); -Assert::assertSame('string', gettype($stringResult)); + $stringMangle = 'identity_T_' . Registry::canonicalHash([new TypeRef('string', isScalar: true)]); + $stringCallable = ['App\\GenericMethod\\Util', $stringMangle]; + $stringResult = $stringCallable('hello'); + Assert::assertSame('hello', $stringResult); + Assert::assertSame('string', gettype($stringResult)); +}; diff --git a/test/fixture/compile/generic_method_local_variable_receiver/verify/runtime.php b/test/fixture/compile/generic_method_local_variable_receiver/verify/runtime.php index 551a03d1..b76f045b 100644 --- a/test/fixture/compile/generic_method_local_variable_receiver/verify/runtime.php +++ b/test/fixture/compile/generic_method_local_variable_receiver/verify/runtime.php @@ -8,13 +8,16 @@ * `$u->identity::(…)` specialize against Util via the visitor's * lexical-last-write record. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Util.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Util.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(99, $i); -Assert::assertSame('world', $s); + Assert::assertSame(99, $i); + Assert::assertSame('world', $s); +}; diff --git a/test/fixture/compile/generic_method_new_self_turbofish/verify/runtime.php b/test/fixture/compile/generic_method_new_self_turbofish/verify/runtime.php index 355387c0..c332e26d 100644 --- a/test/fixture/compile/generic_method_new_self_turbofish/verify/runtime.php +++ b/test/fixture/compile/generic_method_new_self_turbofish/verify/runtime.php @@ -9,21 +9,24 @@ * specialized class — so `$a->with(13)` returns a `Container` * with `item = 13`, the same class as `$a`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Container.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Container.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(13, $b->item); -Assert::assertSame(get_class($a), get_class($b)); + Assert::assertSame(13, $b->item); + Assert::assertSame(get_class($a), get_class($b)); -$specializedFqn = Registry::generatedFqn( - 'App\\GenericMethodNewSelfTurbofish\\Container', - [new TypeRef('int', isScalar: true)], -); -Assert::assertSame($specializedFqn, get_class($a)); + $specializedFqn = Registry::generatedFqn( + 'App\\GenericMethodNewSelfTurbofish\\Container', + [new TypeRef('int', isScalar: true)], + ); + Assert::assertSame($specializedFqn, get_class($a)); +}; diff --git a/test/fixture/compile/generic_method_new_static_turbofish/verify/runtime.php b/test/fixture/compile/generic_method_new_static_turbofish/verify/runtime.php index 610f6978..d98696af 100644 --- a/test/fixture/compile/generic_method_new_static_turbofish/verify/runtime.php +++ b/test/fixture/compile/generic_method_new_static_turbofish/verify/runtime.php @@ -8,21 +8,24 @@ * binding resolves `static` against the specialized class. With no * subclassing in this fixture, `$a` and `$b` end up in the same class. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Builder.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Builder.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(2, $b->value); -Assert::assertSame(get_class($a), get_class($b)); + Assert::assertSame(2, $b->value); + Assert::assertSame(get_class($a), get_class($b)); -$specializedFqn = Registry::generatedFqn( - 'App\\GenericMethodNewStaticTurbofish\\Builder', - [new TypeRef('int', isScalar: true)], -); -Assert::assertSame($specializedFqn, get_class($a)); + $specializedFqn = Registry::generatedFqn( + 'App\\GenericMethodNewStaticTurbofish\\Builder', + [new TypeRef('int', isScalar: true)], + ); + Assert::assertSame($specializedFqn, get_class($a)); +}; diff --git a/test/fixture/compile/generic_method_self_with_type_args/verify/runtime.php b/test/fixture/compile/generic_method_self_with_type_args/verify/runtime.php index de51b5b1..bf96a1fd 100644 --- a/test/fixture/compile/generic_method_self_with_type_args/verify/runtime.php +++ b/test/fixture/compile/generic_method_self_with_type_args/verify/runtime.php @@ -8,7 +8,7 @@ * specialization, so `Container::withItem(2)` mutates and * returns `$this` with `item = 2`. * - * Driver contract: `$fixture` (CompiledFixture) in scope. The + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. The * autoloader resolves `App\GenericMethodSelfReturnTypeArgs\Container` * (an interface stub) plus the generated `T_` class. */ @@ -16,16 +16,19 @@ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Container.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Container.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(2, $b->item); + Assert::assertSame(2, $b->item); -// The specialized class lives under XPHP\Generated\…\Container\T_. -$specializedFqn = Registry::generatedFqn( - 'App\\GenericMethodSelfReturnTypeArgs\\Container', - [new TypeRef('int', isScalar: true)], -); -Assert::assertTrue(class_exists($specializedFqn)); -Assert::assertInstanceOf($specializedFqn, $b); + // The specialized class lives under XPHP\Generated\…\Container\T_. + $specializedFqn = Registry::generatedFqn( + 'App\\GenericMethodSelfReturnTypeArgs\\Container', + [new TypeRef('int', isScalar: true)], + ); + Assert::assertTrue(class_exists($specializedFqn)); + Assert::assertInstanceOf($specializedFqn, $b); +}; diff --git a/test/fixture/compile/generic_method_this_receiver/verify/runtime.php b/test/fixture/compile/generic_method_this_receiver/verify/runtime.php index 059c40ab..a5159a99 100644 --- a/test/fixture/compile/generic_method_this_receiver/verify/runtime.php +++ b/test/fixture/compile/generic_method_this_receiver/verify/runtime.php @@ -8,13 +8,16 @@ * the enclosing class (no flow analysis needed), so the int and * string call sites each land on their own mangled method. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Util.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Util.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(42, $i); -Assert::assertSame('hi', $s); + Assert::assertSame(42, $i); + Assert::assertSame('hi', $s); +}; diff --git a/test/fixture/compile/generic_method_through_inheritance/verify/runtime.php b/test/fixture/compile/generic_method_through_inheritance/verify/runtime.php index a2759368..d69b7193 100644 --- a/test/fixture/compile/generic_method_through_inheritance/verify/runtime.php +++ b/test/fixture/compile/generic_method_through_inheritance/verify/runtime.php @@ -9,12 +9,15 @@ * receiver. The specialization is emitted onto the declaring base and * inherited through the class-level `extends` edge. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('hi', $s); -Assert::assertSame(7, $n); + Assert::assertSame('hi', $s); + Assert::assertSame(7, $n); +}; diff --git a/test/fixture/compile/generic_static_method_through_inheritance/verify/runtime.php b/test/fixture/compile/generic_static_method_through_inheritance/verify/runtime.php index 6c71aeea..61ebfb99 100644 --- a/test/fixture/compile/generic_static_method_through_inheritance/verify/runtime.php +++ b/test/fixture/compile/generic_static_method_through_inheritance/verify/runtime.php @@ -8,14 +8,17 @@ * called as `Derived::make::<...>()` on a subclass. The specialization is emitted * onto Base and reached through PHP's static-method inheritance. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Base.php'; -require $fixture->targetDir . '/Derived.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Base.php'; + require $fixture->targetDir . '/Derived.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('hi', $s); -Assert::assertSame(7, $n); + Assert::assertSame('hi', $s); + Assert::assertSame(7, $n); +}; diff --git a/test/fixture/compile/generic_trait_adaptation/verify/runtime.php b/test/fixture/compile/generic_trait_adaptation/verify/runtime.php index 6a2e7e4b..dc4b451a 100644 --- a/test/fixture/compile/generic_trait_adaptation/verify/runtime.php +++ b/test/fixture/compile/generic_trait_adaptation/verify/runtime.php @@ -11,14 +11,17 @@ * `use`-list entries -- a bare operand would fatal at class load ("Trait App\... not * found"). * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoloader registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoloader registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('A:5', $pick); // insteadof: A's pick wins -Assert::assertSame('B:6', $bpick); // as: B's pick reachable under the alias -Assert::assertSame(3, $aOnly); // A's distinct method -Assert::assertSame(4, $bOnly); // B's distinct method + Assert::assertSame('A:5', $pick); // insteadof: A's pick wins + Assert::assertSame('B:6', $bpick); // as: B's pick reachable under the alias + Assert::assertSame(3, $aOnly); // A's distinct method + Assert::assertSame(4, $bOnly); // B's distinct method +}; diff --git a/test/fixture/compile/generic_trait_adaptation_mixed/verify/runtime.php b/test/fixture/compile/generic_trait_adaptation_mixed/verify/runtime.php index 2580c513..6b6cf79e 100644 --- a/test/fixture/compile/generic_trait_adaptation_mixed/verify/runtime.php +++ b/test/fixture/compile/generic_trait_adaptation_mixed/verify/runtime.php @@ -9,14 +9,17 @@ * generic operands rewrite to their specializations. Plain's `val` wins; the excluded * generic `val`s are re-exposed under aliases; Plain's distinct method runs. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoloader registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoloader registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('P:1', $val); // insteadof: Plain's val wins over G, H -Assert::assertSame('G:2', $gval); // as: excluded generic G::val under alias -Assert::assertSame('H:3', $hval); // as: excluded generic H::val under alias -Assert::assertSame('plain', $plainOnly); // Plain's distinct method + Assert::assertSame('P:1', $val); // insteadof: Plain's val wins over G, H + Assert::assertSame('G:2', $gval); // as: excluded generic G::val under alias + Assert::assertSame('H:3', $hval); // as: excluded generic H::val under alias + Assert::assertSame('plain', $plainOnly); // Plain's distinct method +}; diff --git a/test/fixture/compile/group_import_class_requalify/verify/runtime.php b/test/fixture/compile/group_import_class_requalify/verify/runtime.php index 1c8a7b11..c3393110 100644 --- a/test/fixture/compile/group_import_class_requalify/verify/runtime.php +++ b/test/fixture/compile/group_import_class_requalify/verify/runtime.php @@ -8,15 +8,18 @@ * relocated Box body. Tool::ping()='pong' . Widget::spin()='spin' -> 'pongspin'. A group form * that fell back to the current namespace would fatal with "Class App\Tool not found". * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -// Vendor's two classes share one emitted lib.php (not one-class-per-file), so PSR-4 can't autoload -// them — require it before Use.php runs its top-level instantiation. The specialized Box autoloads -// via XPHP\Generated. -require $fixture->targetDir . '/lib.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + // Vendor's two classes share one emitted lib.php (not one-class-per-file), so PSR-4 can't autoload + // them — require it before Use.php runs its top-level instantiation. The specialized Box autoloads + // via XPHP\Generated. + require $fixture->targetDir . '/lib.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('pongspin', $result); + Assert::assertSame('pongspin', $result); +}; diff --git a/test/fixture/compile/keyword_named_generic_method/verify/runtime.php b/test/fixture/compile/keyword_named_generic_method/verify/runtime.php index 40284974..200c6ab2 100644 --- a/test/fixture/compile/keyword_named_generic_method/verify/runtime.php +++ b/test/fixture/compile/keyword_named_generic_method/verify/runtime.php @@ -7,12 +7,15 @@ * (`list`, `print`) declares, specializes, and is callable through both an instance turbofish and a * static turbofish. Instance `list::(41)` returns 41; static `print::(7)` returns 7. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(41, $instanceResult); -Assert::assertSame(7, $staticResult); + Assert::assertSame(41, $instanceResult); + Assert::assertSame(7, $staticResult); +}; diff --git a/test/fixture/compile/keyword_nongeneric_passthrough/verify/runtime.php b/test/fixture/compile/keyword_nongeneric_passthrough/verify/runtime.php index 3d9a8cbf..20ed4c75 100644 --- a/test/fixture/compile/keyword_nongeneric_passthrough/verify/runtime.php +++ b/test/fixture/compile/keyword_nongeneric_passthrough/verify/runtime.php @@ -7,13 +7,16 @@ * `list()` destructuring survive the keyword-turbofish support unchanged. list(10)+1=11, * print(20)+2=22, unpack([3,4])=7. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(11, $instance); -Assert::assertSame(22, $static); -Assert::assertSame(7, $destructured); + Assert::assertSame(11, $instance); + Assert::assertSame(22, $static); + Assert::assertSame(7, $destructured); +}; diff --git a/test/fixture/compile/multi_type/verify/type_error_on_wrong_slot.php b/test/fixture/compile/multi_type/verify/type_error_on_wrong_slot.php index 28d3909f..08e08b64 100644 --- a/test/fixture/compile/multi_type/verify/type_error_on_wrong_slot.php +++ b/test/fixture/compile/multi_type/verify/type_error_on_wrong_slot.php @@ -6,35 +6,38 @@ * Runtime verify for `multi_type`: a specialized Pair * accepts (User, Plastic) but rejects (Plastic, User) with a TypeError. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload * registered for `App\MultiType\` + the generated namespace. */ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -$pairFqn = Registry::generatedFqn( - 'App\\MultiType\\Containers\\Pair', - [new TypeRef('App\\MultiType\\Models\\User'), new TypeRef('App\\MultiType\\Models\\Plastic')], -); - -// Correct order: constructor accepts (User, Plastic). -$ok = new $pairFqn( - new \App\MultiType\Models\User('alice'), - new \App\MultiType\Models\Plastic('red'), -); -Assert::assertInstanceOf($pairFqn, $ok); +return function (CompiledFixture $fixture): void { + $pairFqn = Registry::generatedFqn( + 'App\\MultiType\\Containers\\Pair', + [new TypeRef('App\\MultiType\\Models\\User'), new TypeRef('App\\MultiType\\Models\\Plastic')], + ); -// Swapped order: constructor expects User in slot 0, Plastic in slot 1; -// passing them flipped triggers a TypeError on the first slot mismatch. -$caught = null; -try { - new $pairFqn( - new \App\MultiType\Models\Plastic('red'), + // Correct order: constructor accepts (User, Plastic). + $ok = new $pairFqn( new \App\MultiType\Models\User('alice'), + new \App\MultiType\Models\Plastic('red'), ); -} catch (\TypeError $e) { - $caught = $e; -} -Assert::assertInstanceOf(\TypeError::class, $caught); + Assert::assertInstanceOf($pairFqn, $ok); + + // Swapped order: constructor expects User in slot 0, Plastic in slot 1; + // passing them flipped triggers a TypeError on the first slot mismatch. + $caught = null; + try { + new $pairFqn( + new \App\MultiType\Models\Plastic('red'), + new \App\MultiType\Models\User('alice'), + ); + } catch (\TypeError $e) { + $caught = $e; + } + Assert::assertInstanceOf(\TypeError::class, $caught); +}; diff --git a/test/fixture/compile/multiline_generic_markers/verify/runtime.php b/test/fixture/compile/multiline_generic_markers/verify/runtime.php index d6ccb815..5da8872d 100644 --- a/test/fixture/compile/multiline_generic_markers/verify/runtime.php +++ b/test/fixture/compile/multiline_generic_markers/verify/runtime.php @@ -8,15 +8,18 @@ * declarations; every one of them must have specialized (none emitted * raw), and the emitted program must execute. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('w', $w->v); -Assert::assertSame(7, $b->v); -Assert::assertSame(41, $n); -Assert::assertSame('s', $s); -Assert::assertSame(2, $c); + Assert::assertSame('w', $w->v); + Assert::assertSame(7, $b->v); + Assert::assertSame(41, $n); + Assert::assertSame('s', $s); + Assert::assertSame(2, $c); +}; diff --git a/test/fixture/compile/nested_typehint/verify/nested_specialization_runtime.php b/test/fixture/compile/nested_typehint/verify/nested_specialization_runtime.php index 112daa5f..e3064719 100644 --- a/test/fixture/compile/nested_typehint/verify/nested_specialization_runtime.php +++ b/test/fixture/compile/nested_typehint/verify/nested_specialization_runtime.php @@ -8,34 +8,37 @@ * type, and calling `setBoxed('not a plastic')` raises a TypeError on * the substituted parameter signature. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload * registered for `App\NestedTypehint\` + the generated namespace. */ use PHPUnit\Framework\Assert; use XPHP\Transpiler\Monomorphize\Registry; use XPHP\Transpiler\Monomorphize\TypeRef; +use XPHP\TestSupport\CompiledFixture; -$plastic = new TypeRef('App\\NestedTypehint\\Models\\Plastic'); -$boxFqn = Registry::generatedFqn('App\\NestedTypehint\\Containers\\Box', [$plastic]); -$wrapperFqn = Registry::generatedFqn('App\\NestedTypehint\\Containers\\Wrapper', [$plastic]); +return function (CompiledFixture $fixture): void { + $plastic = new TypeRef('App\\NestedTypehint\\Models\\Plastic'); + $boxFqn = Registry::generatedFqn('App\\NestedTypehint\\Containers\\Box', [$plastic]); + $wrapperFqn = Registry::generatedFqn('App\\NestedTypehint\\Containers\\Wrapper', [$plastic]); -// Reflection: Wrapper's $box property is typed against the specialized Box. -$propType = (new \ReflectionProperty($wrapperFqn, 'box'))->getType(); -Assert::assertInstanceOf(\ReflectionNamedType::class, $propType); -Assert::assertSame($boxFqn, $propType->getName()); + // Reflection: Wrapper's $box property is typed against the specialized Box. + $propType = (new \ReflectionProperty($wrapperFqn, 'box'))->getType(); + Assert::assertInstanceOf(\ReflectionNamedType::class, $propType); + Assert::assertSame($boxFqn, $propType->getName()); -// Constructor must succeed independently -- otherwise the next -// catch block would falsely attribute its TypeError to setBoxed. -$w = new $wrapperFqn(); -Assert::assertInstanceOf($wrapperFqn, $w); + // Constructor must succeed independently -- otherwise the next + // catch block would falsely attribute its TypeError to setBoxed. + $w = new $wrapperFqn(); + Assert::assertInstanceOf($wrapperFqn, $w); -// TypeError on substituted parameter: setBoxed expects the concrete Plastic, -// not an arbitrary string. -$caught = null; -try { - $w->setBoxed('not a plastic'); -} catch (\TypeError $e) { - $caught = $e; -} -Assert::assertInstanceOf(\TypeError::class, $caught); + // TypeError on substituted parameter: setBoxed expects the concrete Plastic, + // not an arbitrary string. + $caught = null; + try { + $w->setBoxed('not a plastic'); + } catch (\TypeError $e) { + $caught = $e; + } + Assert::assertInstanceOf(\TypeError::class, $caught); +}; diff --git a/test/fixture/compile/qualified_bare_new_defaults/verify/runtime.php b/test/fixture/compile/qualified_bare_new_defaults/verify/runtime.php index fc2b9624..4f70cffc 100644 --- a/test/fixture/compile/qualified_bare_new_defaults/verify/runtime.php +++ b/test/fixture/compile/qualified_bare_new_defaults/verify/runtime.php @@ -9,24 +9,27 @@ * template even with a colliding `use` alias in scope, while the aliased * bare form keeps targeting the aliased template. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/OtherBox.php'; -require $fixture->targetDir . '/Use.php'; -require $fixture->targetDir . '/RelativeUse.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/OtherBox.php'; + require $fixture->targetDir . '/Use.php'; + require $fixture->targetDir . '/RelativeUse.php'; -Assert::assertSame('hi', $a->v); -Assert::assertSame('ho', $b->v); -Assert::assertSame(7, $c->n); + Assert::assertSame('hi', $a->v); + Assert::assertSame('ho', $b->v); + Assert::assertSame(7, $c->n); -// $a and $b are the same App-side specialization; $c is Other's. -Assert::assertSame(get_class($a), get_class($b)); -Assert::assertNotSame(get_class($a), get_class($c)); -// $c is a relocated specialization: emitted under Other's Generated namespace. -Assert::assertSame( - 'XPHP\\Generated\\Other\\Box\\T_6da88c34ba124c41f977db66a4fc5c1a951708d285c81bb0d47c3206f4c27ca8', - get_class($c), -); + // $a and $b are the same App-side specialization; $c is Other's. + Assert::assertSame(get_class($a), get_class($b)); + Assert::assertNotSame(get_class($a), get_class($c)); + // $c is a relocated specialization: emitted under Other's Generated namespace. + Assert::assertSame( + 'XPHP\\Generated\\Other\\Box\\T_6da88c34ba124c41f977db66a4fc5c1a951708d285c81bb0d47c3206f4c27ca8', + get_class($c), + ); +}; diff --git a/test/fixture/compile/qualified_generic_call_sites/verify/runtime.php b/test/fixture/compile/qualified_generic_call_sites/verify/runtime.php index a6176ae8..80275699 100644 --- a/test/fixture/compile/qualified_generic_call_sites/verify/runtime.php +++ b/test/fixture/compile/qualified_generic_call_sites/verify/runtime.php @@ -8,22 +8,25 @@ * `new` against the marker interface, no doubled-namespace template), * route to the SAME specializations as the bare forms, and execute. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(1, $a->v); -Assert::assertSame('r', $b->v); -Assert::assertSame('k', $c->key); -Assert::assertSame(5, $d->v); -Assert::assertSame(9, $e->v); -Assert::assertSame(3, $f); -Assert::assertSame('g', $g); + Assert::assertSame(1, $a->v); + Assert::assertSame('r', $b->v); + Assert::assertSame('k', $c->key); + Assert::assertSame(5, $d->v); + Assert::assertSame(9, $e->v); + Assert::assertSame(3, $f); + Assert::assertSame('g', $g); -// FQ, in-template, and same-line-relative int instantiations must all be -// the one int specialization. -Assert::assertSame(get_class($a), get_class($d)); -Assert::assertSame(get_class($a), get_class($e)); + // FQ, in-template, and same-line-relative int instantiations must all be + // the one int specialization. + Assert::assertSame(get_class($a), get_class($d)); + Assert::assertSame(get_class($a), get_class($e)); +}; diff --git a/test/fixture/compile/relative_names_in_templates/verify/runtime.php b/test/fixture/compile/relative_names_in_templates/verify/runtime.php index 3e86a503..f8f9ebb5 100644 --- a/test/fixture/compile/relative_names_in_templates/verify/runtime.php +++ b/test/fixture/compile/relative_names_in_templates/verify/runtime.php @@ -8,19 +8,22 @@ * `use` alias, never a type parameter), across extends clauses, method * signatures, generic-method receivers, and conformance hierarchies. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/LocalDefs.php'; -require $fixture->targetDir . '/OtherDefs.php'; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/LocalDefs.php'; + require $fixture->targetDir . '/OtherDefs.php'; + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(4, $g->v); -Assert::assertSame('App\\RelativeTemplates\\Base', get_parent_class($g)); -Assert::assertSame(1, $k->generic); -Assert::assertSame('ok', $lbl); -Assert::assertSame(5, $r); -Assert::assertInstanceOf('App\\RelativeTemplates\\Cat', $cat); -Assert::assertSame('App\\RelativeTemplates\\Base', get_parent_class($cat)); + Assert::assertSame(4, $g->v); + Assert::assertSame('App\\RelativeTemplates\\Base', get_parent_class($g)); + Assert::assertSame(1, $k->generic); + Assert::assertSame('ok', $lbl); + Assert::assertSame(5, $r); + Assert::assertInstanceOf('App\\RelativeTemplates\\Cat', $cat); + Assert::assertSame('App\\RelativeTemplates\\Base', get_parent_class($cat)); +}; diff --git a/test/fixture/compile/same_line_marker_pairs/verify/runtime.php b/test/fixture/compile/same_line_marker_pairs/verify/runtime.php index 46c765b0..a6685c6a 100644 --- a/test/fixture/compile/same_line_marker_pairs/verify/runtime.php +++ b/test/fixture/compile/same_line_marker_pairs/verify/runtime.php @@ -7,23 +7,26 @@ * same-spelling pair must have bound its markers to the right sites and * the whole program must execute. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; -require $fixture->targetDir . '/Aliased.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; + require $fixture->targetDir . '/Aliased.php'; -Assert::assertSame(9, $m); -Assert::assertSame(7, $a); -Assert::assertSame(8, $b); -Assert::assertSame(1, $k->v); -Assert::assertSame(2, $p1->v); -Assert::assertSame('s', $p2->v); -Assert::assertNotSame(get_class($p1), get_class($p2)); -Assert::assertSame(11, $t); -Assert::assertSame('App\\SameLinePairs\\B', get_class($bb)); -Assert::assertSame(3, $sum); -Assert::assertSame('v=9', $msg); -Assert::assertSame('al', $hv); + Assert::assertSame(9, $m); + Assert::assertSame(7, $a); + Assert::assertSame(8, $b); + Assert::assertSame(1, $k->v); + Assert::assertSame(2, $p1->v); + Assert::assertSame('s', $p2->v); + Assert::assertNotSame(get_class($p1), get_class($p2)); + Assert::assertSame(11, $t); + Assert::assertSame('App\\SameLinePairs\\B', get_class($bb)); + Assert::assertSame(3, $sum); + Assert::assertSame('v=9', $msg); + Assert::assertSame('al', $hv); +}; diff --git a/test/fixture/compile/scalar_alias_class_resolves/verify/runtime.php b/test/fixture/compile/scalar_alias_class_resolves/verify/runtime.php index 35ea947e..de5b9a1e 100644 --- a/test/fixture/compile/scalar_alias_class_resolves/verify/runtime.php +++ b/test/fixture/compile/scalar_alias_class_resolves/verify/runtime.php @@ -9,14 +9,17 @@ * construction. That all three construct, run, and return their class-typed values proves the alias names * resolve to the classes in argument position. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; -require $fixture->targetDir . '/Use.php'; -Assert::assertInstanceOf(\App\Double::class, $dv, 'Box:: must carry an App\\Double, not a scalar'); -Assert::assertSame(2.5, $dv->f); -Assert::assertInstanceOf(\App\Integer::class, $iv, 'Box:: must carry an App\\Integer'); -Assert::assertSame(7, $iv->i); -Assert::assertInstanceOf(\App\Boolean::class, $bv, 'Box:: must carry an App\\Boolean'); -Assert::assertTrue($bv->b); -echo "OK\n"; +use XPHP\TestSupport\CompiledFixture; + +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; + Assert::assertInstanceOf(\App\Double::class, $dv, 'Box:: must carry an App\\Double, not a scalar'); + Assert::assertSame(2.5, $dv->f); + Assert::assertInstanceOf(\App\Integer::class, $iv, 'Box:: must carry an App\\Integer'); + Assert::assertSame(7, $iv->i); + Assert::assertInstanceOf(\App\Boolean::class, $bv, 'Box:: must carry an App\\Boolean'); + Assert::assertTrue($bv->b); +}; diff --git a/test/fixture/compile/split_declaration_headers/verify/runtime.php b/test/fixture/compile/split_declaration_headers/verify/runtime.php index f3cd528b..2131efcb 100644 --- a/test/fixture/compile/split_declaration_headers/verify/runtime.php +++ b/test/fixture/compile/split_declaration_headers/verify/runtime.php @@ -7,16 +7,19 @@ * and functions whose headers split across lines (attribute or modifier on * its own line, keyword/name split) must all specialize and run. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('bx', $b->v); -Assert::assertSame(4, $p->u); -Assert::assertSame(5, $l); -Assert::assertSame('pk', $s); -Assert::assertSame(9, $i); -Assert::assertSame(['z', 'z'], $d); + Assert::assertSame('bx', $b->v); + Assert::assertSame(4, $p->u); + Assert::assertSame(5, $l); + Assert::assertSame('pk', $s); + Assert::assertSame(9, $i); + Assert::assertSame(['z', 'z'], $d); +}; diff --git a/test/fixture/compile/turbofish_fcc_closure/verify/runtime.php b/test/fixture/compile/turbofish_fcc_closure/verify/runtime.php index 96217b19..b8ddac82 100644 --- a/test/fixture/compile/turbofish_fcc_closure/verify/runtime.php +++ b/test/fixture/compile/turbofish_fcc_closure/verify/runtime.php @@ -7,17 +7,20 @@ * specialization emits a valid forwarding closure (the file parses, or this require would * fatal) that routes through the dispatcher and preserves callable semantics. * - * Driver contract: `$fixture` (CompiledFixture) in scope. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame(50, $viaCall); -Assert::assertSame([10, 20, 30], $viaMap); -Assert::assertSame(42, $named); -Assert::assertSame(7, $defaulted); -Assert::assertSame(4, $direct); -Assert::assertSame(8, $viaFcc); -Assert::assertSame(9, $collided); + Assert::assertSame(50, $viaCall); + Assert::assertSame([10, 20, 30], $viaMap); + Assert::assertSame(42, $named); + Assert::assertSame(7, $defaulted); + Assert::assertSame(4, $direct); + Assert::assertSame(8, $viaFcc); + Assert::assertSame(9, $collided); +}; diff --git a/test/fixture/compile/use_trait_generic/verify/runtime.php b/test/fixture/compile/use_trait_generic/verify/runtime.php index 3185ce26..f83d9d78 100644 --- a/test/fixture/compile/use_trait_generic/verify/runtime.php +++ b/test/fixture/compile/use_trait_generic/verify/runtime.php @@ -6,11 +6,14 @@ * Runtime verify for `use_trait_generic`: a generic trait-use survives the WI-08 * use-import reject, specializes, and runs -- the inlined trait method returns. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoloader registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoloader registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertSame('held', $label); + Assert::assertSame('held', $label); +}; diff --git a/test/fixture/compile/variance_edge_preserves_source_parent/verify/runtime.php b/test/fixture/compile/variance_edge_preserves_source_parent/verify/runtime.php index a0c65175..2d20c423 100644 --- a/test/fixture/compile/variance_edge_preserves_source_parent/verify/runtime.php +++ b/test/fixture/compile/variance_edge_preserves_source_parent/verify/runtime.php @@ -14,12 +14,15 @@ * That both calls resolve and run proves each specialization kept its source parent and its inherited * erased member. * - * Driver contract: `$fixture` (CompiledFixture) in scope, autoload registered. + * Driver contract: the driver invokes the returned closure with the `CompiledFixture`, autoload registered. */ use PHPUnit\Framework\Assert; +use XPHP\TestSupport\CompiledFixture; -require $fixture->targetDir . '/Use.php'; +return function (CompiledFixture $fixture): void { + require $fixture->targetDir . '/Use.php'; -Assert::assertTrue($fruitHit, 'ListColl must inherit contains_ from its source parent Base'); -Assert::assertTrue($bananaHit, 'ListColl must keep its source parent (not be overwritten) so contains_ resolves'); + Assert::assertTrue($fruitHit, 'ListColl must inherit contains_ from its source parent Base'); + Assert::assertTrue($bananaHit, 'ListColl must keep its source parent (not be overwritten) so contains_ resolves'); +};