2012-05-15 20:25:18 +00:00
< ? php
2012-05-22 11:16:56 +00:00
2012-05-15 20:25:18 +00:00
/*
* This file is part of Composer .
*
* ( c ) Nils Adermann < naderman @ naderman . de >
* Jordi Boggiano < j . boggiano @ seld . be >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2013-08-14 15:42:11 +00:00
namespace Composer\Test\EventDispatcher ;
2012-05-15 20:25:18 +00:00
2013-08-14 15:42:11 +00:00
use Composer\EventDispatcher\Event ;
2016-07-21 22:20:56 +00:00
use Composer\EventDispatcher\EventDispatcher ;
2018-11-26 11:35:41 +00:00
use Composer\EventDispatcher\ScriptExecutionException ;
2014-09-30 15:26:55 +00:00
use Composer\Installer\InstallerEvents ;
2016-02-10 14:35:53 +00:00
use Composer\Config ;
use Composer\Composer ;
2018-11-12 14:23:32 +00:00
use Composer\Test\TestCase ;
2016-01-28 13:41:19 +00:00
use Composer\IO\BufferIO ;
2014-09-30 15:26:55 +00:00
use Composer\Script\ScriptEvents ;
2018-11-12 14:57:44 +00:00
use Composer\Script\Event as ScriptEvent ;
2012-12-06 08:56:27 +00:00
use Composer\Util\ProcessExecutor ;
2016-01-28 13:41:19 +00:00
use Symfony\Component\Console\Output\OutputInterface ;
2012-05-15 20:25:18 +00:00
class EventDispatcherTest extends TestCase
{
/**
2012-05-22 11:16:56 +00:00
* @ expectedException RuntimeException
2012-05-15 20:25:18 +00:00
*/
2012-05-22 11:16:56 +00:00
public function testListenerExceptionsAreCaught ()
2012-05-15 20:25:18 +00:00
{
2018-04-12 08:24:56 +00:00
$io = $this -> getMockBuilder ( 'Composer\IO\IOInterface' ) -> getMock ();
2012-05-15 20:25:18 +00:00
$dispatcher = $this -> getDispatcherStubForListenersTest ( array (
2015-09-28 09:51:14 +00:00
'Composer\Test\EventDispatcher\EventDispatcherTest::call' ,
2012-05-22 11:16:56 +00:00
), $io );
2015-06-24 07:21:36 +00:00
$io -> expects ( $this -> at ( 0 ))
2015-07-04 11:22:58 +00:00
-> method ( 'isVerbose' )
-> willReturn ( 0 );
$io -> expects ( $this -> at ( 1 ))
2015-06-24 07:21:36 +00:00
-> method ( 'writeError' )
-> with ( '> Composer\Test\EventDispatcher\EventDispatcherTest::call' );
2015-07-04 11:22:58 +00:00
$io -> expects ( $this -> at ( 2 ))
2015-02-06 12:52:44 +00:00
-> method ( 'writeError' )
2013-08-14 15:42:11 +00:00
-> with ( '<error>Script Composer\Test\EventDispatcher\EventDispatcherTest::call handling the post-install-cmd event terminated with an exception</error>' );
2012-05-22 11:16:56 +00:00
2015-02-23 15:31:54 +00:00
$dispatcher -> dispatchScript ( ScriptEvents :: POST_INSTALL_CMD , false );
2012-05-15 20:25:18 +00:00
}
2012-10-07 02:54:52 +00:00
/**
* @ dataProvider getValidCommands
* @ param string $command
*/
public function testDispatcherCanExecuteSingleCommandLineScript ( $command )
2012-09-29 21:24:59 +00:00
{
2018-04-12 08:24:56 +00:00
$process = $this -> getMockBuilder ( 'Composer\Util\ProcessExecutor' ) -> getMock ();
2013-08-14 15:42:11 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
2012-09-29 21:24:59 +00:00
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$this -> createComposerInstance (),
2018-04-12 08:24:56 +00:00
$this -> getMockBuilder ( 'Composer\IO\IOInterface' ) -> getMock (),
2012-09-29 21:24:59 +00:00
$process ,
))
-> setMethods ( array ( 'getListeners' ))
-> getMock ();
2012-10-07 02:54:52 +00:00
$listener = array ( $command );
2012-09-29 21:24:59 +00:00
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
2012-10-07 02:54:52 +00:00
-> will ( $this -> returnValue ( $listener ));
2012-09-29 21:24:59 +00:00
$process -> expects ( $this -> once ())
-> method ( 'execute' )
2013-05-28 17:15:22 +00:00
-> with ( $command )
-> will ( $this -> returnValue ( 0 ));
2012-09-29 21:24:59 +00:00
2015-02-23 15:31:54 +00:00
$dispatcher -> dispatchScript ( ScriptEvents :: POST_INSTALL_CMD , false );
2012-09-29 21:24:59 +00:00
}
2016-07-21 22:20:56 +00:00
/**
* @ dataProvider getDevModes
* @ param bool $devMode
*/
public function testDispatcherPassDevModeToAutoloadGeneratorForScriptEvents ( $devMode )
{
$composer = $this -> createComposerInstance ();
$generator = $this -> getGeneratorMockForDevModePassingTest ();
$generator -> expects ( $this -> atLeastOnce ())
-> method ( 'setDevMode' )
-> with ( $devMode );
$composer -> setAutoloadGenerator ( $generator );
2018-04-12 08:24:56 +00:00
$package = $this -> getMockBuilder ( 'Composer\Package\RootPackageInterface' ) -> getMock ();
2016-07-21 22:20:56 +00:00
$package -> method ( 'getScripts' ) -> will ( $this -> returnValue ( array ( 'scriptName' => array ( 'scriptName' ))));
$composer -> setPackage ( $package );
$composer -> setRepositoryManager ( $this -> getRepositoryManagerMockForDevModePassingTest ());
2018-04-12 08:24:56 +00:00
$composer -> setInstallationManager ( $this -> getMockBuilder ( 'Composer\Installer\InstallationManager' ) -> getMock ());
2016-07-21 22:20:56 +00:00
$dispatcher = new EventDispatcher (
$composer ,
2018-04-12 08:24:56 +00:00
$this -> getMockBuilder ( 'Composer\IO\IOInterface' ) -> getMock (),
$this -> getMockBuilder ( 'Composer\Util\ProcessExecutor' ) -> getMock ()
2016-07-21 22:20:56 +00:00
);
$event = $this -> getMockBuilder ( 'Composer\Script\Event' )
-> disableOriginalConstructor ()
-> getMock ();
$event -> method ( 'getName' ) -> will ( $this -> returnValue ( 'scriptName' ));
$event -> expects ( $this -> atLeastOnce ())
-> method ( 'isDevMode' )
-> will ( $this -> returnValue ( $devMode ));
$dispatcher -> hasEventListeners ( $event );
}
public function getDevModes ()
{
return array (
array ( true ),
array ( false ),
);
}
private function getGeneratorMockForDevModePassingTest ()
{
$generator = $this -> getMockBuilder ( 'Composer\Autoload\AutoloadGenerator' )
-> disableOriginalConstructor ()
-> setMethods ( array (
'buildPackageMap' ,
'parseAutoloads' ,
'createLoader' ,
'setDevMode' ,
))
-> getMock ();
$generator
-> method ( 'buildPackageMap' )
-> will ( $this -> returnValue ( array ()));
$generator
-> method ( 'parseAutoloads' )
-> will ( $this -> returnValue ( array ()));
$generator
-> method ( 'createLoader' )
2018-04-12 08:24:56 +00:00
-> will ( $this -> returnValue ( $this -> getMockBuilder ( 'Composer\Autoload\ClassLoader' ) -> getMock ()));
2016-07-21 22:20:56 +00:00
return $generator ;
}
private function getRepositoryManagerMockForDevModePassingTest ()
{
$rm = $this -> getMockBuilder ( 'Composer\Repository\RepositoryManager' )
-> disableOriginalConstructor ()
-> setMethods ( array ( 'getLocalRepository' ))
-> getMock ();
2018-04-12 08:24:56 +00:00
$repo = $this -> getMockBuilder ( 'Composer\Repository\InstalledRepositoryInterface' ) -> getMock ();
2016-07-21 22:20:56 +00:00
$repo
-> method ( 'getCanonicalPackages' )
-> will ( $this -> returnValue ( array ()));
$rm
-> method ( 'getLocalRepository' )
-> will ( $this -> returnValue ( $repo ));
return $rm ;
}
2012-10-07 03:37:52 +00:00
public function testDispatcherCanExecuteCliAndPhpInSameEventScriptStack ()
{
2018-04-12 08:24:56 +00:00
$process = $this -> getMockBuilder ( 'Composer\Util\ProcessExecutor' ) -> getMock ();
2013-08-14 15:42:11 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
2012-10-07 03:37:52 +00:00
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$this -> createComposerInstance (),
2016-01-28 13:41:19 +00:00
$io = new BufferIO ( '' , OutputInterface :: VERBOSITY_VERBOSE ),
2012-10-07 03:37:52 +00:00
$process ,
))
-> setMethods ( array (
'getListeners' ,
))
-> getMock ();
$process -> expects ( $this -> exactly ( 2 ))
2013-05-28 17:15:22 +00:00
-> method ( 'execute' )
-> will ( $this -> returnValue ( 0 ));
2012-10-07 03:37:52 +00:00
$listeners = array (
'echo -n foo' ,
2013-08-14 15:42:11 +00:00
'Composer\\Test\\EventDispatcher\\EventDispatcherTest::someMethod' ,
2012-10-07 03:37:52 +00:00
'echo -n bar' ,
);
2015-06-24 07:21:36 +00:00
2012-10-07 03:37:52 +00:00
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
-> will ( $this -> returnValue ( $listeners ));
2015-02-23 15:31:54 +00:00
$dispatcher -> dispatchScript ( ScriptEvents :: POST_INSTALL_CMD , false );
2016-01-28 13:41:19 +00:00
$expected = '> post-install-cmd: echo -n foo' . PHP_EOL .
'> post-install-cmd: Composer\Test\EventDispatcher\EventDispatcherTest::someMethod' . PHP_EOL .
'> post-install-cmd: echo -n bar' . PHP_EOL ;
$this -> assertEquals ( $expected , $io -> getOutput ());
2012-10-07 03:37:52 +00:00
}
2015-11-09 10:35:48 +00:00
public function testDispatcherCanExecuteComposerScriptGroups ()
{
2018-04-12 08:24:56 +00:00
$process = $this -> getMockBuilder ( 'Composer\Util\ProcessExecutor' ) -> getMock ();
2015-11-21 19:28:10 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
2015-11-09 10:35:48 +00:00
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$composer = $this -> createComposerInstance (),
2016-01-28 13:41:19 +00:00
$io = new BufferIO ( '' , OutputInterface :: VERBOSITY_VERBOSE ),
2015-11-09 10:35:48 +00:00
$process ,
))
-> setMethods ( array (
'getListeners' ,
))
-> getMock ();
$process -> expects ( $this -> exactly ( 3 ))
-> method ( 'execute' )
-> will ( $this -> returnValue ( 0 ));
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
-> will ( $this -> returnCallback ( function ( Event $event ) {
if ( $event -> getName () === 'root' ) {
return array ( '@group' );
2016-05-17 10:34:54 +00:00
}
if ( $event -> getName () === 'group' ) {
2015-11-09 10:35:48 +00:00
return array ( 'echo -n foo' , '@subgroup' , 'echo -n bar' );
2016-05-17 10:34:54 +00:00
}
if ( $event -> getName () === 'subgroup' ) {
2015-11-09 10:35:48 +00:00
return array ( 'echo -n baz' );
}
return array ();
}));
2018-11-12 14:57:44 +00:00
$dispatcher -> dispatch ( 'root' , new ScriptEvent ( 'root' , $composer , $io ));
2016-01-28 13:41:19 +00:00
$expected = '> root: @group' . PHP_EOL .
'> group: echo -n foo' . PHP_EOL .
'> group: @subgroup' . PHP_EOL .
'> subgroup: echo -n baz' . PHP_EOL .
'> group: echo -n bar' . PHP_EOL ;
$this -> assertEquals ( $expected , $io -> getOutput ());
2015-11-09 10:35:48 +00:00
}
2018-11-26 11:35:41 +00:00
public function testRecursionInScriptsNames ()
{
$process = $this -> getMockBuilder ( 'Composer\Util\ProcessExecutor' ) -> getMock ();
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
-> setConstructorArgs ( array (
$composer = $this -> createComposerInstance (),
$io = new BufferIO ( '' , OutputInterface :: VERBOSITY_VERBOSE ),
$process
))
-> setMethods ( array (
'getListeners'
))
-> getMock ();
$process -> expects ( $this -> exactly ( 1 ))
-> method ( 'execute' )
-> will ( $this -> returnValue ( 0 ));
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
-> will ( $this -> returnCallback ( function ( Event $event ) {
if ( $event -> getName () === 'hello' ) {
return array ( 'echo Hello' );
}
if ( $event -> getName () === 'helloWorld' ) {
return array ( '@hello World' );
}
return array ();
}));
$dispatcher -> dispatch ( 'helloWorld' , new CommandEvent ( 'helloWorld' , $composer , $io ));
$expected = " > helloWorld: @hello World " . PHP_EOL .
" > hello: echo Hello " . escapeshellarg ( 'World' ) . PHP_EOL ;
$this -> assertEquals ( $expected , $io -> getOutput ());
2015-11-09 10:35:48 +00:00
}
2015-11-09 12:05:16 +00:00
/**
* @ expectedException RuntimeException
*/
public function testDispatcherDetectInfiniteRecursion ()
{
2018-04-12 08:24:56 +00:00
$process = $this -> getMockBuilder ( 'Composer\Util\ProcessExecutor' ) -> getMock ();
2015-11-09 12:05:16 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$composer = $this -> createComposerInstance (),
2018-04-12 08:24:56 +00:00
$io = $this -> getMockBuilder ( 'Composer\IO\IOInterface' ) -> getMock (),
2015-11-09 12:05:16 +00:00
$process ,
))
-> setMethods ( array (
'getListeners' ,
))
-> getMock ();
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
-> will ( $this -> returnCallback ( function ( Event $event ) {
if ( $event -> getName () === 'root' ) {
return array ( '@recurse' );
2016-05-17 10:34:54 +00:00
}
if ( $event -> getName () === 'recurse' ) {
2015-11-09 12:05:16 +00:00
return array ( '@root' );
}
return array ();
}));
2018-11-12 14:57:44 +00:00
$dispatcher -> dispatch ( 'root' , new ScriptEvent ( 'root' , $composer , $io ));
2015-11-09 12:05:16 +00:00
}
2012-05-22 11:16:56 +00:00
private function getDispatcherStubForListenersTest ( $listeners , $io )
2012-05-15 20:25:18 +00:00
{
2013-08-14 15:42:11 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
2012-05-22 11:16:56 +00:00
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$this -> createComposerInstance (),
2012-05-22 11:16:56 +00:00
$io ,
))
-> setMethods ( array ( 'getListeners' ))
-> getMock ();
2012-05-15 20:25:18 +00:00
$dispatcher -> expects ( $this -> atLeastOnce ())
2012-05-22 11:16:56 +00:00
-> method ( 'getListeners' )
-> will ( $this -> returnValue ( $listeners ));
2012-05-15 20:25:18 +00:00
return $dispatcher ;
}
2012-10-07 02:54:52 +00:00
public function getValidCommands ()
{
return array (
array ( 'phpunit' ),
array ( 'echo foo' ),
array ( 'echo -n foo' ),
);
}
2015-06-09 11:40:13 +00:00
public function testDispatcherOutputsCommand ()
2012-12-06 08:56:27 +00:00
{
2013-08-14 15:42:11 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
2012-12-06 08:56:27 +00:00
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$this -> createComposerInstance (),
2018-04-12 08:24:56 +00:00
$io = $this -> getMockBuilder ( 'Composer\IO\IOInterface' ) -> getMock (),
2016-11-06 04:18:18 +00:00
new ProcessExecutor ( $io ),
2012-12-06 08:56:27 +00:00
))
-> setMethods ( array ( 'getListeners' ))
-> getMock ();
$listener = array ( 'echo foo' );
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
-> will ( $this -> returnValue ( $listener ));
2015-06-09 07:02:32 +00:00
$io -> expects ( $this -> once ())
-> method ( 'writeError' )
-> with ( $this -> equalTo ( '> echo foo' ));
2016-11-06 04:18:18 +00:00
$io -> expects ( $this -> once ())
-> method ( 'write' )
2016-12-06 15:03:03 +00:00
-> with ( $this -> equalTo ( 'foo' . PHP_EOL ), false );
2016-11-06 04:18:18 +00:00
2015-02-23 15:31:54 +00:00
$dispatcher -> dispatchScript ( ScriptEvents :: POST_INSTALL_CMD , false );
2012-12-06 08:56:27 +00:00
}
public function testDispatcherOutputsErrorOnFailedCommand ()
{
2013-08-14 15:42:11 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
2012-12-06 08:56:27 +00:00
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$this -> createComposerInstance (),
2018-04-12 08:24:56 +00:00
$io = $this -> getMockBuilder ( 'Composer\IO\IOInterface' ) -> getMock (),
2012-12-06 08:56:27 +00:00
new ProcessExecutor ,
))
-> setMethods ( array ( 'getListeners' ))
-> getMock ();
2012-12-06 09:07:57 +00:00
$code = 'exit 1' ;
2012-12-06 08:56:27 +00:00
$listener = array ( $code );
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
-> will ( $this -> returnValue ( $listener ));
2015-06-09 11:40:13 +00:00
$io -> expects ( $this -> at ( 0 ))
2015-07-04 11:22:58 +00:00
-> method ( 'isVerbose' )
-> willReturn ( 0 );
$io -> expects ( $this -> at ( 1 ))
2015-06-09 11:40:13 +00:00
-> method ( 'writeError' )
-> willReturn ( '> exit 1' );
2015-07-04 11:22:58 +00:00
$io -> expects ( $this -> at ( 2 ))
2015-02-06 12:52:44 +00:00
-> method ( 'writeError' )
2016-05-05 12:37:01 +00:00
-> with ( $this -> equalTo ( '<error>Script ' . $code . ' handling the post-install-cmd event returned with error code 1</error>' ));
2012-12-06 08:56:27 +00:00
2013-05-28 17:15:22 +00:00
$this -> setExpectedException ( 'RuntimeException' );
2015-02-23 15:31:54 +00:00
$dispatcher -> dispatchScript ( ScriptEvents :: POST_INSTALL_CMD , false );
2012-12-06 08:56:27 +00:00
}
2014-07-29 13:25:16 +00:00
public function testDispatcherInstallerEvents ()
{
2018-04-12 08:24:56 +00:00
$process = $this -> getMockBuilder ( 'Composer\Util\ProcessExecutor' ) -> getMock ();
2014-07-29 13:25:16 +00:00
$dispatcher = $this -> getMockBuilder ( 'Composer\EventDispatcher\EventDispatcher' )
-> setConstructorArgs ( array (
2016-02-10 14:35:53 +00:00
$this -> createComposerInstance (),
2018-04-12 08:24:56 +00:00
$this -> getMockBuilder ( 'Composer\IO\IOInterface' ) -> getMock (),
2014-07-29 13:25:16 +00:00
$process ,
))
-> setMethods ( array ( 'getListeners' ))
-> getMock ();
$dispatcher -> expects ( $this -> atLeastOnce ())
-> method ( 'getListeners' )
-> will ( $this -> returnValue ( array ()));
2018-04-12 08:24:56 +00:00
$policy = $this -> getMockBuilder ( 'Composer\DependencyResolver\PolicyInterface' ) -> getMock ();
2018-09-10 13:23:40 +00:00
$repositorySet = $this -> getMockBuilder ( 'Composer\Repository\RepositorySet' ) -> disableOriginalConstructor () -> getMock ();
2014-07-29 13:25:16 +00:00
$installedRepo = $this -> getMockBuilder ( 'Composer\Repository\CompositeRepository' ) -> disableOriginalConstructor () -> getMock ();
$request = $this -> getMockBuilder ( 'Composer\DependencyResolver\Request' ) -> disableOriginalConstructor () -> getMock ();
2018-09-10 13:23:40 +00:00
$dispatcher -> dispatchInstallerEvent ( InstallerEvents :: PRE_DEPENDENCIES_SOLVING , true , $policy , $repositorySet , $installedRepo , $request );
$dispatcher -> dispatchInstallerEvent ( InstallerEvents :: POST_DEPENDENCIES_SOLVING , true , $policy , $repositorySet , $installedRepo , $request , array ());
2014-07-29 13:25:16 +00:00
}
2012-05-15 20:25:18 +00:00
public static function call ()
{
2012-05-22 11:16:56 +00:00
throw new \RuntimeException ();
2012-05-15 20:25:18 +00:00
}
2012-10-07 03:37:52 +00:00
public static function someMethod ()
{
return true ;
}
2016-02-10 14:35:53 +00:00
private function createComposerInstance ()
{
$composer = new Composer ;
$config = new Config ;
$composer -> setConfig ( $config );
2018-04-12 08:24:56 +00:00
$package = $this -> getMockBuilder ( 'Composer\Package\RootPackageInterface' ) -> getMock ();
2016-08-20 13:49:50 +00:00
$composer -> setPackage ( $package );
2016-02-10 14:35:53 +00:00
return $composer ;
}
2012-06-14 10:10:01 +00:00
}