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 ...
|
Environment::$checkAssertions = false; |
|
header('Content-Type: text/plain'); |
|
echo "\n"; |
|
echo 'TestCase:' . static::class . "\n"; |
|
echo 'Method:' . implode("\nMethod:", $methods) . "\n"; |
... to result in bad (mangled) output when using
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
phpdbg and php interpreters differ in how they behave when echoing a string containing a NULL byte.
- When using anonymous classes, PHP builds its name like so:
- When this anonymous class's name is echoed,
php somehow deals with (ignores?) the NULL byte, while phpdbg seems to stop the echo at that point.
- How to reproduce? Create a file
nullbyteclassname.php with 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:
[smuuf@smuuf-hp]$ php8.2 nullbyteclassname.php
-START
123class@anonymous/mnt/d/produkce/coding/php/php-nette-tester/nullbyteclassname.php:3$0456
-END
[smuuf@smuuf-hp]$ phpdbg8.2 -qrrb -S cli nullbyteclassname.php
-START
123class@anonymous-END
- ⚠️ What
phpdbg echoes is not a complete class name. And the 456\n is also trimmed.
- In Nette Tester, the method
TestCase::sendMethodList() reports a list of test methods using this code:
echo "\n";
echo 'TestCase:' . static::class . "\n";
echo 'Method:' . implode("\nMethod:", $methods) . "\n";
... but due to the reasons stated above ...
- ❌ ... when using
phpdbg, this results in mangled output, like so:
NOTICE 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.php
... which is incorrect (not expected) and information about the only test method is mixed on the line starting with TestCase: - thus the information about the only test method is lost. ❗
- ✅ ... on the other way
php does it like so:
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
... which is correct (expected).
Steps To Reproduce
- Clone
nette/tester repo and install Composer dependencies.
- Create a file
anonclasstestcase.phpt in 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:
php
php8.2 -d memory_limit=4096M -d register_argc_argv=on anonclasstestcase.phpt --method=nette-tester-list-methods
Result:
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
phpdbg
phpdbg8.2 -qrrb -d memory_limit=4096M -d register_argc_argv=on anonclasstestcase.phpt --method=nette-tester-list-methods
Result:
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:
Version: 2.5.2, WSL (Ubuntu), but reproduced also in non-WSL Ubuntu.
Bug Description
tl;dr
When using
phpdbgNette Tester doesn't see the only test method defined in anonymous class which extends\Tester\TestCaseclass.Slightly longer tl;dr
phpdbgandphpinterpreters 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
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\TestCaseclass.Explanation
phpdbgandphpinterpreters differ in how they behave when echoing a string containing a NULL byte.\0NULL byte.phpsomehow deals with (ignores?) the NULL byte, whilephpdbgseems to stop the echo at that point.nullbyteclassname.phpwith this content:phpphpdbgphpdbgechoes is not a complete class name. And the456\nis also trimmed.TestCase::sendMethodList()reports a list of test methods using this code:phpdbg, this results in mangled output, like so:TestCase:- thus the information about the only test method is lost. ❗phpdoes it like so:Steps To Reproduce
nette/testerrepo and install Composer dependencies.anonclasstestcase.phptin the repo's root dir:phpphpdbgExpected Behavior
Even when using
phpdbgNette Tester should find the only test case method defined inside anonymous class which extends\Tester\TestCaseclass.Possible Solution
It seems that preprocessing the result of
static::classby removing"\0"from it solves the problem.Possibly related: