301 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			301 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|  | <?php | ||
|  | 
 | ||
|  | namespace Alchemy\Tests\BinaryDriver; | ||
|  | 
 | ||
|  | use Alchemy\BinaryDriver\AbstractBinary; | ||
|  | use Alchemy\BinaryDriver\BinaryDriverTestCase; | ||
|  | use Alchemy\BinaryDriver\Configuration; | ||
|  | use Alchemy\BinaryDriver\Exception\ExecutableNotFoundException; | ||
|  | use Alchemy\BinaryDriver\Listeners\ListenerInterface; | ||
|  | use Symfony\Component\Process\ExecutableFinder; | ||
|  | 
 | ||
|  | class AbstractBinaryTest extends BinaryDriverTestCase | ||
|  | { | ||
|  |     protected function getPhpBinary() | ||
|  |     { | ||
|  |         $finder = new ExecutableFinder(); | ||
|  |         $php    = $finder->find('php'); | ||
|  | 
 | ||
|  |         if (null === $php) { | ||
|  |             $this->markTestSkipped('Unable to find a php binary'); | ||
|  |         } | ||
|  | 
 | ||
|  |         return $php; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testSimpleLoadWithBinaryPath() | ||
|  |     { | ||
|  |         $php = $this->getPhpBinary(); | ||
|  |         $imp = Implementation::load($php); | ||
|  |         $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp); | ||
|  | 
 | ||
|  |         $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testMultipleLoadWithBinaryPath() | ||
|  |     { | ||
|  |         $php = $this->getPhpBinary(); | ||
|  |         $imp = Implementation::load(['/zz/path/to/unexisting/command', $php]); | ||
|  |         $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp); | ||
|  | 
 | ||
|  |         $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testSimpleLoadWithBinaryName() | ||
|  |     { | ||
|  |         $php = $this->getPhpBinary(); | ||
|  |         $imp = Implementation::load('php'); | ||
|  |         $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp); | ||
|  | 
 | ||
|  |         $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testMultipleLoadWithBinaryName() | ||
|  |     { | ||
|  |         $php = $this->getPhpBinary(); | ||
|  |         $imp = Implementation::load(['bachibouzouk', 'php']); | ||
|  |         $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp); | ||
|  | 
 | ||
|  |         $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testLoadWithMultiplePathExpectingAFailure() | ||
|  |     { | ||
|  |         $this->expectException(ExecutableNotFoundException::class); | ||
|  | 
 | ||
|  |         Implementation::load(['bachibouzouk', 'moribon']); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testLoadWithUniquePathExpectingAFailure() | ||
|  |     { | ||
|  |         $this->expectException(ExecutableNotFoundException::class); | ||
|  | 
 | ||
|  |         Implementation::load('bachibouzouk'); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testLoadWithCustomLogger() | ||
|  |     { | ||
|  |         $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); | ||
|  |         $imp    = Implementation::load('php', $logger); | ||
|  | 
 | ||
|  |         $this->assertEquals($logger, $imp->getProcessRunner()->getLogger()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testLoadWithCustomConfigurationAsArray() | ||
|  |     { | ||
|  |         $conf = ['timeout' => 200]; | ||
|  |         $imp  = Implementation::load('php', null, $conf); | ||
|  | 
 | ||
|  |         $this->assertEquals($conf, $imp->getConfiguration()->all()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testLoadWithCustomConfigurationAsObject() | ||
|  |     { | ||
|  |         $conf = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock(); | ||
|  |         $imp  = Implementation::load('php', null, $conf); | ||
|  | 
 | ||
|  |         $this->assertEquals($conf, $imp->getConfiguration()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testProcessBuilderFactoryGetterAndSetters() | ||
|  |     { | ||
|  |         $imp     = Implementation::load('php'); | ||
|  |         $factory = $this->getMockBuilder('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface')->getMock(); | ||
|  | 
 | ||
|  |         $imp->setProcessBuilderFactory($factory); | ||
|  |         $this->assertEquals($factory, $imp->getProcessBuilderFactory()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testConfigurationGetterAndSetters() | ||
|  |     { | ||
|  |         $imp  = Implementation::load('php'); | ||
|  |         $conf = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock(); | ||
|  | 
 | ||
|  |         $imp->setConfiguration($conf); | ||
|  |         $this->assertEquals($conf, $imp->getConfiguration()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testTimeoutIsSetOnConstruction() | ||
|  |     { | ||
|  |         $imp = Implementation::load('php', null, ['timeout' => 42]); | ||
|  |         $this->assertEquals(42, $imp->getProcessBuilderFactory()->getTimeout()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testTimeoutIsSetOnConfigurationSetting() | ||
|  |     { | ||
|  |         $imp = Implementation::load('php', null); | ||
|  |         $imp->setConfiguration(new Configuration(['timeout' => 42])); | ||
|  |         $this->assertEquals(42, $imp->getProcessBuilderFactory()->getTimeout()); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testTimeoutIsSetOnProcessBuilderSetting() | ||
|  |     { | ||
|  |         $imp = Implementation::load('php', null, ['timeout' => 42]); | ||
|  | 
 | ||
|  |         $factory = $this->getMockBuilder('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface')->getMock(); | ||
|  |         $factory->expects($this->once()) | ||
|  |             ->method('setTimeout') | ||
|  |             ->with(42); | ||
|  | 
 | ||
|  |         $imp->setProcessBuilderFactory($factory); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testListenRegistersAListener() | ||
|  |     { | ||
|  |         $imp = Implementation::load('php'); | ||
|  | 
 | ||
|  |         $listeners = $this->getMockBuilder('Alchemy\BinaryDriver\Listeners\Listeners') | ||
|  |             ->disableOriginalConstructor() | ||
|  |             ->getMock(); | ||
|  | 
 | ||
|  |         $listener = $this->getMockBuilder('Alchemy\BinaryDriver\Listeners\ListenerInterface')->getMock(); | ||
|  | 
 | ||
|  |         $listeners->expects($this->once()) | ||
|  |             ->method('register') | ||
|  |             ->with($this->equalTo($listener), $this->equalTo($imp)); | ||
|  | 
 | ||
|  |         $reflexion = new \ReflectionClass('Alchemy\BinaryDriver\AbstractBinary'); | ||
|  |         $prop      = $reflexion->getProperty('listenersManager'); | ||
|  |         $prop->setAccessible(true); | ||
|  |         $prop->setValue($imp, $listeners); | ||
|  | 
 | ||
|  |         $imp->listen($listener); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @dataProvider provideCommandParameters | ||
|  |      */ | ||
|  |     public function testCommandRunsAProcess($parameters, $bypassErrors, $expectedParameters, $output) | ||
|  |     { | ||
|  |         $imp           = Implementation::load('php'); | ||
|  |         $factory       = $this->getMockBuilder('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface')->getMock(); | ||
|  |         $processRunner = $this->getMockBuilder('Alchemy\BinaryDriver\ProcessRunnerInterface')->getMock(); | ||
|  | 
 | ||
|  |         $process = $this->getMockBuilder('Symfony\Component\Process\Process') | ||
|  |             ->disableOriginalConstructor() | ||
|  |             ->getMock(); | ||
|  | 
 | ||
|  |         $processRunner->expects($this->once()) | ||
|  |             ->method('run') | ||
|  |             ->with($this->equalTo($process), $this->isInstanceOf('SplObjectStorage'), $this->equalTo($bypassErrors)) | ||
|  |             ->will($this->returnValue($output)); | ||
|  | 
 | ||
|  |         $factory->expects($this->once()) | ||
|  |             ->method('create') | ||
|  |             ->with($expectedParameters) | ||
|  |             ->will($this->returnValue($process)); | ||
|  | 
 | ||
|  |         $imp->setProcessBuilderFactory($factory); | ||
|  |         $imp->setProcessRunner($processRunner); | ||
|  | 
 | ||
|  |         $this->assertEquals($output, $imp->command($parameters, $bypassErrors)); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @dataProvider provideCommandWithListenersParameters | ||
|  |      */ | ||
|  |     public function testCommandWithTemporaryListeners($parameters, $bypassErrors, $expectedParameters, $output, $count, $listeners) | ||
|  |     { | ||
|  |         $imp           = Implementation::load('php'); | ||
|  |         $factory       = $this->getMockBuilder('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface')->getMock(); | ||
|  |         $processRunner = $this->getMockBuilder('Alchemy\BinaryDriver\ProcessRunnerInterface')->getMock(); | ||
|  | 
 | ||
|  |         $process = $this->getMockBuilder('Symfony\Component\Process\Process') | ||
|  |             ->disableOriginalConstructor() | ||
|  |             ->getMock(); | ||
|  | 
 | ||
|  |         $firstStorage = $secondStorage = null; | ||
|  | 
 | ||
|  |         $processRunner->expects($this->exactly(2)) | ||
|  |             ->method('run') | ||
|  |             ->with($this->equalTo($process), $this->isInstanceOf('SplObjectStorage'), $this->equalTo($bypassErrors)) | ||
|  |             ->will($this->returnCallback(function ($process, $storage, $errors) use ($output, &$firstStorage, &$secondStorage) { | ||
|  |                 if (null === $firstStorage) { | ||
|  |                     $firstStorage = $storage; | ||
|  |                 } else { | ||
|  |                     $secondStorage = $storage; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 return $output; | ||
|  |             })); | ||
|  | 
 | ||
|  |         $factory->expects($this->exactly(2)) | ||
|  |             ->method('create') | ||
|  |             ->with($expectedParameters) | ||
|  |             ->will($this->returnValue($process)); | ||
|  | 
 | ||
|  |         $imp->setProcessBuilderFactory($factory); | ||
|  |         $imp->setProcessRunner($processRunner); | ||
|  | 
 | ||
|  |         $this->assertEquals($output, $imp->command($parameters, $bypassErrors, $listeners)); | ||
|  |         $this->assertCount($count, $firstStorage); | ||
|  |         $this->assertEquals($output, $imp->command($parameters, $bypassErrors)); | ||
|  |         $this->assertCount(0, $secondStorage); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function provideCommandWithListenersParameters() | ||
|  |     { | ||
|  |         return [ | ||
|  |             ['-a', false, ['-a'], 'loubda', 2, [$this->getMockListener(), $this->getMockListener()]], | ||
|  |             ['-a', false, ['-a'], 'loubda', 1, [$this->getMockListener()]], | ||
|  |             ['-a', false, ['-a'], 'loubda', 1, $this->getMockListener()], | ||
|  |             ['-a', false, ['-a'], 'loubda', 0, []], | ||
|  |         ]; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function provideCommandParameters() | ||
|  |     { | ||
|  |         return [ | ||
|  |             ['-a', false, ['-a'], 'loubda'], | ||
|  |             ['-a', true, ['-a'], 'loubda'], | ||
|  |             ['-a -b', false, ['-a -b'], 'loubda'], | ||
|  |             [['-a'], false, ['-a'], 'loubda'], | ||
|  |             [['-a'], true, ['-a'], 'loubda'], | ||
|  |             [['-a', '-b'], false, ['-a', '-b'], 'loubda'], | ||
|  |         ]; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testUnlistenUnregistersAListener() | ||
|  |     { | ||
|  |         $imp = Implementation::load('php'); | ||
|  | 
 | ||
|  |         $listeners = $this->getMockBuilder('Alchemy\BinaryDriver\Listeners\Listeners') | ||
|  |             ->disableOriginalConstructor() | ||
|  |             ->getMock(); | ||
|  | 
 | ||
|  |         $listener = $this->getMockBuilder('Alchemy\BinaryDriver\Listeners\ListenerInterface')->getMock(); | ||
|  | 
 | ||
|  |         $listeners->expects($this->once()) | ||
|  |             ->method('unregister') | ||
|  |             ->with($this->equalTo($listener), $this->equalTo($imp)); | ||
|  | 
 | ||
|  |         $reflexion = new \ReflectionClass('Alchemy\BinaryDriver\AbstractBinary'); | ||
|  |         $prop      = $reflexion->getProperty('listenersManager'); | ||
|  |         $prop->setAccessible(true); | ||
|  |         $prop->setValue($imp, $listeners); | ||
|  | 
 | ||
|  |         $imp->unlisten($listener); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @return \PHPUnit_Framework_MockObject_MockObject | ||
|  |      */ | ||
|  |     private function getMockListener() | ||
|  |     { | ||
|  |         $listener = $this->getMockBuilder(ListenerInterface::class)->getMock(); | ||
|  |         $listener->expects($this->any()) | ||
|  |             ->method('forwardedEvents') | ||
|  |             ->willReturn([]); | ||
|  | 
 | ||
|  |         return $listener; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | class Implementation extends AbstractBinary | ||
|  | { | ||
|  |     public function getName() | ||
|  |     { | ||
|  |         return 'Implementation'; | ||
|  |     } | ||
|  | } |