2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\EventDispatcher\Tests\Debug ;
2017-04-13 15:53:35 +01:00
use PHPUnit\Framework\TestCase ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher ;
use Symfony\Component\EventDispatcher\EventDispatcherInterface ;
use Symfony\Component\EventDispatcher\EventSubscriberInterface ;
use Symfony\Component\EventDispatcher\EventDispatcher ;
use Symfony\Component\EventDispatcher\Event ;
use Symfony\Component\Stopwatch\Stopwatch ;
2017-04-13 15:53:35 +01:00
class TraceableEventDispatcherTest extends TestCase
2015-08-17 17:00:26 -07:00
{
public function testAddRemoveListener ()
{
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
2016-04-20 09:56:34 -07:00
$tdispatcher -> addListener ( 'foo' , $listener = function () {});
2015-08-17 17:00:26 -07:00
$listeners = $dispatcher -> getListeners ( 'foo' );
$this -> assertCount ( 1 , $listeners );
$this -> assertSame ( $listener , $listeners [ 0 ]);
$tdispatcher -> removeListener ( 'foo' , $listener );
$this -> assertCount ( 0 , $dispatcher -> getListeners ( 'foo' ));
}
public function testGetListeners ()
{
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
2016-04-20 09:56:34 -07:00
$tdispatcher -> addListener ( 'foo' , $listener = function () {});
2015-08-17 17:00:26 -07:00
$this -> assertSame ( $dispatcher -> getListeners ( 'foo' ), $tdispatcher -> getListeners ( 'foo' ));
}
public function testHasListeners ()
{
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
$this -> assertFalse ( $dispatcher -> hasListeners ( 'foo' ));
$this -> assertFalse ( $tdispatcher -> hasListeners ( 'foo' ));
2016-04-20 09:56:34 -07:00
$tdispatcher -> addListener ( 'foo' , $listener = function () {});
2015-08-17 17:00:26 -07:00
$this -> assertTrue ( $dispatcher -> hasListeners ( 'foo' ));
$this -> assertTrue ( $tdispatcher -> hasListeners ( 'foo' ));
}
2016-04-20 09:56:34 -07:00
public function testGetListenerPriority ()
{
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
$tdispatcher -> addListener ( 'foo' , function () {}, 123 );
$listeners = $dispatcher -> getListeners ( 'foo' );
$this -> assertSame ( 123 , $tdispatcher -> getListenerPriority ( 'foo' , $listeners [ 0 ]));
// Verify that priority is preserved when listener is removed and re-added
// in preProcess() and postProcess().
$tdispatcher -> dispatch ( 'foo' , new Event ());
$listeners = $dispatcher -> getListeners ( 'foo' );
$this -> assertSame ( 123 , $tdispatcher -> getListenerPriority ( 'foo' , $listeners [ 0 ]));
}
2017-02-02 16:28:38 -08:00
public function testGetListenerPriorityReturnsZeroWhenWrappedMethodDoesNotExist ()
{
$dispatcher = $this -> getMockBuilder ( 'Symfony\Component\EventDispatcher\EventDispatcherInterface' ) -> getMock ();
$traceableEventDispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
$traceableEventDispatcher -> addListener ( 'foo' , function () {}, 123 );
$listeners = $traceableEventDispatcher -> getListeners ( 'foo' );
$this -> assertSame ( 0 , $traceableEventDispatcher -> getListenerPriority ( 'foo' , $listeners [ 0 ]));
}
2015-08-17 17:00:26 -07:00
public function testAddRemoveSubscriber ()
{
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
$subscriber = new EventSubscriber ();
$tdispatcher -> addSubscriber ( $subscriber );
$listeners = $dispatcher -> getListeners ( 'foo' );
$this -> assertCount ( 1 , $listeners );
$this -> assertSame ( array ( $subscriber , 'call' ), $listeners [ 0 ]);
$tdispatcher -> removeSubscriber ( $subscriber );
$this -> assertCount ( 0 , $dispatcher -> getListeners ( 'foo' ));
}
public function testGetCalledListeners ()
{
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
2016-04-20 09:56:34 -07:00
$tdispatcher -> addListener ( 'foo' , $listener = function () {});
2015-08-17 17:00:26 -07:00
$this -> assertEquals ( array (), $tdispatcher -> getCalledListeners ());
2016-04-20 09:56:34 -07:00
$this -> assertEquals ( array ( 'foo.closure' => array ( 'event' => 'foo' , 'type' => 'Closure' , 'pretty' => 'closure' , 'priority' => 0 )), $tdispatcher -> getNotCalledListeners ());
2015-08-17 17:00:26 -07:00
$tdispatcher -> dispatch ( 'foo' );
2016-04-20 09:56:34 -07:00
$this -> assertEquals ( array ( 'foo.closure' => array ( 'event' => 'foo' , 'type' => 'Closure' , 'pretty' => 'closure' , 'priority' => null )), $tdispatcher -> getCalledListeners ());
2015-08-17 17:00:26 -07:00
$this -> assertEquals ( array (), $tdispatcher -> getNotCalledListeners ());
}
public function testGetCalledListenersNested ()
{
$tdispatcher = null ;
$dispatcher = new TraceableEventDispatcher ( new EventDispatcher (), new Stopwatch ());
$dispatcher -> addListener ( 'foo' , function ( Event $event , $eventName , $dispatcher ) use ( & $tdispatcher ) {
$tdispatcher = $dispatcher ;
$dispatcher -> dispatch ( 'bar' );
});
$dispatcher -> addListener ( 'bar' , function ( Event $event ) {});
$dispatcher -> dispatch ( 'foo' );
$this -> assertSame ( $dispatcher , $tdispatcher );
$this -> assertCount ( 2 , $dispatcher -> getCalledListeners ());
}
public function testLogger ()
{
2017-02-02 16:28:38 -08:00
$logger = $this -> getMockBuilder ( 'Psr\Log\LoggerInterface' ) -> getMock ();
2015-08-17 17:00:26 -07:00
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch (), $logger );
2016-04-20 09:56:34 -07:00
$tdispatcher -> addListener ( 'foo' , $listener1 = function () {});
$tdispatcher -> addListener ( 'foo' , $listener2 = function () {});
2015-08-17 17:00:26 -07:00
2015-10-08 11:40:12 -07:00
$logger -> expects ( $this -> at ( 0 )) -> method ( 'debug' ) -> with ( 'Notified event "foo" to listener "closure".' );
$logger -> expects ( $this -> at ( 1 )) -> method ( 'debug' ) -> with ( 'Notified event "foo" to listener "closure".' );
2015-08-17 17:00:26 -07:00
$tdispatcher -> dispatch ( 'foo' );
}
public function testLoggerWithStoppedEvent ()
{
2017-02-02 16:28:38 -08:00
$logger = $this -> getMockBuilder ( 'Psr\Log\LoggerInterface' ) -> getMock ();
2015-08-17 17:00:26 -07:00
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch (), $logger );
$tdispatcher -> addListener ( 'foo' , $listener1 = function ( Event $event ) { $event -> stopPropagation (); });
2016-04-20 09:56:34 -07:00
$tdispatcher -> addListener ( 'foo' , $listener2 = function () {});
2015-08-17 17:00:26 -07:00
2015-10-08 11:40:12 -07:00
$logger -> expects ( $this -> at ( 0 )) -> method ( 'debug' ) -> with ( 'Notified event "foo" to listener "closure".' );
$logger -> expects ( $this -> at ( 1 )) -> method ( 'debug' ) -> with ( 'Listener "closure" stopped propagation of the event "foo".' );
$logger -> expects ( $this -> at ( 2 )) -> method ( 'debug' ) -> with ( 'Listener "closure" was not called for event "foo".' );
2015-08-17 17:00:26 -07:00
$tdispatcher -> dispatch ( 'foo' );
}
public function testDispatchCallListeners ()
{
$called = array ();
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
2016-04-20 09:56:34 -07:00
$tdispatcher -> addListener ( 'foo' , function () use ( & $called ) { $called [] = 'foo1' ; }, 10 );
$tdispatcher -> addListener ( 'foo' , function () use ( & $called ) { $called [] = 'foo2' ; }, 20 );
2015-08-17 17:00:26 -07:00
$tdispatcher -> dispatch ( 'foo' );
2016-04-20 09:56:34 -07:00
$this -> assertSame ( array ( 'foo2' , 'foo1' ), $called );
2015-08-17 17:00:26 -07:00
}
public function testDispatchNested ()
{
$dispatcher = new TraceableEventDispatcher ( new EventDispatcher (), new Stopwatch ());
$loop = 1 ;
2017-04-13 15:53:35 +01:00
$dispatchedEvents = 0 ;
2015-08-17 17:00:26 -07:00
$dispatcher -> addListener ( 'foo' , $listener1 = function () use ( $dispatcher , & $loop ) {
++ $loop ;
if ( 2 == $loop ) {
$dispatcher -> dispatch ( 'foo' );
}
});
2017-04-13 15:53:35 +01:00
$dispatcher -> addListener ( 'foo' , function () use ( & $dispatchedEvents ) {
++ $dispatchedEvents ;
});
2015-08-17 17:00:26 -07:00
$dispatcher -> dispatch ( 'foo' );
2017-04-13 15:53:35 +01:00
$this -> assertSame ( 2 , $dispatchedEvents );
2015-08-17 17:00:26 -07:00
}
public function testDispatchReusedEventNested ()
{
$nestedCall = false ;
$dispatcher = new TraceableEventDispatcher ( new EventDispatcher (), new Stopwatch ());
$dispatcher -> addListener ( 'foo' , function ( Event $e ) use ( $dispatcher ) {
$dispatcher -> dispatch ( 'bar' , $e );
});
$dispatcher -> addListener ( 'bar' , function ( Event $e ) use ( & $nestedCall ) {
$nestedCall = true ;
});
$this -> assertFalse ( $nestedCall );
$dispatcher -> dispatch ( 'foo' );
$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
{
public static function getSubscribedEvents ()
{
return array ( 'foo' => 'call' );
}
}