2015-02-24 16:25:12 +01: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-06-09 14:30:20 +02:00
use PHPUnit\Framework\TestCase ;
2015-02-24 16:25:12 +01:00
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher ;
2017-06-09 14:30:20 +02:00
use Symfony\Component\EventDispatcher\EventDispatcherInterface ;
2015-02-24 16:25:12 +01:00
use Symfony\Component\EventDispatcher\EventSubscriberInterface ;
use Symfony\Component\EventDispatcher\EventDispatcher ;
use Symfony\Component\EventDispatcher\Event ;
use Symfony\Component\Stopwatch\Stopwatch ;
2017-06-09 14:30:20 +02:00
class TraceableEventDispatcherTest extends TestCase
2015-02-24 16:25:12 +01:00
{
public function testAddRemoveListener ()
{
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
2017-06-09 14:30:20 +02:00
$tdispatcher -> addListener ( 'foo' , $listener = function () {});
2015-02-24 16:25:12 +01: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 ());
2017-06-09 14:30:20 +02:00
$tdispatcher -> addListener ( 'foo' , $listener = function () {});
2015-02-24 16:25:12 +01: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' ));
2017-06-09 14:30:20 +02:00
$tdispatcher -> addListener ( 'foo' , $listener = function () {});
2015-02-24 16:25:12 +01:00
$this -> assertTrue ( $dispatcher -> hasListeners ( 'foo' ));
$this -> assertTrue ( $tdispatcher -> hasListeners ( 'foo' ));
}
2017-06-09 14:30:20 +02: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 ]));
}
public function testGetListenerPriorityWhileDispatching ()
{
$tdispatcher = new TraceableEventDispatcher ( new EventDispatcher (), new Stopwatch ());
$priorityWhileDispatching = null ;
$listener = function () use ( $tdispatcher , & $priorityWhileDispatching , & $listener ) {
$priorityWhileDispatching = $tdispatcher -> getListenerPriority ( 'bar' , $listener );
};
$tdispatcher -> addListener ( 'bar' , $listener , 5 );
$tdispatcher -> dispatch ( 'bar' );
$this -> assertSame ( 5 , $priorityWhileDispatching );
}
2015-02-24 16:25:12 +01: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 ()
{
2017-06-09 14:30:20 +02:00
$tdispatcher = new TraceableEventDispatcher ( new EventDispatcher (), new Stopwatch ());
$tdispatcher -> addListener ( 'foo' , function () {}, 5 );
2015-02-24 16:25:12 +01:00
2017-06-09 14:30:20 +02:00
$listeners = $tdispatcher -> getNotCalledListeners ();
$this -> assertArrayHasKey ( 'stub' , $listeners [ 'foo.closure' ]);
unset ( $listeners [ 'foo.closure' ][ 'stub' ]);
2015-02-24 16:25:12 +01:00
$this -> assertEquals ( array (), $tdispatcher -> getCalledListeners ());
2017-06-09 14:30:20 +02:00
$this -> assertEquals ( array ( 'foo.closure' => array ( 'event' => 'foo' , 'pretty' => 'closure' , 'priority' => 5 )), $listeners );
2015-02-24 16:25:12 +01:00
$tdispatcher -> dispatch ( 'foo' );
2017-06-09 14:30:20 +02:00
$listeners = $tdispatcher -> getCalledListeners ();
$this -> assertArrayHasKey ( 'stub' , $listeners [ 'foo.closure' ]);
unset ( $listeners [ 'foo.closure' ][ 'stub' ]);
$this -> assertEquals ( array ( 'foo.closure' => array ( 'event' => 'foo' , 'pretty' => 'closure' , 'priority' => 5 )), $listeners );
2015-02-24 16:25:12 +01: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-06-09 14:30:20 +02:00
$logger = $this -> getMockBuilder ( 'Psr\Log\LoggerInterface' ) -> getMock ();
2015-02-24 16:25:12 +01:00
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch (), $logger );
2017-06-09 14:30:20 +02:00
$tdispatcher -> addListener ( 'foo' , $listener1 = function () {});
$tdispatcher -> addListener ( 'foo' , $listener2 = function () {});
2015-02-24 16:25:12 +01:00
2017-06-09 14:30:20 +02:00
$logger -> expects ( $this -> at ( 0 )) -> method ( 'debug' ) -> with ( 'Notified event "{event}" to listener "{listener}".' , array ( 'event' => 'foo' , 'listener' => 'closure' ));
$logger -> expects ( $this -> at ( 1 )) -> method ( 'debug' ) -> with ( 'Notified event "{event}" to listener "{listener}".' , array ( 'event' => 'foo' , 'listener' => 'closure' ));
2015-02-24 16:25:12 +01:00
$tdispatcher -> dispatch ( 'foo' );
}
public function testLoggerWithStoppedEvent ()
{
2017-06-09 14:30:20 +02:00
$logger = $this -> getMockBuilder ( 'Psr\Log\LoggerInterface' ) -> getMock ();
2015-02-24 16:25:12 +01:00
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch (), $logger );
$tdispatcher -> addListener ( 'foo' , $listener1 = function ( Event $event ) { $event -> stopPropagation (); });
2017-06-09 14:30:20 +02:00
$tdispatcher -> addListener ( 'foo' , $listener2 = function () {});
2015-02-24 16:25:12 +01:00
2017-06-09 14:30:20 +02:00
$logger -> expects ( $this -> at ( 0 )) -> method ( 'debug' ) -> with ( 'Notified event "{event}" to listener "{listener}".' , array ( 'event' => 'foo' , 'listener' => 'closure' ));
$logger -> expects ( $this -> at ( 1 )) -> method ( 'debug' ) -> with ( 'Listener "{listener}" stopped propagation of the event "{event}".' , array ( 'event' => 'foo' , 'listener' => 'closure' ));
$logger -> expects ( $this -> at ( 2 )) -> method ( 'debug' ) -> with ( 'Listener "{listener}" was not called for event "{event}".' , array ( 'event' => 'foo' , 'listener' => 'closure' ));
2015-02-24 16:25:12 +01:00
$tdispatcher -> dispatch ( 'foo' );
}
public function testDispatchCallListeners ()
{
$called = array ();
$dispatcher = new EventDispatcher ();
$tdispatcher = new TraceableEventDispatcher ( $dispatcher , new Stopwatch ());
2017-06-09 14:30:20 +02:00
$tdispatcher -> addListener ( 'foo' , function () use ( & $called ) { $called [] = 'foo1' ; }, 10 );
$tdispatcher -> addListener ( 'foo' , function () use ( & $called ) { $called [] = 'foo2' ; }, 20 );
2015-02-24 16:25:12 +01:00
$tdispatcher -> dispatch ( 'foo' );
2017-06-09 14:30:20 +02:00
$this -> assertSame ( array ( 'foo2' , 'foo1' ), $called );
2015-02-24 16:25:12 +01:00
}
public function testDispatchNested ()
{
$dispatcher = new TraceableEventDispatcher ( new EventDispatcher (), new Stopwatch ());
$loop = 1 ;
2017-06-09 14:30:20 +02:00
$dispatchedEvents = 0 ;
2015-02-24 16:25:12 +01:00
$dispatcher -> addListener ( 'foo' , $listener1 = function () use ( $dispatcher , & $loop ) {
++ $loop ;
if ( 2 == $loop ) {
$dispatcher -> dispatch ( 'foo' );
}
});
2017-06-09 14:30:20 +02:00
$dispatcher -> addListener ( 'foo' , function () use ( & $dispatchedEvents ) {
++ $dispatchedEvents ;
});
2015-02-24 16:25:12 +01:00
$dispatcher -> dispatch ( 'foo' );
2017-06-09 14:30:20 +02:00
$this -> assertSame ( 2 , $dispatchedEvents );
2015-02-24 16:25:12 +01: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 );
}
2017-06-09 14:30:20 +02:00
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' );
}
2015-02-24 16:25:12 +01:00
}
class EventSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents ()
{
return array ( 'foo' => 'call' );
}
}