[BC] Upgraded dependencies, dropped support for anything below PHP 8.0. (#849)
* GitHub actions + style fixes + updated packages * Fixed workflows dir * Support for PHP 8.1 (#1) * Update README.md * Revert some changes from upstream
This commit is contained in:
parent
72c946dc7d
commit
111c153428
335 changed files with 4394 additions and 28116 deletions
300
tests/Alchemy/BinaryDriver/AbstractBinaryTest.php
Normal file
300
tests/Alchemy/BinaryDriver/AbstractBinaryTest.php
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
<?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';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver;
|
||||
|
||||
use Alchemy\BinaryDriver\Exception\InvalidArgumentException;
|
||||
use Alchemy\BinaryDriver\ProcessBuilderFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
|
||||
abstract class AbstractProcessBuilderFactoryTest extends TestCase
|
||||
{
|
||||
public static $phpBinary;
|
||||
|
||||
private $original;
|
||||
/**
|
||||
* @return ProcessBuilderFactory
|
||||
*/
|
||||
abstract protected function getProcessBuilderFactory($binary);
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
ProcessBuilderFactory::$emulateSfLTS = null;
|
||||
if (null === static::$phpBinary) {
|
||||
$this->markTestSkipped('Unable to detect php binary, skipping');
|
||||
}
|
||||
}
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
$finder = new ExecutableFinder();
|
||||
static::$phpBinary = $finder->find('php');
|
||||
}
|
||||
|
||||
public function testThatBinaryIsSetOnConstruction()
|
||||
{
|
||||
$factory = $this->getProcessBuilderFactory(static::$phpBinary);
|
||||
$this->assertEquals(static::$phpBinary, $factory->getBinary());
|
||||
}
|
||||
|
||||
public function testGetSetBinary()
|
||||
{
|
||||
$finder = new ExecutableFinder();
|
||||
$phpUnit = $finder->find('phpunit');
|
||||
|
||||
if (null === $phpUnit) {
|
||||
$this->markTestSkipped('Unable to detect phpunit binary, skipping');
|
||||
}
|
||||
|
||||
$factory = $this->getProcessBuilderFactory(static::$phpBinary);
|
||||
$factory->useBinary($phpUnit);
|
||||
$this->assertEquals($phpUnit, $factory->getBinary());
|
||||
}
|
||||
|
||||
public function testUseNonExistantBinary()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$factory = $this->getProcessBuilderFactory(static::$phpBinary);
|
||||
$factory->useBinary('itissureitdoesnotexist');
|
||||
}
|
||||
|
||||
public function testCreateShouldReturnAProcess()
|
||||
{
|
||||
$factory = $this->getProcessBuilderFactory(static::$phpBinary);
|
||||
$process = $factory->create();
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Process\Process', $process);
|
||||
$this->assertEquals("'" . static::$phpBinary . "'", $process->getCommandLine());
|
||||
}
|
||||
|
||||
public function testCreateWithStringArgument()
|
||||
{
|
||||
$factory = $this->getProcessBuilderFactory(static::$phpBinary);
|
||||
$process = $factory->create('-v');
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Process\Process', $process);
|
||||
$this->assertEquals("'" . static::$phpBinary . "' '-v'", $process->getCommandLine());
|
||||
}
|
||||
|
||||
public function testCreateWithArrayArgument()
|
||||
{
|
||||
$factory = $this->getProcessBuilderFactory(static::$phpBinary);
|
||||
$process = $factory->create(['-r', 'echo "Hello !";']);
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Process\Process', $process);
|
||||
$this->assertEquals("'" . static::$phpBinary . "' '-r' 'echo \"Hello !\";'", $process->getCommandLine());
|
||||
}
|
||||
|
||||
public function testCreateWithTimeout()
|
||||
{
|
||||
$factory = $this->getProcessBuilderFactory(static::$phpBinary);
|
||||
$factory->setTimeout(200);
|
||||
$process = $factory->create(['-i']);
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Process\Process', $process);
|
||||
$this->assertEquals(200, $process->getTimeout());
|
||||
}
|
||||
}
|
||||
78
tests/Alchemy/BinaryDriver/ConfigurationTest.php
Normal file
78
tests/Alchemy/BinaryDriver/ConfigurationTest.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver;
|
||||
|
||||
use Alchemy\BinaryDriver\Configuration;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConfigurationTest extends TestCase
|
||||
{
|
||||
public function testArrayAccessImplementation()
|
||||
{
|
||||
$configuration = new Configuration(['key' => 'value']);
|
||||
|
||||
$this->assertTrue(isset($configuration['key']));
|
||||
$this->assertEquals('value', $configuration['key']);
|
||||
|
||||
$this->assertFalse(isset($configuration['key2']));
|
||||
unset($configuration['key']);
|
||||
$this->assertFalse(isset($configuration['key']));
|
||||
|
||||
$configuration['key2'] = 'value2';
|
||||
$this->assertTrue(isset($configuration['key2']));
|
||||
$this->assertEquals('value2', $configuration['key2']);
|
||||
}
|
||||
|
||||
public function testGetOnNonExistentKeyShouldReturnDefaultValue()
|
||||
{
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals('booba', $conf->get('hooba', 'booba'));
|
||||
$this->assertEquals(null, $conf->get('hooba'));
|
||||
}
|
||||
|
||||
public function testSetHasGetRemove()
|
||||
{
|
||||
$configuration = new Configuration(['key' => 'value']);
|
||||
|
||||
$this->assertTrue($configuration->has('key'));
|
||||
$this->assertEquals('value', $configuration->get('key'));
|
||||
|
||||
$this->assertFalse($configuration->has('key2'));
|
||||
$configuration->remove('key');
|
||||
$this->assertFalse($configuration->has('key'));
|
||||
|
||||
$configuration->set('key2', 'value2');
|
||||
$this->assertTrue($configuration->has('key2'));
|
||||
$this->assertEquals('value2', $configuration->get('key2'));
|
||||
}
|
||||
|
||||
public function testIterator()
|
||||
{
|
||||
$data = [
|
||||
'key1' => 'value1',
|
||||
'key2' => 'value2',
|
||||
'key3' => 'value3',
|
||||
];
|
||||
|
||||
$captured = [];
|
||||
$conf = new Configuration($data);
|
||||
|
||||
foreach ($conf as $key => $value) {
|
||||
$captured[$key] = $value;
|
||||
}
|
||||
|
||||
$this->assertEquals($data, $captured);
|
||||
}
|
||||
|
||||
public function testAll()
|
||||
{
|
||||
$data = [
|
||||
'key1' => 'value1',
|
||||
'key2' => 'value2',
|
||||
'key3' => 'value3',
|
||||
];
|
||||
|
||||
$conf = new Configuration($data);
|
||||
$this->assertEquals($data, $conf->all());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver\Exceptions;
|
||||
|
||||
use Alchemy\BinaryDriver\BinaryDriverTestCase;
|
||||
use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
|
||||
use Alchemy\BinaryDriver\ProcessRunner;
|
||||
|
||||
class ExecutionFailureExceptionTest extends BinaryDriverTestCase
|
||||
{
|
||||
public function getProcessRunner($logger)
|
||||
{
|
||||
return new ProcessRunner($logger, 'test-runner');
|
||||
}
|
||||
|
||||
public function testGetExceptionInfo(){
|
||||
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$process = $this->createProcessMock(1, false, '--helloworld--', null, "Error Output", true);
|
||||
try{
|
||||
$runner->run($process, new \SplObjectStorage(), false);
|
||||
$this->fail('An exception should have been raised');
|
||||
}
|
||||
catch (ExecutionFailureException $e){
|
||||
$this->assertEquals("--helloworld--", $e->getCommand());
|
||||
$this->assertEquals("Error Output", $e->getErrorOutput());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
54
tests/Alchemy/BinaryDriver/LTSProcessBuilder.php
Normal file
54
tests/Alchemy/BinaryDriver/LTSProcessBuilder.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver;
|
||||
|
||||
use Alchemy\BinaryDriver\ProcessBuilderFactory;
|
||||
use LogicException;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\ProcessBuilder;
|
||||
|
||||
class LTSProcessBuilder extends ProcessBuilder
|
||||
{
|
||||
private $arguments;
|
||||
private $prefix;
|
||||
private $timeout;
|
||||
|
||||
public function __construct(array $arguments = array())
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
parent::__construct($arguments);
|
||||
}
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPrefix($prefix)
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTimeout($timeout)
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getProcess()
|
||||
{
|
||||
if (!$this->prefix && !count($this->arguments)) {
|
||||
throw new LogicException('You must add() command arguments before calling getProcess().');
|
||||
}
|
||||
|
||||
$args = $this->prefix ? array_merge(array($this->prefix), $this->arguments) : $this->arguments;
|
||||
$script = implode(' ', array_map('escapeshellarg', $args));
|
||||
|
||||
return new Process($script, null, null, null, $this->timeout);
|
||||
}
|
||||
}
|
||||
28
tests/Alchemy/BinaryDriver/LTSProcessBuilderFactoryTest.php
Normal file
28
tests/Alchemy/BinaryDriver/LTSProcessBuilderFactoryTest.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver;
|
||||
|
||||
use Alchemy\BinaryDriver\ProcessBuilderFactory;
|
||||
|
||||
class LTSProcessBuilderFactoryTest extends AbstractProcessBuilderFactoryTest
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
if (!class_exists('Symfony\Component\Process\ProcessBuilder')) {
|
||||
$this->markTestSkipped('ProcessBuilder is not available.');
|
||||
return;
|
||||
}
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
protected function getProcessBuilderFactory($binary)
|
||||
{
|
||||
$factory = new ProcessBuilderFactory($binary);
|
||||
$factory->setBuilder(new LTSProcessBuilder());
|
||||
ProcessBuilderFactory::$emulateSfLTS = false;
|
||||
$factory->useBinary($binary);
|
||||
|
||||
return $factory;
|
||||
}
|
||||
}
|
||||
34
tests/Alchemy/BinaryDriver/Listeners/DebugListenerTest.php
Normal file
34
tests/Alchemy/BinaryDriver/Listeners/DebugListenerTest.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver\Listeners;
|
||||
|
||||
use Alchemy\BinaryDriver\Listeners\DebugListener;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class DebugListenerTest extends TestCase
|
||||
{
|
||||
public function testHandle()
|
||||
{
|
||||
$listener = new DebugListener();
|
||||
|
||||
$lines = [];
|
||||
$listener->on('debug', function ($line) use (&$lines) {
|
||||
$lines[] = $line;
|
||||
});
|
||||
$listener->handle(Process::ERR, "first line\nsecond line");
|
||||
$listener->handle(Process::OUT, "cool output");
|
||||
$listener->handle('unknown', "lalala");
|
||||
$listener->handle(Process::OUT, "another output\n");
|
||||
|
||||
$expected = [
|
||||
'[ERROR] first line',
|
||||
'[ERROR] second line',
|
||||
'[OUT] cool output',
|
||||
'[OUT] another output',
|
||||
'[OUT] ',
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $lines);
|
||||
}
|
||||
}
|
||||
93
tests/Alchemy/BinaryDriver/Listeners/ListenersTest.php
Normal file
93
tests/Alchemy/BinaryDriver/Listeners/ListenersTest.php
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver\Listeners;
|
||||
|
||||
use Alchemy\BinaryDriver\Listeners\ListenerInterface;
|
||||
use Alchemy\BinaryDriver\Listeners\Listeners;
|
||||
use Evenement\EventEmitter;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ListenersTest extends TestCase
|
||||
{
|
||||
public function testRegister()
|
||||
{
|
||||
$listener = new MockListener();
|
||||
|
||||
$listeners = new Listeners();
|
||||
$listeners->register($listener);
|
||||
|
||||
$n = 0;
|
||||
$listener->on('received', function ($type, $data) use (&$n, &$capturedType, &$capturedData) {
|
||||
$n++;
|
||||
$capturedData = $data;
|
||||
$capturedType = $type;
|
||||
});
|
||||
|
||||
$type = 'type';
|
||||
$data = 'data';
|
||||
|
||||
$listener->handle($type, $data);
|
||||
$listener->handle($type, $data);
|
||||
|
||||
$listeners->unregister($listener);
|
||||
|
||||
$listener->handle($type, $data);
|
||||
|
||||
$this->assertEquals(3, $n);
|
||||
$this->assertEquals($type, $capturedType);
|
||||
$this->assertEquals($data, $capturedData);
|
||||
}
|
||||
|
||||
public function testRegisterAndForwardThenUnregister()
|
||||
{
|
||||
$listener = new MockListener();
|
||||
$target = new EventEmitter();
|
||||
|
||||
$n = 0;
|
||||
$target->on('received', function ($type, $data) use (&$n, &$capturedType, &$capturedData) {
|
||||
$n++;
|
||||
$capturedData = $data;
|
||||
$capturedType = $type;
|
||||
});
|
||||
|
||||
$m = 0;
|
||||
$listener->on('received', function ($type, $data) use (&$m, &$capturedType2, &$capturedData2) {
|
||||
$m++;
|
||||
$capturedData2 = $data;
|
||||
$capturedType2 = $type;
|
||||
});
|
||||
|
||||
$listeners = new Listeners();
|
||||
$listeners->register($listener, $target);
|
||||
|
||||
$type = 'type';
|
||||
$data = 'data';
|
||||
|
||||
$listener->handle($type, $data);
|
||||
$listener->handle($type, $data);
|
||||
|
||||
$listeners->unregister($listener, $target);
|
||||
|
||||
$listener->handle($type, $data);
|
||||
|
||||
$this->assertEquals(2, $n);
|
||||
$this->assertEquals(3, $m);
|
||||
$this->assertEquals($type, $capturedType);
|
||||
$this->assertEquals($data, $capturedData);
|
||||
$this->assertEquals($type, $capturedType2);
|
||||
$this->assertEquals($data, $capturedData2);
|
||||
}
|
||||
}
|
||||
|
||||
class MockListener extends EventEmitter implements ListenerInterface
|
||||
{
|
||||
public function handle($type, $data)
|
||||
{
|
||||
$this->emit('received', [$type, $data]);
|
||||
}
|
||||
|
||||
public function forwardedEvents()
|
||||
{
|
||||
return ['received'];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver;
|
||||
|
||||
use Alchemy\BinaryDriver\ProcessBuilderFactory;
|
||||
|
||||
class NONLTSProcessBuilderFactoryTest extends AbstractProcessBuilderFactoryTest
|
||||
{
|
||||
protected function getProcessBuilderFactory($binary)
|
||||
{
|
||||
ProcessBuilderFactory::$emulateSfLTS = true;
|
||||
|
||||
return new ProcessBuilderFactory($binary);
|
||||
}
|
||||
}
|
||||
208
tests/Alchemy/BinaryDriver/ProcessRunnerTest.php
Normal file
208
tests/Alchemy/BinaryDriver/ProcessRunnerTest.php
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Alchemy\BinaryDriver.
|
||||
*
|
||||
* (c) Alchemy <info@alchemy.fr>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Tests\BinaryDriver;
|
||||
|
||||
use Alchemy\BinaryDriver\ProcessRunner;
|
||||
use Alchemy\BinaryDriver\BinaryDriverTestCase;
|
||||
use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
|
||||
use Alchemy\BinaryDriver\Listeners\ListenerInterface;
|
||||
use Evenement\EventEmitter;
|
||||
use Symfony\Component\Process\Exception\RuntimeException as ProcessRuntimeException;
|
||||
|
||||
class ProcessRunnerTest extends BinaryDriverTestCase
|
||||
{
|
||||
public function getProcessRunner($logger)
|
||||
{
|
||||
return new ProcessRunner($logger, 'test-runner');
|
||||
}
|
||||
|
||||
public function testRunSuccessFullProcess()
|
||||
{
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$process = $this->createProcessMock(1, true, '--helloworld--', "Kikoo Romain", null, true);
|
||||
|
||||
$logger
|
||||
->expects($this->never())
|
||||
->method('error');
|
||||
$logger
|
||||
->expects($this->exactly(2))
|
||||
->method('info');
|
||||
|
||||
$this->assertEquals('Kikoo Romain', $runner->run($process, new \SplObjectStorage(), false));
|
||||
}
|
||||
|
||||
public function testRunSuccessFullProcessBypassingErrors()
|
||||
{
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$process = $this->createProcessMock(1, true, '--helloworld--', "Kikoo Romain", null, true);
|
||||
|
||||
$logger
|
||||
->expects($this->never())
|
||||
->method('error');
|
||||
$logger
|
||||
->expects($this->exactly(2))
|
||||
->method('info');
|
||||
|
||||
$this->assertEquals('Kikoo Romain', $runner->run($process, new \SplObjectStorage(), true));
|
||||
}
|
||||
|
||||
public function testRunFailingProcess()
|
||||
{
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$process = $this->createProcessMock(1, false, '--helloworld--', null, null, true);
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error');
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('info');
|
||||
|
||||
try {
|
||||
$runner->run($process, new \SplObjectStorage(), false);
|
||||
$this->fail('An exception should have been raised');
|
||||
} catch (ExecutionFailureException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function testRunFailingProcessWithException()
|
||||
{
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$exception = new ProcessRuntimeException('Process Failed');
|
||||
$process = $this->getMockBuilder('Symfony\Component\Process\Process')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$process->expects($this->once())
|
||||
->method('run')
|
||||
->will($this->throwException($exception));
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error');
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('info');
|
||||
|
||||
try {
|
||||
$runner->run($process, new \SplObjectStorage(), false);
|
||||
$this->fail('An exception should have been raised');
|
||||
} catch (ExecutionFailureException $e) {
|
||||
$this->assertEquals($exception, $e->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
public function testRunfailingProcessBypassingErrors()
|
||||
{
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$process = $this->createProcessMock(1, false, '--helloworld--', 'Hello output', null, true);
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error');
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('info');
|
||||
|
||||
$this->assertNull($runner->run($process, new \SplObjectStorage(), true));
|
||||
}
|
||||
|
||||
public function testRunFailingProcessWithExceptionBypassingErrors()
|
||||
{
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$exception = new ProcessRuntimeException('Process Failed');
|
||||
$process = $this->getMockBuilder('Symfony\Component\Process\Process')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$process->expects($this->once())
|
||||
->method('run')
|
||||
->will($this->throwException($exception));
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error');
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('info');
|
||||
|
||||
$this->assertNull($runner->run($process, new \SplObjectStorage(), true));
|
||||
}
|
||||
|
||||
public function testRunSuccessFullProcessWithHandlers()
|
||||
{
|
||||
$logger = $this->createLoggerMock();
|
||||
$runner = $this->getProcessRunner($logger);
|
||||
|
||||
$capturedCallback = null;
|
||||
|
||||
$process = $this->createProcessMock(1, true, '--helloworld--', "Kikoo Romain", null, true);
|
||||
$process->expects($this->once())
|
||||
->method('run')
|
||||
->with($this->isInstanceOf('Closure'))
|
||||
->will($this->returnCallback(function ($callback) use (&$capturedCallback) {
|
||||
$capturedCallback = $callback;
|
||||
}));
|
||||
|
||||
$logger
|
||||
->expects($this->never())
|
||||
->method('error');
|
||||
$logger
|
||||
->expects($this->exactly(2))
|
||||
->method('info');
|
||||
|
||||
$listener = new TestListener();
|
||||
$storage = new \SplObjectStorage();
|
||||
$storage->attach($listener);
|
||||
|
||||
$capturedType = $capturedData = null;
|
||||
|
||||
$listener->on('received', function ($type, $data) use (&$capturedType, &$capturedData) {
|
||||
$capturedData = $data;
|
||||
$capturedType = $type;
|
||||
});
|
||||
|
||||
$this->assertEquals('Kikoo Romain', $runner->run($process, $storage, false));
|
||||
|
||||
$type = 'err';
|
||||
$data = 'data';
|
||||
|
||||
$capturedCallback($type, $data);
|
||||
|
||||
$this->assertEquals($data, $capturedData);
|
||||
$this->assertEquals($type, $capturedType);
|
||||
}
|
||||
}
|
||||
|
||||
class TestListener extends EventEmitter implements ListenerInterface
|
||||
{
|
||||
public function handle($type, $data)
|
||||
{
|
||||
return $this->emit('received', array($type, $data));
|
||||
}
|
||||
|
||||
public function forwardedEvents()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue