Merge branch '2.6' into 2.7
* 2.6: [2.6][Translation] fix legacy tests. [EventDispatcher] make listeners removable from an executed listener Conflicts: src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php src/Symfony/Component/Translation/Tests/TranslatorCacheTest.php
This commit is contained in:
commit
bf8f70607a
@ -95,27 +95,6 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
|
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRefreshCacheWhenResourcesAreNoLongerFresh()
|
|
||||||
{
|
|
||||||
$resource = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
|
|
||||||
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
|
|
||||||
$resource->method('isFresh')->will($this->returnValue(false));
|
|
||||||
$loader
|
|
||||||
->expects($this->exactly(2))
|
|
||||||
->method('load')
|
|
||||||
->will($this->returnValue($this->getCatalogue('fr', array(), array($resource))));
|
|
||||||
|
|
||||||
// prime the cache
|
|
||||||
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'debug' => true));
|
|
||||||
$translator->setLocale('fr');
|
|
||||||
$translator->trans('foo');
|
|
||||||
|
|
||||||
// prime the cache second time
|
|
||||||
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'debug' => true));
|
|
||||||
$translator->setLocale('fr');
|
|
||||||
$translator->trans('foo');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testTransWithCachingWithInvalidLocale()
|
public function testTransWithCachingWithInvalidLocale()
|
||||||
{
|
{
|
||||||
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
|
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
|
||||||
@ -169,115 +148,21 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('répertoire', $translator->trans('folder'));
|
$this->assertEquals('répertoire', $translator->trans('folder'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetLocale()
|
public function testGetDefaultLocale()
|
||||||
{
|
{
|
||||||
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
|
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
|
||||||
|
$container
|
||||||
$request
|
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getLocale')
|
->method('getParameter')
|
||||||
|
->with('kernel.default_locale')
|
||||||
->will($this->returnValue('en'))
|
->will($this->returnValue('en'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
|
|
||||||
|
|
||||||
$container
|
|
||||||
->expects($this->exactly(2))
|
|
||||||
->method('isScopeActive')
|
|
||||||
->with('request')
|
|
||||||
->will($this->onConsecutiveCalls(false, true))
|
|
||||||
;
|
|
||||||
|
|
||||||
$container
|
|
||||||
->expects($this->once())
|
|
||||||
->method('has')
|
|
||||||
->with('request')
|
|
||||||
->will($this->returnValue(true))
|
|
||||||
;
|
|
||||||
|
|
||||||
$container
|
|
||||||
->expects($this->once())
|
|
||||||
->method('get')
|
|
||||||
->with('request')
|
|
||||||
->will($this->returnValue($request))
|
|
||||||
;
|
|
||||||
|
|
||||||
$translator = new Translator($container, new MessageSelector());
|
$translator = new Translator($container, new MessageSelector());
|
||||||
|
|
||||||
$this->assertNull($translator->getLocale());
|
|
||||||
$this->assertSame('en', $translator->getLocale());
|
$this->assertSame('en', $translator->getLocale());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetLocaleWithInvalidLocale()
|
|
||||||
{
|
|
||||||
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
|
|
||||||
|
|
||||||
$request
|
|
||||||
->expects($this->once())
|
|
||||||
->method('getLocale')
|
|
||||||
->will($this->returnValue('foo bar'))
|
|
||||||
;
|
|
||||||
$request
|
|
||||||
->expects($this->once())
|
|
||||||
->method('getDefaultLocale')
|
|
||||||
->will($this->returnValue('en-US'))
|
|
||||||
;
|
|
||||||
|
|
||||||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
|
|
||||||
|
|
||||||
$container
|
|
||||||
->expects($this->once())
|
|
||||||
->method('isScopeActive')
|
|
||||||
->with('request')
|
|
||||||
->will($this->returnValue(true))
|
|
||||||
;
|
|
||||||
|
|
||||||
$container
|
|
||||||
->expects($this->once())
|
|
||||||
->method('has')
|
|
||||||
->with('request')
|
|
||||||
->will($this->returnValue(true))
|
|
||||||
;
|
|
||||||
|
|
||||||
$container
|
|
||||||
->expects($this->any())
|
|
||||||
->method('get')
|
|
||||||
->with('request')
|
|
||||||
->will($this->returnValue($request))
|
|
||||||
;
|
|
||||||
|
|
||||||
$translator = new Translator($container, new MessageSelector());
|
|
||||||
$this->assertSame('en-US', $translator->getLocale());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Because the cache file contains a catalogue including all of its fallback
|
|
||||||
* catalogues, we must take the active set of fallback locales into
|
|
||||||
* consideration when loading a catalogue from the cache.
|
|
||||||
*/
|
|
||||||
$translator = $this->createTranslator(new ArrayLoader(), array('cache_dir' => $this->tmpDir));
|
|
||||||
$translator->setLocale('a');
|
|
||||||
$translator->setFallbackLocales(array('b'));
|
|
||||||
$translator->addResource('loader', array('foo' => 'foo (a)'), 'a');
|
|
||||||
$translator->addResource('loader', array('bar' => 'bar (b)'), 'b');
|
|
||||||
|
|
||||||
$this->assertEquals('bar (b)', $translator->trans('bar'));
|
|
||||||
|
|
||||||
// Remove fallback locale
|
|
||||||
$translator->setFallbackLocales(array());
|
|
||||||
$this->assertEquals('bar', $translator->trans('bar'));
|
|
||||||
|
|
||||||
// Use a fresh translator with no fallback locales, result should be the same
|
|
||||||
$translator = $this->createTranslator(new ArrayLoader(), array('cache_dir' => $this->tmpDir));
|
|
||||||
$translator->setLocale('a');
|
|
||||||
$translator->addResource('loader', array('foo' => 'foo (a)'), 'a');
|
|
||||||
$translator->addResource('loader', array('bar' => 'bar (b)'), 'b');
|
|
||||||
|
|
||||||
$this->assertEquals('bar', $translator->trans('bar'));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getCatalogue($locale, $messages, $resources = array())
|
protected function getCatalogue($locale, $messages, $resources = array())
|
||||||
{
|
{
|
||||||
$catalogue = new MessageCatalogue($locale);
|
$catalogue = new MessageCatalogue($locale);
|
||||||
|
@ -31,6 +31,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
|
|
||||||
private $called;
|
private $called;
|
||||||
private $dispatcher;
|
private $dispatcher;
|
||||||
|
private $wrappedListeners;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -45,6 +46,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
$this->stopwatch = $stopwatch;
|
$this->stopwatch = $stopwatch;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->called = array();
|
$this->called = array();
|
||||||
|
$this->wrappedListeners = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,6 +70,16 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
*/
|
*/
|
||||||
public function removeListener($eventName, $listener)
|
public function removeListener($eventName, $listener)
|
||||||
{
|
{
|
||||||
|
if (isset($this->wrappedListeners[$eventName])) {
|
||||||
|
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
|
||||||
|
if ($wrappedListener->getWrappedListener() === $listener) {
|
||||||
|
$listener = $wrappedListener;
|
||||||
|
unset($this->wrappedListeners[$eventName][$index]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->dispatcher->removeListener($eventName, $listener);
|
return $this->dispatcher->removeListener($eventName, $listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,12 +228,15 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
$this->dispatcher->removeListener($eventName, $listener);
|
$this->dispatcher->removeListener($eventName, $listener);
|
||||||
$info = $this->getListenerInfo($listener, $eventName);
|
$info = $this->getListenerInfo($listener, $eventName);
|
||||||
$name = isset($info['class']) ? $info['class'] : $info['type'];
|
$name = isset($info['class']) ? $info['class'] : $info['type'];
|
||||||
$this->dispatcher->addListener($eventName, new WrappedListener($listener, $name, $this->stopwatch, $this));
|
$wrappedListener = new WrappedListener($listener, $name, $this->stopwatch, $this);
|
||||||
|
$this->wrappedListeners[$eventName][] = $wrappedListener;
|
||||||
|
$this->dispatcher->addListener($eventName, $wrappedListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function postProcess($eventName)
|
private function postProcess($eventName)
|
||||||
{
|
{
|
||||||
|
unset($this->wrappedListeners[$eventName]);
|
||||||
$skipped = false;
|
$skipped = false;
|
||||||
foreach ($this->dispatcher->getListeners($eventName) as $listener) {
|
foreach ($this->dispatcher->getListeners($eventName) as $listener) {
|
||||||
if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch.
|
if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch.
|
||||||
@ -259,7 +274,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns information about the listener
|
* Returns information about the listener.
|
||||||
*
|
*
|
||||||
* @param object $listener The listener
|
* @param object $listener The listener
|
||||||
* @param string $eventName The event name
|
* @param string $eventName The event name
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\EventDispatcher\Tests\Debug;
|
namespace Symfony\Component\EventDispatcher\Tests\Debug;
|
||||||
|
|
||||||
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
|
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||||
use Symfony\Component\EventDispatcher\Event;
|
use Symfony\Component\EventDispatcher\Event;
|
||||||
@ -174,6 +175,19 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
|
|||||||
$dispatcher->dispatch('foo');
|
$dispatcher->dispatch('foo');
|
||||||
$this->assertTrue($nestedCall);
|
$this->assertTrue($nestedCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testListenerCanRemoveItselfWhenExecuted()
|
||||||
|
{
|
||||||
|
$eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
||||||
|
$listener1 = function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) {
|
||||||
|
$dispatcher->removeListener('foo', $listener1);
|
||||||
|
};
|
||||||
|
$eventDispatcher->addListener('foo', $listener1);
|
||||||
|
$eventDispatcher->addListener('foo', function () {});
|
||||||
|
$eventDispatcher->dispatch('foo');
|
||||||
|
|
||||||
|
$this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventSubscriber implements EventSubscriberInterface
|
class EventSubscriber implements EventSubscriberInterface
|
||||||
|
@ -235,12 +235,38 @@ class TranslatorCacheTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertTrue($fallback->defines('foo'));
|
$this->assertTrue($fallback->defines('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getCatalogue($locale, $messages)
|
public function testRefreshCacheWhenResourcesAreNoLongerFresh()
|
||||||
|
{
|
||||||
|
$resource = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
|
||||||
|
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
|
||||||
|
$resource->method('isFresh')->will($this->returnValue(false));
|
||||||
|
$loader
|
||||||
|
->expects($this->exactly(2))
|
||||||
|
->method('load')
|
||||||
|
->will($this->returnValue($this->getCatalogue('fr', array(), array($resource))));
|
||||||
|
|
||||||
|
// prime the cache
|
||||||
|
$translator = new Translator('fr', null, $this->tmpDir, true);
|
||||||
|
$translator->addLoader('loader', $loader);
|
||||||
|
$translator->addResource('loader', 'foo', 'fr');
|
||||||
|
$translator->trans('foo');
|
||||||
|
|
||||||
|
// prime the cache second time
|
||||||
|
$translator = new Translator('fr', null, $this->tmpDir, true);
|
||||||
|
$translator->addLoader('loader', $loader);
|
||||||
|
$translator->addResource('loader', 'foo', 'fr');
|
||||||
|
$translator->trans('foo');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCatalogue($locale, $messages, $resources = array())
|
||||||
{
|
{
|
||||||
$catalogue = new MessageCatalogue($locale);
|
$catalogue = new MessageCatalogue($locale);
|
||||||
foreach ($messages as $key => $translation) {
|
foreach ($messages as $key => $translation) {
|
||||||
$catalogue->set($key, $translation);
|
$catalogue->set($key, $translation);
|
||||||
}
|
}
|
||||||
|
foreach ($resources as $resource) {
|
||||||
|
$catalogue->addResource($resource);
|
||||||
|
}
|
||||||
|
|
||||||
return $catalogue;
|
return $catalogue;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user