From 678766900be69d7533ee1e74d0d86cf355d57756 Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Sat, 19 Jul 2014 21:31:34 +0100 Subject: [PATCH 01/13] [DependencyInjection] Pass a Scope instance instead of a scope name. --- .../DependencyInjection/Dumper/GraphvizDumper.php | 5 +++-- .../Tests/Dumper/GraphvizDumperTest.php | 7 +++++++ .../Tests/Fixtures/containers/container18.php | 14 ++++++++++++++ .../Tests/Fixtures/graphviz/services18.dot | 8 ++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container18.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services18.dot diff --git a/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php index 5ee1b7eea0fa..1ffe142af490 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Scope; /** * GraphvizDumper dumps a service container as a graphviz file. @@ -193,8 +194,8 @@ private function cloneContainer() $container->setDefinitions($this->container->getDefinitions()); $container->setAliases($this->container->getAliases()); $container->setResources($this->container->getResources()); - foreach ($this->container->getScopes() as $scope) { - $container->addScope($scope); + foreach ($this->container->getScopes() as $scope => $parentScope) { + $container->addScope(new Scope($scope, $parentScope)); } foreach ($this->container->getExtensions() as $extension) { $container->registerExtension($extension); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php index 0dc1ce8de150..3db11504adeb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php @@ -62,4 +62,11 @@ public function testDumpWithFrozenCustomClassContainer() $dumper = new GraphvizDumper($container); $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services'); } + + public function testDumpWithScopes() + { + $container = include self::$fixturesPath.'/containers/container18.php'; + $dumper = new GraphvizDumper($container); + $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services18.dot')), $dumper->dump(), '->dump() dumps services'); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container18.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container18.php new file mode 100644 index 000000000000..0248ed462722 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container18.php @@ -0,0 +1,14 @@ +addScope(new Scope('request')); +$container-> + register('foo', 'FooClass')-> + setScope('request') +; +$container->compile(); + +return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services18.dot b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services18.dot new file mode 100644 index 000000000000..4fbcceef3614 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services18.dot @@ -0,0 +1,8 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; +} From 02eb765a9c45fef7a925401381500d680d35d9af Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 19 Jul 2014 17:29:08 -0600 Subject: [PATCH 02/13] [Process] Fixes issue #11421 --- src/Symfony/Component/Process/ExecutableFinder.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/Process/ExecutableFinder.php b/src/Symfony/Component/Process/ExecutableFinder.php index 44f1605fa956..6ae74dca174b 100644 --- a/src/Symfony/Component/Process/ExecutableFinder.php +++ b/src/Symfony/Component/Process/ExecutableFinder.php @@ -59,8 +59,7 @@ public function find($name, $default = null, array $extraDirs = array()) if (is_dir($path)) { $dirs[] = $path; } else { - $file = str_replace(dirname($path), '', $path); - if ($file == $name && is_executable($path)) { + if (basename($path) == $name && is_executable($path)) { return $path; } } From 9f4313cf6f550d829e761e1add5ee8f74f5861a6 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 19 Jul 2014 17:48:53 -0600 Subject: [PATCH 03/13] [Process] Add test to verify fix for issue #11421 --- .../Process/Tests/ExecutableFinderTest.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php index e728c0ee73d5..0a905e946cb7 100644 --- a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php +++ b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php @@ -110,6 +110,27 @@ public function testFindWithOpenBaseDir() $this->assertSamePath(PHP_BINARY, $result); } + public function testFindProcessInOpenBasedir() + { + if (ini_get('open_basedir')) { + $this->markTestSkipped('Cannot test when open_basedir is set'); + } + + if (!defined('PHP_BINARY')) { + $this->markTestSkipped('Requires the PHP_BINARY constant'); + } + + $execPath = __DIR__.DIRECTORY_SEPARATOR.'SignalListener.php'; + + $this->setPath(''); + ini_set('open_basedir', PHP_BINARY.PATH_SEPARATOR.'/'); + + $finder = new ExecutableFinder; + $result = $finder->find($this->getPhpBinaryName(), false); + + $this->assertSamePath(PHP_BINARY, $result); + } + private function assertSamePath($expected, $tested) { if (defined('PHP_WINDOWS_VERSION_BUILD')) { From 4cf50e8d3036664d51efb7709e770d209358cd2b Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 20 Jul 2014 22:50:55 -0600 Subject: [PATCH 04/13] Bring code into standard --- src/Symfony/Component/Process/Tests/ExecutableFinderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php index 0a905e946cb7..3b5bff26e999 100644 --- a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php +++ b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php @@ -120,12 +120,12 @@ public function testFindProcessInOpenBasedir() $this->markTestSkipped('Requires the PHP_BINARY constant'); } - $execPath = __DIR__.DIRECTORY_SEPARATOR.'SignalListener.php'; + $execPath = __DIR__.'/SignalListener.php'; $this->setPath(''); ini_set('open_basedir', PHP_BINARY.PATH_SEPARATOR.'/'); - $finder = new ExecutableFinder; + $finder = new ExecutableFinder(); $result = $finder->find($this->getPhpBinaryName(), false); $this->assertSamePath(PHP_BINARY, $result); From f401ab9032378884e9e5bb9d6727b15c3e55e690 Mon Sep 17 00:00:00 2001 From: Benjamin Cremer Date: Wed, 9 Jul 2014 09:53:11 +0200 Subject: [PATCH 05/13] Fixed server HTTP_HOST port uri conversion --- src/Symfony/Component/BrowserKit/Client.php | 6 +++++- .../Component/BrowserKit/Tests/ClientTest.php | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php index a69e1625c081..befc0371f430 100644 --- a/src/Symfony/Component/BrowserKit/Client.php +++ b/src/Symfony/Component/BrowserKit/Client.php @@ -304,7 +304,11 @@ public function request($method, $uri, array $parameters = array(), array $files $uri = $this->getAbsoluteUri($uri); if (isset($server['HTTP_HOST'])) { - $uri = preg_replace('{^(https?\://)'.parse_url($uri, PHP_URL_HOST).'}', '${1}'.$server['HTTP_HOST'], $uri); + if ($port = parse_url($uri, PHP_URL_PORT)) { + $port = ':'.$port; + } + + $uri = preg_replace('{^(https?\://)'.parse_url($uri, PHP_URL_HOST).$port.'}', '${1}'.$server['HTTP_HOST'], $uri); } if (isset($server['HTTPS'])) { diff --git a/src/Symfony/Component/BrowserKit/Tests/ClientTest.php b/src/Symfony/Component/BrowserKit/Tests/ClientTest.php index 2612bb26c4d2..a5eade2a5812 100644 --- a/src/Symfony/Component/BrowserKit/Tests/ClientTest.php +++ b/src/Symfony/Component/BrowserKit/Tests/ClientTest.php @@ -210,6 +210,24 @@ public function testRequestURIConversion() $this->assertEquals('http://www.example.com/foo/bar', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs'); } + public function testRequestURIConversionByServerHost() + { + $client = new TestClient(); + + $server = array('HTTP_HOST' => 'www.example.com:8000'); + $parameters = array(); + $files = array(); + + $client->request('GET', 'http://example.com', $parameters, $files, $server); + $this->assertEquals('http://www.example.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to add port'); + + $client->request('GET', 'http://example.com:8888', $parameters, $files, $server); + $this->assertEquals('http://www.example.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to modify existing port'); + + $client->request('GET', 'http://example.com:8000', $parameters, $files, $server); + $this->assertEquals('http://www.example.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST respects correct set port'); + } + public function testRequestReferer() { $client = new TestClient(); From 103fd88b403f0ff5ddec5284344ffb64fc0183df Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 25 Jul 2014 07:47:26 +0200 Subject: [PATCH 06/13] [BrowserKit] refactor code and fix unquoted regex --- src/Symfony/Component/BrowserKit/Client.php | 24 ++++++++++--------- .../Component/BrowserKit/Tests/ClientTest.php | 14 +++++------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php index befc0371f430..6e91305a74d7 100644 --- a/src/Symfony/Component/BrowserKit/Client.php +++ b/src/Symfony/Component/BrowserKit/Client.php @@ -304,11 +304,7 @@ public function request($method, $uri, array $parameters = array(), array $files $uri = $this->getAbsoluteUri($uri); if (isset($server['HTTP_HOST'])) { - if ($port = parse_url($uri, PHP_URL_PORT)) { - $port = ':'.$port; - } - - $uri = preg_replace('{^(https?\://)'.parse_url($uri, PHP_URL_HOST).$port.'}', '${1}'.$server['HTTP_HOST'], $uri); + $uri = preg_replace('{^(https?\://)'.preg_quote($this->extractHost($uri)).'}', '${1}'.$server['HTTP_HOST'], $uri); } if (isset($server['HTTPS'])) { @@ -321,12 +317,7 @@ public function request($method, $uri, array $parameters = array(), array $files $server['HTTP_REFERER'] = $this->history->current()->getUri(); } - $server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST); - - if ($port = parse_url($uri, PHP_URL_PORT)) { - $server['HTTP_HOST'] .= ':'.$port; - } - + $server['HTTP_HOST'] = $this->extractHost($uri); $server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME); $this->internalRequest = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content); @@ -623,4 +614,15 @@ private function updateServerFromUri($server, $uri) return $server; } + + private function extractHost($uri) + { + $host = parse_url($uri, PHP_URL_HOST); + + if ($port = parse_url($uri, PHP_URL_PORT)) { + return $host.':'.$port; + } + + return $host; + } } diff --git a/src/Symfony/Component/BrowserKit/Tests/ClientTest.php b/src/Symfony/Component/BrowserKit/Tests/ClientTest.php index a5eade2a5812..cd37fcf76ae1 100644 --- a/src/Symfony/Component/BrowserKit/Tests/ClientTest.php +++ b/src/Symfony/Component/BrowserKit/Tests/ClientTest.php @@ -214,18 +214,18 @@ public function testRequestURIConversionByServerHost() { $client = new TestClient(); - $server = array('HTTP_HOST' => 'www.example.com:8000'); + $server = array('HTTP_HOST' => 'www.exampl+e.com:8000'); $parameters = array(); $files = array(); - $client->request('GET', 'http://example.com', $parameters, $files, $server); - $this->assertEquals('http://www.example.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to add port'); + $client->request('GET', 'http://exampl+e.com', $parameters, $files, $server); + $this->assertEquals('http://www.exampl+e.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to add port'); - $client->request('GET', 'http://example.com:8888', $parameters, $files, $server); - $this->assertEquals('http://www.example.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to modify existing port'); + $client->request('GET', 'http://exampl+e.com:8888', $parameters, $files, $server); + $this->assertEquals('http://www.exampl+e.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to modify existing port'); - $client->request('GET', 'http://example.com:8000', $parameters, $files, $server); - $this->assertEquals('http://www.example.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST respects correct set port'); + $client->request('GET', 'http://exampl+e.com:8000', $parameters, $files, $server); + $this->assertEquals('http://www.exampl+e.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST respects correct set port'); } public function testRequestReferer() From eb68662360d584f2063788c6dcfaee52b6cc7803 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 22 Jul 2014 18:04:22 +0200 Subject: [PATCH 07/13] [Process] fix signal handling in wait() wait() throws an exception when the process was terminated by a signal. This should not happen when the termination was requested by calling either the stop() or the signal() method (for example, inside a callback which is passed to wait()). --- src/Symfony/Component/Process/Process.php | 10 ++++- .../Process/Tests/SimpleProcessTest.php | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 2ccad53d775c..3185633fbfd2 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -64,6 +64,8 @@ class Process /** @var ProcessPipes */ private $processPipes; + private $latestSignal; + private static $sigchild; /** @@ -321,7 +323,7 @@ public function wait($callback = null) usleep(1000); } - if ($this->processInformation['signaled']) { + if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) { throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig'])); } @@ -661,7 +663,8 @@ public function stop($timeout = 10, $signal = null) throw new RuntimeException('Unable to kill the process'); } } - proc_terminate($this->process); + // given `SIGTERM` may not be defined and that `proc_terminate` uses the constant value and not the constant itself, we use the same here + $this->doSignal(15, false); do { usleep(1000); } while ($this->isRunning() && microtime(true) < $timeoutMicro); @@ -1158,6 +1161,7 @@ private function resetProcessData() $this->stdout = null; $this->stderr = null; $this->process = null; + $this->latestSignal = null; $this->status = self::STATUS_READY; $this->incrementalOutputOffset = 0; $this->incrementalErrorOutputOffset = 0; @@ -1201,6 +1205,8 @@ private function doSignal($signal, $throwException) return false; } + $this->latestSignal = $signal; + return true; } diff --git a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php b/src/Symfony/Component/Process/Tests/SimpleProcessTest.php index 69ad3d5b09f1..cb06f289682f 100644 --- a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php +++ b/src/Symfony/Component/Process/Tests/SimpleProcessTest.php @@ -147,6 +147,50 @@ public function testSignalWithWrongNonIntSignal() parent::testSignalWithWrongNonIntSignal(); } + public function testStopTerminatesProcessCleanly() + { + try { + $process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"'); + $process->run(function () use ($process) { + $process->stop(); + }); + } catch (RuntimeException $e) { + $this->fail('A call to stop() is not expected to cause wait() to throw a RuntimeException'); + } + } + + public function testKillSignalTerminatesProcessCleanly() + { + $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); + + try { + $process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"'); + $process->run(function () use ($process) { + if ($process->isRunning()) { + $process->signal(SIGKILL); + } + }); + } catch (RuntimeException $e) { + $this->fail('A call to signal() is not expected to cause wait() to throw a RuntimeException'); + } + } + + public function testTermSignalTerminatesProcessCleanly() + { + $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); + + try { + $process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"'); + $process->run(function () use ($process) { + if ($process->isRunning()) { + $process->signal(SIGTERM); + } + }); + } catch (RuntimeException $e) { + $this->fail('A call to signal() is not expected to cause wait() to throw a RuntimeException'); + } + } + /** * {@inheritdoc} */ From 5939d34c17350684a0c5004591df7021d2f5ec9b Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Fri, 25 Jul 2014 09:46:51 +0200 Subject: [PATCH 08/13] [Process] Fix unit tests in sigchild environment --- .../Process/Tests/SigchildDisabledProcessTest.php | 5 +++++ .../Process/Tests/SigchildEnabledProcessTest.php | 15 +++++++++++++++ .../Component/Process/Tests/SimpleProcessTest.php | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php b/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php index 798e66a57193..383a53220314 100644 --- a/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php +++ b/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php @@ -211,6 +211,11 @@ public function testExitCodeIsAvailableAfterSignal() $this->markTestSkipped('Signal is not supported in sigchild environment'); } + public function testRunProcessWithTimeout() + { + $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php b/src/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php index 65dd4bb57364..37a064188f7d 100644 --- a/src/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php +++ b/src/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php @@ -120,6 +120,21 @@ public function testStartAfterATimeout() parent::testStartAfterATimeout(); } + public function testStopWithTimeoutIsActuallyWorking() + { + $this->markTestSkipped('Stopping with signal is not supported in sigchild environment'); + } + + public function testRunProcessWithTimeout() + { + $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); + } + + public function testCheckTimeoutOnStartedProcess() + { + $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php b/src/Symfony/Component/Process/Tests/SimpleProcessTest.php index cb06f289682f..ccaa78df2459 100644 --- a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php +++ b/src/Symfony/Component/Process/Tests/SimpleProcessTest.php @@ -191,6 +191,13 @@ public function testTermSignalTerminatesProcessCleanly() } } + public function testStopWithTimeoutIsActuallyWorking() + { + $this->skipIfPHPSigchild(); + + parent::testStopWithTimeoutIsActuallyWorking(); + } + /** * {@inheritdoc} */ From fdbb04a6aca2dd11cc8bb1418a5d0156dd8a650e Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 25 Jul 2014 15:59:30 +0200 Subject: [PATCH 09/13] [EventDispatcher] don't count empty listeners When event listeners for certain events are removed from the event dispatcher, empty arrays are not being removed. Therefore, counting on empty arrays leads to wrong results of the hasListeners() method. --- .../EventDispatcher/EventDispatcher.php | 2 +- .../Tests/EventDispatcherTest.php | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index 6d2f683a7d17..e189a57e42bf 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -74,7 +74,7 @@ public function getListeners($eventName = null) } } - return $this->sorted; + return array_filter($this->sorted); } /** diff --git a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php index f1053cfe1d89..1053c290ee69 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php @@ -23,6 +23,9 @@ class EventDispatcherTest extends \PHPUnit_Framework_TestCase const preBar = 'pre.bar'; const postBar = 'post.bar'; + /** + * @var \Symfony\Component\EventDispatcher\EventDispatcher + */ private $dispatcher; private $listener; @@ -261,6 +264,28 @@ public function testWorkaroundForPhpBug62976() $dispatcher->removeListener('bug.62976', function () {}); $this->assertTrue($dispatcher->hasListeners('bug.62976')); } + + public function testHasListenersWhenAddedCallbackListenerIsRemoved() + { + $listener = function () {}; + $this->dispatcher->addListener('foo', $listener); + $this->dispatcher->removeListener('foo', $listener); + $this->assertFalse($this->dispatcher->hasListeners()); + } + + public function testGetListenersWhenAddedCallbackListenerIsRemoved() + { + $listener = function () {}; + $this->dispatcher->addListener('foo', $listener); + $this->dispatcher->removeListener('foo', $listener); + $this->assertSame(array(), $this->dispatcher->getListeners()); + } + + public function testHasListenersWithoutEventsReturnsFalseAfterHasListenersWithEventHasBeenCalled() + { + $this->assertFalse($this->dispatcher->hasListeners('foo')); + $this->assertFalse($this->dispatcher->hasListeners()); + } } class CallableClass From be04c5000c1bc7865530228a25b4c57276b550b5 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 26 Jul 2014 11:54:23 +0200 Subject: [PATCH 10/13] Unify null comparisons --- .../Doctrine/ContainerAwareEventManager.php | 2 +- .../DependencyInjection/Configuration.php | 2 +- .../views/Form/choice_widget_collapsed.html.php | 2 +- .../Bundle/FrameworkBundle/Test/WebTestCase.php | 4 ++-- .../Resources/views/Collector/time.html.twig | 2 +- .../Resources/views/Profiler/layout.html.twig | 16 ++++++++-------- .../Tests/Definition/Builder/ExprBuilderTest.php | 2 +- .../Finder/Tests/Iterator/MockSplFileInfo.php | 6 +++--- .../ViolationMapper/ViolationPathTest.php | 2 +- .../RememberMe/AbstractRememberMeServices.php | 2 +- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php b/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php index ac21ece6e0a9..5f6902d4a4b3 100644 --- a/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php +++ b/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php @@ -49,7 +49,7 @@ public function __construct(ContainerInterface $container) public function dispatchEvent($eventName, EventArgs $eventArgs = null) { if (isset($this->listeners[$eventName])) { - $eventArgs = $eventArgs === null ? EventArgs::getEmptyInstance() : $eventArgs; + $eventArgs = null === $eventArgs ? EventArgs::getEmptyInstance() : $eventArgs; $initialized = isset($this->initialized[$eventName]); diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 852f8ba4246c..fc6a6ade56d3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -41,7 +41,7 @@ public function getConfigTreeBuilder() ->end() ->arrayNode('trusted_proxies') ->beforeNormalization() - ->ifTrue(function ($v) { return !is_array($v) && !is_null($v); }) + ->ifTrue(function ($v) { return !is_array($v) && null !== $v; }) ->then(function ($v) { return is_bool($v) ? array() : preg_split('/\s*,\s*/', $v); }) ->end() ->prototype('scalar') diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php index 345be23b03f9..be78e46e8cc6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php @@ -1,5 +1,5 @@