merged branch igorw/phpunit-ob-level (PR #2617)

Commits
-------

29e12af [TwigBundle] Extract output buffer cleaning to method
ed1a6c2 [TwigBundle] Do not clean output buffering below initial level

Discussion
----------

[TwigBundle] Do not clean output buffering below initial level

This resulted in issues with PHPUnit 3.6, which will buffer all output and clean them in the end. Since
we cleaned their buffer, the subsequent clean would raise a warning. This is documented in [issue 390](https://github.com/sebastianbergmann/phpunit/issues/390) of
the PHPUnit tracker.

Closes #2531.

This also affects FOSRestBundle's ExceptionController /cc @lsmith.

---------------------------------------------------------------------------

by fabpot at 2011/11/11 07:33:24 -0800

I have a similar fix locally but I have not merged it yet as it looks a bit dirty (but I've not a better idea yet). Anyway, your PR is better than mine as you've added some unit tests already.
This commit is contained in:
Fabien Potencier 2011-11-11 22:17:55 +01:00
commit 1940bec31b
4 changed files with 127 additions and 8 deletions

View File

@ -37,14 +37,7 @@ class ExceptionController extends ContainerAware
{
$this->container->get('request')->setRequestFormat($format);
// the count variable avoids an infinite loop on
// some Windows configurations where ob_get_level()
// never reaches 0
$count = 100;
$currentContent = '';
while (ob_get_level() && --$count) {
$currentContent .= ob_get_clean();
}
$currentContent = $this->getAndCleanOutputBuffering();
$templating = $this->container->get('templating');
$code = $exception->getStatusCode();
@ -66,6 +59,21 @@ class ExceptionController extends ContainerAware
return $response;
}
protected function getAndCleanOutputBuffering()
{
// the count variable avoids an infinite loop on
// some Windows configurations where ob_get_level()
// never reaches 0
$count = 100;
$startObLevel = $this->container->get('kernel')->getStartObLevel();
$currentContent = '';
while (ob_get_level() > $startObLevel && --$count) {
$currentContent .= ob_get_clean();
}
return $currentContent;
}
protected function findTemplate($templating, $format, $code, $debug)
{
$name = $debug ? 'exception' : 'error';

View File

@ -0,0 +1,91 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\TwigBundle\Tests\Controller;
use Symfony\Bundle\TwigBundle\Tests\TestCase;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\DependencyInjection\Definition;
class ExceptionControllerTest extends TestCase
{
protected $controller;
protected $container;
protected $flatten;
protected $templating;
protected $kernel;
protected function setUp()
{
parent::setUp();
$this->flatten = $this->getMock('Symfony\Component\HttpKernel\Exception\FlattenException');
$this->flatten
->expects($this->once())
->method('getStatusCode')
->will($this->returnValue(404));
$this->flatten
->expects($this->once())
->method('getHeaders')
->will($this->returnValue(array()));
$this->controller = new ExceptionController();
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
$this->templating = $this->getMockBuilder('Symfony\\Bundle\\TwigBundle\\TwigEngine')
->disableOriginalConstructor()
->getMock();
$this->templating
->expects($this->any())
->method('renderResponse')
->will($this->returnValue($this->getMock('Symfony\Component\HttpFoundation\Response')));
$this->container = $this->getContainer();
}
protected function tearDown()
{
parent::tearDown();
$this->controller = null;
$this->container = null;
$this->flatten = null;
$this->templating = null;
$this->kernel = null;
}
public function testOnlyClearOwnOutputBuffers()
{
$this->container->enterScope('request');
$this->kernel
->expects($this->once())
->method('getStartObLevel')
->will($this->returnValue(1));
$this->controller->setContainer($this->container);
$this->controller->showAction($this->flatten);
}
private function getContainer()
{
$container = new ContainerBuilder();
$container->addScope(new Scope('request'));
$container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request');
$container->set('templating', $this->templating);
$container->setParameter('kernel.bundles', array());
$container->setParameter('kernel.cache_dir', __DIR__);
$container->setParameter('kernel.root_dir', __DIR__);
$container->set('kernel', $this->kernel);
return $container;
}
}

View File

@ -55,6 +55,7 @@ abstract class Kernel implements KernelInterface
protected $booted;
protected $name;
protected $startTime;
protected $startObLevel;
protected $classes;
const VERSION = '2.0.6-DEV';
@ -120,6 +121,8 @@ abstract class Kernel implements KernelInterface
return;
}
$this->startObLevel = ob_get_level();
// init bundles
$this->initializeBundles();
@ -421,6 +424,16 @@ abstract class Kernel implements KernelInterface
return $this->debug ? $this->startTime : -INF;
}
/**
* Gets the ob_level at the start of the request
*
* @return integer The request start ob_level
*/
public function getStartObLevel()
{
return $this->startObLevel;
}
/**
* Gets the cache directory.
*

View File

@ -179,6 +179,13 @@ interface KernelInterface extends HttpKernelInterface, \Serializable
*/
function getStartTime();
/**
* Gets the ob_level at the start of the request
*
* @return integer The request start ob_level
*/
function getStartObLevel();
/**
* Gets the cache directory.
*