-
-
Notifications
You must be signed in to change notification settings - Fork 73
Closed
Description
Version: 2.5.2, WSL (Ubuntu), but reproduced also in non-WSL Ubuntu.
Bug Description
tl;dr
When using phpdbg Nette Tester doesn't see the only test method defined in anonymous class which extends \Tester\TestCase class.
Slightly longer tl;dr
phpdbg and php interpreters seem to differ in how they behave when echoing a string containing a NULL byte. This causes the code ...
tester/src/Framework/TestCase.php
Lines 214 to 218 in 7fd3b98
| Environment::$checkAssertions = false; | |
| header('Content-Type: text/plain'); | |
| echo "\n"; | |
| echo 'TestCase:' . static::class . "\n"; | |
| echo 'Method:' . implode("\nMethod:", $methods) . "\n"; |
phpdbg, which then causes Nette Tester to think there are no test case methods, if there is only one, when using an anonymous class extending a \Tester\TestCase class.
Explanation
phpdbgandphpinterpreters differ in how they behave when echoing a string containing a NULL byte.- Who knows why. I was unable to pinpoint the exact place in https://github.com/php/php-src which would explain this.
- When using anonymous classes, PHP builds its name like so:
- https://github.com/php/php-src/blob/d545b1d64350cac9cbf27859ad44d3ba32f6b736/Zend/zend_compile.c#L8266-L8284
- ... which means the class name string contains a
\0NULL byte.
- When this anonymous class's name is echoed,
phpsomehow deals with (ignores?) the NULL byte, whilephpdbgseems to stop the echo at that point.- How to reproduce? Create a file
nullbyteclassname.phpwith this content:
<?php $x = new class { function printMe() { echo "-START\n"; echo "123" . static::class . "456\n"; echo "-END\n"; } }; $x->printMe();
- Then execute it both ways and see the results:
php
[smuuf@smuuf-hp]$ php8.2 nullbyteclassname.php -START 123class@anonymous/mnt/d/produkce/coding/php/php-nette-tester/nullbyteclassname.php:3$0456 -END
phpdbg
[smuuf@smuuf-hp]$ phpdbg8.2 -qrrb -S cli nullbyteclassname.php -START 123class@anonymous-END
⚠️ Whatphpdbgechoes is not a complete class name. And the456\nis also trimmed.
- How to reproduce? Create a file
- In Nette Tester, the method
TestCase::sendMethodList()reports a list of test methods using this code:... but due to the reasons stated above ...echo "\n"; echo 'TestCase:' . static::class . "\n"; echo 'Method:' . implode("\nMethod:", $methods) . "\n";
- ❌ ... when using
phpdbg, this results in mangled output, like so:... which is incorrect (not expected) and information about the only test method is mixed on the line starting withNOTICE THIS -------------------++ || VV TestCase:Tester\TestCase@anonymousMethod:testMe Dependency:/mnt/d/produkce/coding/php/php-nette-tester/anonclasstestcase.phpt Dependency:/mnt/d/produkce/coding/php/php-nette-tester/src/Framework/TestCase.phpTestCase:- thus the information about the only test method is lost. ❗ - ✅ ... on the other way
phpdoes it like so:... which is correct (expected).TestCase:Tester\TestCase@anonymous/mnt/d/produkce/coding/php/php-nette-tester/anonclasstestcase.phpt:8$0 Method:testMe Dependency:/mnt/d/produkce/coding/php/php-nette-tester/anonclasstestcase.phpt Dependency:/mnt/d/produkce/coding/php/php-nette-tester/src/Framework/TestCase.php
- ❌ ... when using
Steps To Reproduce
- Clone
nette/testerrepo and install Composer dependencies. - Create a file
anonclasstestcase.phptin the repo's root dir:<?php require __DIR__ . '/vendor/autoload.php'; use Tester\TestCase; use Tester\Assert; (new class extends TestCase { public function testMe(): void { Assert::true(true); } })->run();
- Execute these and look at the results:
phpResult:php8.2 -d memory_limit=4096M -d register_argc_argv=on anonclasstestcase.phpt --method=nette-tester-list-methods
TestCase:Tester\TestCase@anonymous/mnt/d/produkce/coding/php/php-nette-tester/anonclasstestcase.phpt:8$0 Method:testMe Dependency:/mnt/d/produkce/coding/php/php-nette-tester/anonclasstestcase.phpt Dependency:/mnt/d/produkce/coding/php/php-nette-tester/src/Framework/TestCase.phpphpdbgResult:phpdbg8.2 -qrrb -d memory_limit=4096M -d register_argc_argv=on anonclasstestcase.phpt --method=nette-tester-list-methods
TestCase:Tester\TestCase@anonymousMethod:testMe Dependency:/mnt/d/produkce/coding/php/php-nette-tester/anonclasstestcase.phpt Dependency:/mnt/d/produkce/coding/php/php-nette-tester/src/Framework/TestCase.php
Expected Behavior
Even when using phpdbg Nette Tester should find the only test case method defined inside anonymous class which extends \Tester\TestCase class.
Possible Solution
It seems that preprocessing the result of static::class by removing "\0" from it solves the problem.
Possibly related:
milandufek and MatejHamala
Metadata
Metadata
Assignees
Labels
No labels