-
Notifications
You must be signed in to change notification settings - Fork 446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replacing PSR-4 autoloading with a standard file map #721
Conversation
Replacing PSR-4 autoloading with a standard file map
This seems cause a problem with Composer autoload and PHPUnit. base.php is returning an instance of Base, which breaks the autoloader when used with PHPUnit. PHPUnit test to reproduce the problem: class FatFreeFrameworkTest extends PHPUnit_Framework_TestCase
{
protected static $f3;
public static function setUpBeforeClass()
{
self::$f3 = Base::instance();
}
public static function tearDownAfterClass()
{
self::$f3 = null;
}
public function testSomething() {
$this->assertTrue(self::$f3 instanceof Base, 'Instance of Base');
}
} If you only have this test in the test suit you should see that there is no test to execute. If you remove |
i just saw another phpunit test on fat-free today. He doesn't seem to have that problem: https://github.com/creoLIFE/FatFree-Helpers/blob/master/test/HelpersTest.php |
It does not seem to use the autoload for F3 require_once( __DIR__ . '/../vendor/autoload.php');
require_once(__DIR__ . "/../vendor/bcosca/fatfree/lib/base.php");
require_once( __DIR__ . '/../FatFree/Helpers/Url.php'); There is an autoloader ... but F3 seems to be manually loaded ... You should be able to create a PHPUnit test using the config in the phpunit.xml without having to directly include files in the test case. I think that @xmeltrut did the good thing, but for that to work with Composer autoload and PHPUnit, Base.php needs to get rid of the There will be a drawback if you are using something like |
I doupt that the returning instance is to blame for that. Where does it cause a problem? Composer works with fat-free. So it rather looks like a bug in phpunit for me. Is phpunit overwriting the existing spl_autoloader? (i never tried it along with fatfree) Are you sure that the test works correct? Have you tried maybe this: $this->assertTrue(\Base::instance() instanceof \Base, 'Instance of Base'); |
Test runs perfectly when you remove There is no logical explanation for a file containing a class definition to return something. PHPUnit is using the Composer loader. |
This looks like a unit test gone wrong. Just because the class returns something doesn't mean it's illogical. It's just non-conformist. There is no rule book that says you can't or shouldn't do otherwise. |
You can reproduce the problem without having any calls to F3 in an empty project ... just having it in Composer autoloader suffice to break PHPUnit tests. phpunit.xml: <?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<testsuites>
<testsuite name="Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit> PHPUnit test: <?php
class FatFreeFrameworkTest extends PHPUnit_Framework_TestCase
{
public function testSomething()
{
$this->assertTrue(true, 'That is true');
}
} Composer.json: {
"require": {
"bcosca/fatfree": "dev-master"
},
"require-dev": {
"bcosca/fatfree": "dev-master",
"phpunit/phpunit": "4.4.*"
}
} You can try that in an empty project, so there is nothing more than F3 and PHPUnit in Composer autoloader and it will still crash the test suite. |
I suggest you take it up with the Composer team. It seems illogical that a third-party autoloader will have trouble with F3 considering spl_autoload_register is stackable, and any autoloader registered prior to F3 should have priority. F3 doesn't generate any exception or error in its autoload function either, so it conforms to the specs, if not a lot more flexible than the so-called standard (which forces you to follow certain namespace/file naming and invocation conventions). It should also be of no consequence whether the framework returns something or not when What your unit test demonstrates is a failure of the third-party autoloader (Composer's) to cope with a return value. Perhaps you should use F3's autoloader as the primary. It's a lot more forgiving than the standard. |
Hi, Been rechecking that issue and I have finally found the culprit, which could be either in F3 or PHPUnit. So here is the code in F3 if (PHP_SAPI=='cli') {
// Emulate HTTP request
if (isset($_SERVER['argc']) && $_SERVER['argc']<2) {
$_SERVER['argc']++;
$_SERVER['argv'][1]='/';
}
$_SERVER['REQUEST_METHOD']='GET';
$_SERVER['REQUEST_URI']=$_SERVER['argv'][1];
} And the one in PHPUnit public static function main($exit = true)
{
$command = new static;
return $command->run($_SERVER['argv'], $exit);
} The use of Any suggestions ? I am not pointing F3 nor PHPUnit about that conflict. |
Since you're running the framework in CLI mode, there's really nothing we can do about it because the framework itself has a specific syntax and order of arguments when running from the command line. Altering this behavior will BREAK backward-compatibility, and that's something we don't intend to do. |
That makes sense! Thank you for your time. |
That explains the misunderstanding. All the time I thought you were running it as a Web app, which doesn't connect the dots with PHPunit. |
PSR-4 autoloading will not work because of the case difference (file is base but class is Base). This replaces it with a standard file map to include base.php with the Composer autoload.