bug #1874 Fix adding mock extension to Twig environment (GromNaN)

This PR was merged into the 1.x branch.

Discussion
----------

Fix adding mock extension to Twig environment

When the extension class is not defined in a file but in eval'd code we cannot assume `ReflectionObject::getFileName()` will return a valid file path.
https://bugs.php.net/bug.php?id=63901

This PR adds a test case that produce the following error without the fix:

```
1) Twig_Tests_EnvironmentTest::testAddMockExtension
filemtime(): stat failed for phar:///usr/local/php5-5.5.14-20140628-105310/bin/phpunit/phpunit-mock-objects/Framework/MockObject/Generator.php(335) : eval()'d code

/xxx/Twig/vendor/symfony/phpunit-bridge/DeprecationErrorHandler.php:40
/xxx/Twig/lib/Twig/Environment.php:769
/xxx/Twig/test/Twig/Tests/EnvironmentTest.php:304
```

I encountered this issue with mocked twig extensions in SonataAdminBundle test suite:
https://github.com/sonata-project/SonataAdminBundle/blob/master/Tests/Controller/HelperControllerTest.php#L254

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #1870
| License       | MIT
| Doc PR        | n/a

Commits
-------

a57b1cc Fix adding mock extension to Twig environment
This commit is contained in:
Fabien Potencier
2015-10-25 07:53:33 +01:00
2 changed files with 17 additions and 1 deletions
+1 -1
View File
@@ -462,7 +462,7 @@ class Twig_Environment
if (0 === $this->lastModifiedExtension) {
foreach ($this->extensions as $extension) {
$r = new ReflectionObject($extension);
if (($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
$this->lastModifiedExtension = $extensionTime;
}
}
+16
View File
@@ -292,6 +292,22 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
$this->assertCount(2, $twig->getNodeVisitors());
}
public function testAddMockExtension()
{
$extension = $this->getMock('Twig_ExtensionInterface');
$extension->expects($this->once())
->method('getName')
->will($this->returnValue('mock'));
$loader = new Twig_Loader_Array(array('page' => 'hey'));
$twig = new Twig_Environment($loader);
$twig->addExtension($extension);
$this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension('mock'));
$this->assertTrue($twig->isTemplateFresh('page', time()));
}
protected function getMockLoader($templateName, $templateContent)
{
$loader = $this->getMock('Twig_LoaderInterface');