Refactoring

This commit is contained in:
gamonoid
2017-09-03 20:39:22 +02:00
parent af40881847
commit a7274d3cfd
5075 changed files with 238202 additions and 16291 deletions

View File

@@ -0,0 +1,140 @@
<?php
require_once codecept_data_dir() . 'TestedRoboFile.php';
use Robo\Robo;
use Robo\Runner;
use League\Container\Container;
use Consolidation\AnnotatedCommand\AnnotatedCommandFactory;
use Consolidation\AnnotatedCommand\Parser\CommandInfo;
class ApplicationTest extends \Codeception\TestCase\Test
{
/**
* @var \Robo\Runner
*/
private $runner;
/**
* @var \Robo\Application
*/
private $app;
/**
* @var Consolidation\AnnotatedCommand\AnnotatedCommandFactory
*/
private $commandFactory;
/**
* @var TestRoboFile
*/
private $roboCommandFileInstance;
protected function _before()
{
$container = Robo::createDefaultContainer();
$this->app = $container->get('application');
$config = $container->get('config');
$this->commandFactory = $container->get('commandFactory');
$this->roboCommandFileInstance = new TestedRoboFile;
$builder = $container->get('collectionBuilder', [$this->roboCommandFileInstance]);
$this->roboCommandFileInstance->setBuilder($builder);
$commandList = $this->commandFactory->createCommandsFromClass($this->roboCommandFileInstance);
foreach ($commandList as $command) {
$this->app->add($command);
}
}
public function testTaskAccessor()
{
// Get a reference to the protected 'task' method, as
// this is normally only callable by methods of the
// commandfile instance.
$method = new ReflectionMethod($this->roboCommandFileInstance, 'task');
$method->setAccessible(true);
$collectionBuilder = $method->invoke($this->roboCommandFileInstance, 'Robo\Task\Base\Exec', ['ls']);
verify(get_class($collectionBuilder))->equals('Robo\Collection\CollectionBuilder');
$task = $collectionBuilder->getCollectionBuilderCurrentTask();
verify(get_class($task))->equals('Robo\Task\Base\Exec');
verify(get_class($task))->equals('Robo\Task\Base\Exec');
}
public function testAllowEmptyValuesAsDefaultsToOptionalOptions()
{
$command = $this->createCommand('hello');
$yell = $command->getDefinition()->getOption('yell');
verify($yell->isValueOptional())
->equals(false);
verify($yell->getDefault())
->equals(false);
$to = $command->getDefinition()->getOption('to');
verify($to->isValueOptional())
->equals(true);
verify($to->getDefault())
->equals(null);
}
public function testCommandDocumentation()
{
$command = $this->createCommand('fibonacci');
verify($command->getDescription())
->equals('Calculate the fibonacci sequence between two numbers.');
}
public function testCommandCompactDocumentation()
{
$command = $this->createCommand('compact');
verify($command->getDescription())
->equals('Compact doc comment');
}
public function testCommandArgumentDocumentation()
{
$command = $this->createCommand('fibonacci');
$start = $command->getDefinition()->getArgument('start');
verify($start->getDescription())
->equals('Number to start from');
$steps = $command->getDefinition()->getArgument('steps');
verify($steps->getDescription())
->equals('Number of steps to perform');
}
public function testCommandOptionDocumentation()
{
$command = $this->createCommand('fibonacci');
$graphic = $command->getDefinition()->getOption('graphic');
verify($graphic->getDescription())
->equals('Display the sequence graphically using cube representation');
}
public function testCommandHelpDocumentation()
{
$command = $this->createCommand('fibonacci');
verify($command->getHelp())
->contains('+----+---+');
}
public function testCommandNaming()
{
$this->assertNotNull($this->app->find('generate:user-avatar'));
}
protected function createCommand($name)
{
$commandInfo = new CommandInfo($this->roboCommandFileInstance, $name);
return $this->commandFactory->createCommand($commandInfo, $this->roboCommandFileInstance);
}
}

View File

@@ -0,0 +1,86 @@
<?php
use Robo\Traits\Common\CommandArgumentsHost;
/**
* Class CommandArgumentsTest.
*
* @coversDefaultClass \Robo\Common\CommandArguments
*/
class CommandArgumentsTest extends \Codeception\Test\Unit
{
/**
* @var \CodeGuy
*/
protected $guy;
public function casesArgs() {
return [
'no arguments' => [
' ',
[],
],
'empty string' => [
" ''",
[''],
],
'space' => [
" ' '",
[' '],
],
'no escape - a' => [
" a",
['a'],
],
'no escape - A' => [
" A",
['A'],
],
'no escape - 0' => [
" 0",
['0'],
],
'no escape - --' => [
" --",
['--'],
],
'no escape - @_~.' => [
" @_~.",
['@_~.'],
],
'$' => [
" 'a\$b'",
['a$b'],
],
'*' => [
" 'a*b'",
['a*b'],
],
'multi' => [
" '' a '\$PATH'",
['', 'a', '$PATH'],
],
];
}
/**
* @dataProvider casesArgs
*
* @covers ::args
*
* @param string $expected
* @param array $args
*/
public function testArgs($expected, $args)
{
$commandArguments = new CommandArgumentsHost();
$commandArguments->args($args);
$this->guy->assertEquals($expected, $commandArguments->getArguments());
if ($args) {
$commandArguments = new CommandArgumentsHost();
call_user_func_array([$commandArguments, 'args'], $args);
$this->guy->assertEquals($expected, $commandArguments->getArguments());
}
}
}

View File

@@ -0,0 +1,80 @@
<?php
use Robo\Common\ResourceExistenceChecker;
use Robo\Result;
use Robo\Task\BaseTask;
class ResourceExistenceCheckerTest extends \Codeception\TestCase\Test
{
use ResourceExistenceChecker;
protected $testDir = null;
protected $testFile = null;
protected function _before()
{
$this->apigen = test::double('Robo\Task\ApiGen\ApiGen', [
'executeCommand' => null,
'output' => new \Symfony\Component\Console\Output\NullOutput()
]);
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
$this->testDir = __DIR__ . '..' . DS . '..' . DS . 'data' . DS;
$this->testFile = $this->testDir . 'dump.sql';
}
/**
* testCheckResources
*/
public function testCheckResources()
{
$this->assertTrue($this->checkResources($this->testDir, 'dir'));
$this->assertTrue($this->checkResources([
$this->testDir,
$this->testFile
]));
}
/**
* @expectException \InvalidArgumentException
*/
public function testCheckResourcesException()
{
$this->checkResources('does not exist', 'invalid type');
}
/**
* testCheckResource
*/
public function testCheckResource()
{
$this->assertTrue($this->checkResource($this->testDir, 'dir'));
$this->assertTrue($this->checkResource($this->testDir, 'fileAndDir'));
$this->assertTrue($this->checkResource($this->testFile, 'file'));
$this->assertTrue($this->checkResource($this->testFile, 'fileAndDir'));
$this->assertFalse($this->checkResource('does-not-exist', 'dir'));
$this->assertFalse($this->checkResource('does-not-exist', 'fileAndDir'));
$this->assertFalse($this->checkResource('does-not-exist', 'file'));
$this->assertFalse($this->checkResource('does-not-exist', 'fileAndDir'));
}
/**
* testIsDir
*/
public function testIsDir()
{
$this->assertTrue($this->isDir($this->testDir));
$this->assertFalse($this->isDir('does-not-exist'));
}
/**
* testIsFile
*/
public function testIsFile()
{
$this->assertTrue($this->isFile($this->testFile));
$this->assertFalse($this->isFile($this->testDir . 'does-not-exist'));
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace unit;
use Robo\Robo;
use Robo\Task\BaseTask;
class ConfigurationTest extends \Codeception\TestCase\Test
{
public function testDifferentTasksCanHaveSameConfigKeys()
{
ConfigurationTestTaskA::configure('key', 'value-a');
ConfigurationTestTaskB::configure('key', 'value-b');
$taskA = new ConfigurationTestTaskA();
$taskA->setConfig(Robo::config());
verify($taskA->run())->equals('value-a');
$taskB = new ConfigurationTestTaskB();
$taskB->setConfig(Robo::config());
verify($taskB->run())->equals('value-b');
}
}
class ConfigurationTestTaskA extends BaseTask
{
public function run()
{
return $this->getConfigValue('key');
}
}
class ConfigurationTestTaskB extends BaseTask
{
public function run()
{
return $this->getConfigValue('key');
}
}

View File

@@ -0,0 +1,81 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
use Robo\Common\IO;
class OutputTest extends \Codeception\TestCase\Test
{
use \Robo\Common\IO {
say as public;
yell as public;
ask as public;
output as protected;
}
protected $expectedAnswer;
/**
* @var \CodeGuy
*/
protected $guy;
/**
* @vAspectMock\Proxy\ClassProxyroxy
*/
protected $dialog;
protected function _before()
{
$this->dialog = new Symfony\Component\Console\Helper\QuestionHelper;
$this->setOutput(Robo::service('output'));
}
public function testSay()
{
$this->say('Hello, world!');
$this->guy->seeInOutput('> Hello, world!');
}
public function testAskReply()
{
$this->expectedAnswer = 'jon';
verify($this->ask('What is your name?'))->equals('jon');
$this->guy->seeOutputEquals('? What is your name? ');
}
public function testAskMethod()
{
if (method_exists($this, 'createMock')) {
$this->dialog = $this->createMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']);
} else {
$this->dialog = $this->getMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']);
}
$this->dialog->expects($this->once())
->method('ask');
$this->ask('What is your name?');
}
public function testAskHiddenMethod()
{
if (method_exists($this, 'createMock')) {
$this->dialog = $this->createMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']);
} else {
$this->dialog = $this->getMock('\Symfony\Component\Console\Helper\QuestionHelper', ['ask']);
}
$this->dialog->expects($this->once())
->method('ask');
$this->ask('What is your name?', true);
}
public function testYell()
{
$this->yell('Buuuu!');
$this->guy->seeInOutput('Buuuu!');
}
protected function getDialog()
{
$stream = fopen('php://memory', 'r+', false);
fputs($stream, $this->expectedAnswer);
rewind($stream);
$this->dialog->setInputStream($stream);
return $this->dialog;
}
}

View File

@@ -0,0 +1,79 @@
<?php
use Robo\Result;
use Robo\Exception\TaskExitException;
class ResultTest extends \Codeception\TestCase\Test {
/**
* @var \CodeGuy
*/
protected $guy;
public function testBasics()
{
$task = new ResultDummyTask();
$result = new Result($task, 1, 'The foo barred', ['time' => 10]);
$this->guy->seeInOutput('The foo barred');
$this->guy->seeInOutput('Exit code 1');
$this->guy->seeInOutput('10s');
$this->guy->seeInOutput('[ResultDummyTask]');
$this->assertSame($task, $result->getTask());
$this->assertEquals(1, $result->getExitCode());
$this->assertEquals('The foo barred', $result->getMessage());
$data = $result->getData();
$this->assertEquals(10, $data['time']);
$taskClone = $result->cloneTask();
$this->assertNotSame($task, $taskClone);
$this->assertInstanceOf('Robo\Contract\TaskInterface', $taskClone);
}
public function testArrayAccess()
{
$task = new ResultDummyTask();
$result = new Result($task, 1, 'The foo barred', ['time' => 10]);
$this->assertEquals($result['time'], 10);
}
public function testStopOnFail()
{
$exceptionClass = false;
$task = new ResultDummyTask();
Result::$stopOnFail = true;
$result = Result::success($task, "Something that worked");
try {
$result = Result::error($task, "Something that did not work");
// stopOnFail will cause Result::error() to throw an exception,
// so we will never get here. If we did, the assert below would fail.
$this->assertTrue($result->wasSuccessful());
$this->assertTrue(false);
} catch (\Exception $e) {
$exceptionClass = get_class($e);
}
$this->assertEquals(TaskExitException::class, $exceptionClass);
$this->assertTrue($result->wasSuccessful());
/*
// This gives an error:
// Exception of class Robo\Exception\TaskExitException expected to
// be thrown, but PHPUnit_Framework_Exception caught
// This happens whether or not the expected exception is thrown
$this->guy->expectException(TaskExitException::class, function() {
// $result = Result::error($task, "Something that did not work");
$result = Result::success($task, "Something that worked");
});
*/
Result::$stopOnFail = false;
}
}
class ResultDummyTask implements \Robo\Contract\TaskInterface
{
public function run()
{
}
}

View File

@@ -0,0 +1,279 @@
<?php
use Robo\Robo;
use Symfony\Component\Console\Output\BufferedOutput;
class RunnerTest extends \Codeception\TestCase\Test
{
/**
* @var \Robo\Runner
*/
private $runner;
/**
* @var \CodeGuy
*/
protected $guy;
public function _before()
{
$this->runner = new \Robo\Runner('\Robo\RoboFileFixture');
}
public function testHandleError()
{
$tmpLevel = error_reporting();
$this->assertFalse($this->runner->handleError());
error_reporting(0);
$this->assertTrue($this->runner->handleError());
error_reporting($tmpLevel);
}
public function testErrorIsHandled()
{
$tmpLevel = error_reporting();
// Set error_get_last to a known state. Note that it can never be
// reset; see http://php.net/manual/en/function.error-get-last.php
@trigger_error('control');
$error_description = error_get_last();
$this->assertEquals('control', $error_description['message']);
@trigger_error('');
$error_description = error_get_last();
$this->assertEquals('', $error_description['message']);
// Set error_reporting to a non-zero value. In this instance,
// 'trigger_error' would abort our test script, so we use
// @trigger_error so that execution will continue. With our
// error handler in place, the value of error_get_last() does
// not change.
error_reporting(E_USER_ERROR);
set_error_handler(array($this->runner, 'handleError'));
@trigger_error('test error', E_USER_ERROR);
$error_description = error_get_last();
$this->assertEquals('', $error_description['message']);
// Set error_reporting to zero. Now, even 'trigger_error'
// does not abort execution. The value of error_get_last()
// still does not change.
error_reporting(0);
trigger_error('test error 2', E_USER_ERROR);
$error_description = error_get_last();
$this->assertEquals('', $error_description['message']);
error_reporting($tmpLevel);
}
public function testThrowsExceptionWhenNoContainerAvailable()
{
\PHPUnit_Framework_TestCase::setExpectedExceptionRegExp(
'\RuntimeException',
'/container is not initialized yet.*/'
);
Robo::unsetContainer();
Robo::getContainer();
}
public function testRunnerNoSuchCommand()
{
$argv = ['placeholder', 'no-such-command'];
$this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('Command "no-such-command" is not defined.');
}
public function testRunnerList()
{
$argv = ['placeholder', 'list'];
$this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('test:array-args');
}
public function testRunnerTryArgs()
{
$argv = ['placeholder', 'test:array-args', 'a', 'b', 'c'];
$this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$expected = <<<EOT
> The parameters passed are:
array (
0 => 'a',
1 => 'b',
2 => 'c',
)
EOT;
$this->guy->seeOutputEquals($expected);
}
public function testSymfonyStyle()
{
$argv = ['placeholder', 'test:symfony-style'];
$this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('Some text in section one.');
}
public function testCommandEventHook()
{
$argv = ['placeholder', 'test:command-event'];
$this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$expected = <<<EOT
This is the command-event hook for the test:command-event command.
This is the main method for the test:command-event command.
This is the post-command hook for the test:command-event command.
EOT;
$this->guy->seeInOutput($expected);
}
public function testRoboStaticRunMethod()
{
$argv = ['placeholder', 'test:symfony-style'];
$commandFiles = ['\Robo\RoboFileFixture'];
Robo::run($argv, $commandFiles, 'MyApp', '1.2.3', $this->guy->capturedOutputStream());
$this->guy->seeInOutput('Some text in section one.');
}
public function testDeploy()
{
$argv = ['placeholder', 'test:deploy', '--simulate'];
$this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('[Simulator] Simulating Remote\\Ssh(\'mysite.com\', null)');
$this->guy->seeInOutput('[Simulator] Running ssh mysite.com \'cd "/var/www/somesite" && git pull\'');
}
public function testRunnerTryError()
{
$argv = ['placeholder', 'test:error'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('[Exec] Running ls xyzzy');
$this->assertTrue($result > 0);
}
public function testRunnerTrySimulatedError()
{
$argv = ['placeholder', 'test:error', '--simulate'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('Simulating Exec');
$this->assertEquals(0, $result);
}
public function testRunnerTryException()
{
$argv = ['placeholder', 'test:exception', '--task'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('Task failed with an exception');
$this->assertEquals(1, $result);
}
public function testInitCommand()
{
$container = \Robo\Robo::getContainer();
$app = $container->get('application');
$app->addInitRoboFileCommand(getcwd() . '/testRoboFile.php', 'RoboTestClass');
$argv = ['placeholder', 'init'];
$status = $this->runner->run($argv, $this->guy->capturedOutputStream(), $app);
$this->guy->seeInOutput('testRoboFile.php will be created in the current directory');
$this->assertEquals(0, $status);
$this->assertTrue(file_exists('testRoboFile.php'));
$commandContents = file_get_contents('testRoboFile.php');
unlink('testRoboFile.php');
$this->assertContains('class RoboTestClass', $commandContents);
}
public function testTasksStopOnFail()
{
$argv = ['placeholder', 'test:stop-on-fail'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('[');
$this->assertTrue($result > 0);
}
public function testInvalidRoboDirectory()
{
$runnerWithNoRoboFile = new \Robo\Runner();
$argv = ['placeholder', 'list', '-f', 'no-such-directory'];
$result = $runnerWithNoRoboFile->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('Path `no-such-directory` is invalid; please provide a valid absolute path to the Robofile to load.');
}
public function testUnloadableRoboFile()
{
$runnerWithNoRoboFile = new \Robo\Runner();
$argv = ['placeholder', 'list', '-f', dirname(__DIR__) . '/src/RoboFileFixture.php'];
$result = $runnerWithNoRoboFile->execute($argv, null, null, $this->guy->capturedOutputStream());
// We cannot load RoboFileFixture.php via -f / --load-from because
// it has a namespace, and --load-from does not support that.
$this->guy->seeInOutput('Class RoboFileFixture was not loaded');
}
public function testRunnerQuietOutput()
{
$argv = ['placeholder', 'test:verbosity', '--quiet'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->doNotSeeInOutput('This command will print more information at higher verbosity levels');
$this->guy->doNotSeeInOutput('This is a verbose message (-v).');
$this->guy->doNotSeeInOutput('This is a very verbose message (-vv).');
$this->guy->doNotSeeInOutput('This is a debug message (-vvv).');
$this->guy->doNotSeeInOutput(' [warning] This is a warning log message.');
$this->guy->doNotSeeInOutput(' [notice] This is a notice log message.');
$this->guy->doNotSeeInOutput(' [debug] This is a debug log message.');
$this->assertEquals(0, $result);
}
public function testRunnerVerboseOutput()
{
$argv = ['placeholder', 'test:verbosity', '-v'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('This command will print more information at higher verbosity levels');
$this->guy->seeInOutput('This is a verbose message (-v).');
$this->guy->doNotSeeInOutput('This is a very verbose message (-vv).');
$this->guy->doNotSeeInOutput('This is a debug message (-vvv).');
$this->guy->seeInOutput(' [warning] This is a warning log message.');
$this->guy->seeInOutput(' [notice] This is a notice log message.');
$this->guy->doNotSeeInOutput(' [debug] This is a debug log message.');
$this->assertEquals(0, $result);
}
public function testRunnerVeryVerboseOutput()
{
$argv = ['placeholder', 'test:verbosity', '-vv'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('This command will print more information at higher verbosity levels');
$this->guy->seeInOutput('This is a verbose message (-v).');
$this->guy->seeInOutput('This is a very verbose message (-vv).');
$this->guy->doNotSeeInOutput('This is a debug message (-vvv).');
$this->guy->seeInOutput(' [warning] This is a warning log message.');
$this->guy->seeInOutput(' [notice] This is a notice log message.');
$this->guy->doNotSeeInOutput(' [debug] This is a debug log message.');
$this->assertEquals(0, $result);
}
public function testRunnerDebugOutput()
{
$argv = ['placeholder', 'test:verbosity', '-vvv'];
$result = $this->runner->execute($argv, null, null, $this->guy->capturedOutputStream());
$this->guy->seeInOutput('This command will print more information at higher verbosity levels');
$this->guy->seeInOutput('This is a verbose message (-v).');
$this->guy->seeInOutput('This is a very verbose message (-vv).');
$this->guy->seeInOutput('This is a debug message (-vvv).');
$this->guy->seeInOutput(' [warning] This is a warning log message.');
$this->guy->seeInOutput(' [notice] This is a notice log message.');
$this->guy->seeInOutput(' [debug] This is a debug log message.');
$this->assertEquals(0, $result);
}
}

View File

@@ -0,0 +1,52 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class ApiGenTest extends \Codeception\TestCase\Test
{
protected $container;
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $apigen;
protected function _before()
{
$this->apigen = test::double('Robo\Task\ApiGen\ApiGen', [
'executeCommand' => null,
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
$this->container = Robo::getContainer();
}
// tests
public function testPHPUnitCommand()
{
// need an explicit Traversable
$skippedPaths = new \SplDoublyLinkedList();
$skippedPaths->push('a');
$skippedPaths->push('b');
// going for 'bang for the buck' here re: test converage
$task = (new \Robo\Task\ApiGen\ApiGen('apigen'))
->config('./apigen.neon')
->source('src') // single string value of Traversable
->extensions('php') // single string value of List
->exclude(array('test', 'tmp')) // array value of Traversable
->skipDocPath($skippedPaths) // multi-value of Traversable
->charset(array('utf8','iso88591')) // array of List
->internal('no') // boolean as supported "no"
->php(true) // boolean as boolean
->tree('Y') // boolean as string
->debug('n');
$cmd = 'apigen --config ./apigen.neon --source src --extensions php --exclude test --exclude tmp --skip-doc-path a --skip-doc-path b --charset \'utf8,iso88591\' --internal no --php yes --tree yes --debug no';
verify($task->getCommand())->equals($cmd);
$task->run();
$this->apigen->verifyInvoked('executeCommand', [$cmd]);
}
}

View File

@@ -0,0 +1,38 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class AtoumTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $atoum;
protected function _before()
{
$this->atoum = test::double('Robo\Task\Testing\Atoum', [
'executeCommand' => null,
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
public function testAtoumCommand()
{
$task = (new \Robo\Task\Testing\Atoum('atoum'))
->bootstrap('bootstrap.php')
->tags("needDb")
->lightReport()
->tap()
->bootstrap('tests/bootstrap.php')
->configFile("config/dev.php")
->debug()
->files(array("path/to/file1.php", "path/to/file2.php"))
->directories("tests/units")
;
verify($task->getCommand())->equals('atoum --bootstrap bootstrap.php --tags needDb --use-light-report --use-tap-report --bootstrap tests/bootstrap.php -c config/dev.php --debug --f path/to/file1.php --f path/to/file2.php --directories tests/units');
$task->run();
$this->atoum->verifyInvoked('executeCommand', ['atoum --bootstrap bootstrap.php --tags needDb --use-light-report --use-tap-report --bootstrap tests/bootstrap.php -c config/dev.php --debug --f path/to/file1.php --f path/to/file2.php --directories tests/units']);
}
}

View File

@@ -0,0 +1,43 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class BehatTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $behat;
protected function _before()
{
$this->behat = test::double('Robo\Task\Testing\Behat', [
'executeCommand' => null,
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testBehatRun()
{
$behat = test::double('Robo\Task\Testing\Behat', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Testing\Behat('behat'))->run();
$behat->verifyInvoked('executeCommand');
}
public function testBehatCommand()
{
$behat = test::double('Robo\Task\Testing\Behat', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
$task = (new \Robo\Task\Testing\Behat('behat'))
->stopOnFail()
->noInteraction()
->colors();
verify($task->getCommand())->equals('behat run --stop-on-failure --no-interaction --colors');
$task->run();
$behat->verifyInvoked('executeCommand', ['behat run --stop-on-failure --no-interaction --colors']);
}
}

View File

@@ -0,0 +1,59 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class BowerTest extends \Codeception\TestCase\Test
{
protected $container;
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $baseBower;
protected function _before()
{
$this->baseBower = test::double('Robo\Task\Bower\Base', [
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testBowerInstall()
{
$bower = test::double('Robo\Task\Bower\Install', ['executeCommand' => null, 'logger' => new \Psr\Log\NullLogger(),]);
(new \Robo\Task\Bower\Install('bower'))->run();
$bower->verifyInvoked('executeCommand', ['bower install']);
}
public function testBowerUpdate()
{
$bower = test::double('Robo\Task\Bower\Update', ['executeCommand' => null]);
$task = new \Robo\Task\Bower\Update('bower');
$task->setLogger(new \Psr\Log\NullLogger());
$task->run();
$bower->verifyInvoked('executeCommand', ['bower update']);
}
public function testBowerInstallCommand()
{
verify(
(new \Robo\Task\Bower\Install('bower'))->getCommand()
)->equals('bower install');
verify(
(new \Robo\Task\Bower\Update('bower'))->getCommand()
)->equals('bower update');
verify(
(new \Robo\Task\Bower\Install('bower'))
->allowRoot()
->forceLatest()
->offline()
->noDev()
->getCommand()
)->equals('bower install --allow-root --force-latest --offline --production');
}
}

View File

@@ -0,0 +1,63 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class CodeceptionTest extends \Codeception\TestCase\Test
{
protected $container;
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $codecept;
protected function _before()
{
$this->codecept = test::double('Robo\Task\Testing\Codecept', [
'executeCommand' => null,
'output' => new \Symfony\Component\Console\Output\NullOutput()
]);
}
// tests
public function testCodeceptionCommand()
{
verify(trim((new \Robo\Task\Testing\Codecept('codecept.phar'))->getCommand()))->equals('codecept.phar run');
}
public function testCodeceptionRun()
{
$task = new \Robo\Task\Testing\Codecept('codecept.phar');
$task->setLogger(new \Psr\Log\NullLogger());
$task->run();
$this->codecept->verifyInvoked('executeCommand');
}
public function testCodeceptOptions()
{
verify((new \Robo\Task\Testing\Codecept('codecept'))
->suite('unit')
->test('Codeception/Command')
->group('core')
->env('process1')
->coverage()
->getCommand()
)->equals('codecept run --group core --env process1 --coverage unit Codeception/Command');
verify((new \Robo\Task\Testing\Codecept('codecept'))
->test('tests/unit/Codeception')
->configFile('~/Codeception')
->xml('result.xml')
->html()
->getCommand()
)->equals('codecept run -c ~/Codeception --xml result.xml --html tests/unit/Codeception');
verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->debug()->getCommand())->contains(' --debug');
verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->silent()->getCommand())->contains(' --silent');
verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->excludeGroup('g')->getCommand())->contains(' --skip-group g');
verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->tap()->getCommand())->contains('--tap');
verify((new \Robo\Task\Testing\Codecept('codecept.phar'))->json()->getCommand())->contains('--json');
}
}

View File

@@ -0,0 +1,183 @@
<?php
namespace unit;
// @codingStandardsIgnoreFile
// We do not want NitPick CI to report results about this file,
// as we have a couple of private test classes that appear in this file
// rather than in their own file.
use Robo\Result;
use Robo\Task\BaseTask;
use Robo\Contract\TaskInterface;
use Robo\Collection\Collection;
use Robo\Robo;
class CollectionTest extends \Codeception\TestCase\Test
{
/**
* @var \CodeGuy
*/
protected $guy;
public function testAfterFilters()
{
$collection = new Collection();
$taskA = new CollectionTestTask('a', 'value-a');
$taskB = new CollectionTestTask('b', 'value-b');
$collection
->add($taskA, 'a-name')
->add($taskB, 'b-name');
// We add methods of our task instances as before and
// after tasks. These methods have access to the task
// class' fields, and may modify them as needed.
$collection
->after('a-name', [$taskA, 'parenthesizer'])
->after('a-name', [$taskA, 'emphasizer'])
->after('b-name', [$taskB, 'emphasizer'])
->after('b-name', [$taskB, 'parenthesizer'])
->after('b-name', [$taskB, 'parenthesizer'], 'special-name');
$result = $collection->run();
// verify(var_export($result->getData(), true))->equals('');
// Ensure that the results have the correct key values
verify(implode(',', array_keys($result->getData())))->equals('a-name,b-name,special-name,time');
// Verify that all of the after tasks ran in
// the correct order.
verify($result['a-name']['a'])->equals('*(value-a)*');
verify($result['b-name']['b'])->equals('(*value-b*)');
// Note that the last after task is added with a special name;
// its results therefore show up under the name given, rather
// than being stored under the name of the task it was added after.
verify($result['special-name']['b'])->equals('((*value-b*))');
}
public function testBeforeFilters()
{
$collection = new Collection();
$taskA = new CollectionTestTask('a', 'value-a');
$taskB = new CollectionTestTask('b', 'value-b');
$collection
->add($taskA, 'a-name')
->add($taskB, 'b-name');
// We add methods of our task instances as before and
// after tasks. These methods have access to the task
// class' fields, and may modify them as needed.
$collection
->before('b-name', [$taskA, 'parenthesizer'])
->before('b-name', [$taskA, 'emphasizer'], 'special-before-name');
$result = $collection->run();
// Ensure that the results have the correct key values
verify(implode(',', array_keys($result->getData())))->equals('a-name,b-name,special-before-name,time');
// The result from the 'before' task is attached
// to 'b-name', since it was called as before('b-name', ...)
verify($result['b-name']['a'])->equals('(value-a)');
// When a 'before' task is given its own name, then
// its results are attached under that name.
verify($result['special-before-name']['a'])->equals('*(value-a)*');
}
public function testAddCodeRollbackAndCompletion()
{
$collection = new Collection();
$rollback1 = new CountingTask();
$rollback2 = new CountingTask();
$completion1 = new CountingTask();
$completion2 = new CountingTask();
$collection
->progressMessage("start collection tasks")
->rollback($rollback1)
->completion($completion1)
->rollbackCode(function() use($rollback1) { $rollback1->run(); } )
->completionCode(function() use($completion1) { $completion1->run(); } )
->addCode(function () { return 42; })
->progressMessage("not reached")
->rollback($rollback2)
->completion($completion2)
->addCode(function () { return 13; });
$collection->setLogger($this->guy->logger());
$result = $collection->run();
// Execution stops on the first error.
// Confirm that status code is converted to a Result object.
verify($result->getExitCode())->equals(42);
verify($rollback1->getCount())->equals(2);
verify($rollback2->getCount())->equals(0);
verify($completion1->getCount())->equals(2);
verify($completion2->getCount())->equals(0);
$this->guy->seeInOutput('start collection tasks');
$this->guy->doNotSeeInOutput('not reached');
}
}
class CountingTask extends BaseTask
{
protected $count = 0;
public function run()
{
$this->count++;
return Result::success($this);
}
public function getCount()
{
return $this->count;
}
}
class CollectionTestTask extends BaseTask
{
protected $key;
protected $value;
public function __construct($key, $value)
{
$this->key = $key;
$this->value = $value;
}
public function run()
{
return $this->getValue();
}
protected function getValue()
{
$result = Result::success($this);
$result[$this->key] = $this->value;
return $result;
}
// Note that by returning a value with the same
// key as the result, we overwrite the value generated
// by the primary task method ('run()'). If we returned
// a result with a different key, then both values
// would appear in the result.
public function parenthesizer()
{
$this->value = "({$this->value})";
return $this->getValue();
}
public function emphasizer()
{
$this->value = "*{$this->value}*";
return $this->getValue();
}
}

View File

@@ -0,0 +1,26 @@
<?php
use Codeception\Util\Stub;
use Robo\Robo;
class CommandStackTest extends \Codeception\TestCase\Test
{
public function testExecStackExecutableIsTrimmedFromCommand()
{
$commandStack = Stub::make('Robo\Task\CommandStack');
verify($commandStack
->executable('some-executable')
->exec('some-executable status')
->getCommand()
)->equals('some-executable status');
}
public function testExecStackCommandIsNotTrimmedIfHavingSameCharsAsExecutable()
{
$commandStack = Stub::make('Robo\Task\CommandStack');
verify($commandStack
->executable('some-executable')
->exec('status')
->getCommand()
)->equals('some-executable status');
}
}

View File

@@ -0,0 +1,266 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class ComposerTest extends \Codeception\TestCase\Test
{
protected $container;
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $baseComposer;
protected function _before()
{
$this->baseComposer = test::double('Robo\Task\Composer\Base', [
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testComposerInstall()
{
$composer = test::double('Robo\Task\Composer\Install', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Composer\Install('composer'))->run();
$composer->verifyInvoked('executeCommand', ['composer install']);
(new \Robo\Task\Composer\Install('composer'))
->preferSource()
->run();
$composer->verifyInvoked('executeCommand', ['composer install --prefer-source']);
(new \Robo\Task\Composer\Install('composer'))
->optimizeAutoloader()
->run();
$composer->verifyInvoked('executeCommand', ['composer install --optimize-autoloader']);
}
public function testComposerInstallAnsi()
{
$config = new \Robo\Config();
$config->setDecorated(true);
$composer = test::double('Robo\Task\Composer\Install', ['executeCommand' => null, 'getConfig' => $config, 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Composer\Install('composer'))->run();
$composer->verifyInvoked('executeCommand', ['composer install --ansi']);
(new \Robo\Task\Composer\Install('composer'))
->preferSource()
->run();
$composer->verifyInvoked('executeCommand', ['composer install --prefer-source --ansi']);
(new \Robo\Task\Composer\Install('composer'))
->optimizeAutoloader()
->run();
$composer->verifyInvoked('executeCommand', ['composer install --optimize-autoloader --ansi']);
}
public function testComposerUpdate()
{
$composer = test::double('Robo\Task\Composer\Update', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Composer\Update('composer'))->run();
$composer->verifyInvoked('executeCommand', ['composer update']);
(new \Robo\Task\Composer\Update('composer'))
->optimizeAutoloader()
->run();
$composer->verifyInvoked('executeCommand', ['composer update --optimize-autoloader']);
}
public function testComposerDumpAutoload()
{
$composer = test::double('Robo\Task\Composer\DumpAutoload', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Composer\DumpAutoload('composer'))->run();
$composer->verifyInvoked('executeCommand', ['composer dump-autoload']);
(new \Robo\Task\Composer\DumpAutoload('composer'))
->noDev()
->run();
$composer->verifyInvoked('executeCommand', ['composer dump-autoload --no-dev']);
(new \Robo\Task\Composer\DumpAutoload('composer'))
->optimize()
->run();
$composer->verifyInvoked('executeCommand', ['composer dump-autoload --optimize']);
(new \Robo\Task\Composer\DumpAutoload('composer'))
->optimize()
->noDev()
->run();
$composer->verifyInvoked('executeCommand', ['composer dump-autoload --optimize --no-dev']);
}
public function testComposerValidate()
{
$composer = test::double('Robo\Task\Composer\Validate', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Composer\Validate('composer'))->run();
$composer->verifyInvoked('executeCommand', ['composer validate']);
(new \Robo\Task\Composer\Validate('composer'))
->noCheckAll()
->run();
$composer->verifyInvoked('executeCommand', ['composer validate --no-check-all']);
(new \Robo\Task\Composer\Validate('composer'))
->noCheckLock()
->run();
$composer->verifyInvoked('executeCommand', ['composer validate --no-check-lock']);
(new \Robo\Task\Composer\Validate('composer'))
->noCheckPublish()
->run();
$composer->verifyInvoked('executeCommand', ['composer validate --no-check-publish']);
(new \Robo\Task\Composer\Validate('composer'))
->withDependencies()
->run();
$composer->verifyInvoked('executeCommand', ['composer validate --with-dependencies']);
(new \Robo\Task\Composer\Validate('composer'))
->strict()
->run();
$composer->verifyInvoked('executeCommand', ['composer validate --strict']);
}
public function testComposerInstallCommand()
{
verify(
(new \Robo\Task\Composer\Install('composer'))->setConfig(new \Robo\Config())->getCommand()
)->equals('composer install');
verify(
(new \Robo\Task\Composer\Install('composer'))
->setConfig(new \Robo\Config())
->noDev()
->preferDist()
->optimizeAutoloader()
->getCommand()
)->equals('composer install --prefer-dist --no-dev --optimize-autoloader');
}
public function testComposerUpdateCommand()
{
verify(
(new \Robo\Task\Composer\Update('composer'))->setConfig(new \Robo\Config())->getCommand()
)->equals('composer update');
verify(
(new \Robo\Task\Composer\Update('composer'))
->setConfig(new \Robo\Config())
->noDev()
->preferDist()
->getCommand()
)->equals('composer update --prefer-dist --no-dev');
verify(
(new \Robo\Task\Composer\Update('composer'))
->setConfig(new \Robo\Config())
->noDev()
->preferDist()
->optimizeAutoloader()
->getCommand()
)->equals('composer update --prefer-dist --no-dev --optimize-autoloader');
}
public function testComposerDumpAutoloadCommand()
{
verify(
(new \Robo\Task\Composer\DumpAutoload('composer'))->setConfig(new \Robo\Config())->getCommand()
)->equals('composer dump-autoload');
verify(
(new \Robo\Task\Composer\DumpAutoload('composer'))
->setConfig(new \Robo\Config())
->noDev()
->getCommand()
)->equals('composer dump-autoload --no-dev');
verify(
(new \Robo\Task\Composer\DumpAutoload('composer'))
->setConfig(new \Robo\Config())
->optimize()
->getCommand()
)->equals('composer dump-autoload --optimize');
verify(
(new \Robo\Task\Composer\DumpAutoload('composer'))
->setConfig(new \Robo\Config())
->optimize()
->noDev()
->getCommand()
)->equals('composer dump-autoload --optimize --no-dev');
}
public function testComposerRemove()
{
verify(
(new \Robo\Task\Composer\Remove('composer'))->setConfig(new \Robo\Config())->getCommand()
)->equals('composer remove');
verify(
(new \Robo\Task\Composer\Remove('composer'))
->setConfig(new \Robo\Config())
->dev()
->noProgress()
->noUpdate()
->getCommand()
)->equals('composer remove --dev --no-progress --no-update');
}
public function testComposerValidateCommand()
{
verify(
(new \Robo\Task\Composer\Validate('composer'))->setConfig(new \Robo\Config())->getCommand()
)->equals('composer validate');
verify(
(new \Robo\Task\Composer\Validate('composer'))
->setConfig(new \Robo\Config())
->noCheckAll()
->getCommand()
)->equals('composer validate --no-check-all');
verify(
(new \Robo\Task\Composer\Validate('composer'))
->setConfig(new \Robo\Config())
->noCheckLock()
->getCommand()
)->equals('composer validate --no-check-lock');
verify(
(new \Robo\Task\Composer\Validate('composer'))
->setConfig(new \Robo\Config())
->noCheckPublish()
->getCommand()
)->equals('composer validate --no-check-publish');
verify(
(new \Robo\Task\Composer\Validate('composer'))
->setConfig(new \Robo\Config())
->withDependencies()
->getCommand()
)->equals('composer validate --with-dependencies');
verify(
(new \Robo\Task\Composer\Validate('composer'))
->setConfig(new \Robo\Config())
->strict()
->getCommand()
)->equals('composer validate --strict');
verify(
(new \Robo\Task\Composer\Validate('composer'))
->setConfig(new \Robo\Config())
->noCheckAll()
->noCheckLock()
->noCheckPublish()
->withDependencies()
->strict()
->getCommand()
)->equals('composer validate --no-check-all --no-check-lock --no-check-publish --with-dependencies --strict');
}
}

View File

@@ -0,0 +1,97 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class DockerTest extends \Codeception\TestCase\Test
{
protected $container;
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $baseDocker;
protected function _before()
{
$this->baseDocker = test::double('Robo\Task\Docker\Base', [
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testDockerBuild()
{
$docker = test::double('Robo\Task\Docker\Build', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Docker\Build())->run();
$docker->verifyInvoked('executeCommand', ['docker build .']);
(new \Robo\Task\Docker\Build())->tag('something')->run();
$docker->verifyInvoked('executeCommand', ['docker build -t something .']);
}
public function testDockerCommit()
{
$docker = test::double('Robo\Task\Docker\Commit', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Docker\Commit('cid'))->run();
$docker->verifyInvoked('executeCommand', ['docker commit cid ']);
(new \Robo\Task\Docker\Commit('cid'))->name('somename')->run();
$docker->verifyInvoked('executeCommand', ['docker commit cid somename ']);
}
public function testDockerExec()
{
$docker = test::double('Robo\Task\Docker\Exec', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Docker\Exec('cid'))->run();
$docker->verifyInvoked('executeCommand', ['docker exec cid ']);
(new \Robo\Task\Docker\Exec('cid'))->exec('pwd')->run();
$docker->verifyInvoked('executeCommand', ['docker exec cid pwd']);
}
public function testDockerPull()
{
$docker = test::double('Robo\Task\Docker\Pull', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Docker\Pull('image'))->run();
$docker->verifyInvoked('executeCommand', ['docker pull image ']);
}
public function testDockerRemove()
{
$docker = test::double('Robo\Task\Docker\Remove', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Docker\Remove('container'))->run();
$docker->verifyInvoked('executeCommand', ['docker rm container ']);
}
public function testDockerRun()
{
$docker = test::double('Robo\Task\Docker\Run', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger(), 'getUniqId' => '12345']);
(new \Robo\Task\Docker\Run('cid'))->tmpDir('/tmp')->run();
$docker->verifyInvoked('executeCommand', ['docker run -i --cidfile /tmp/docker_12345.cid cid']);
(new \Robo\Task\Docker\Run('cid'))->tmpDir('/tmp')->exec('pwd')->run();
$docker->verifyInvoked('executeCommand', ['docker run -i --cidfile /tmp/docker_12345.cid cid pwd']);
}
public function testDockerStart()
{
$docker = test::double('Robo\Task\Docker\Start', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Docker\Start('cid'))->run();
$docker->verifyInvoked('executeCommand', ['docker start cid']);
}
public function testDockerStop()
{
$docker = test::double('Robo\Task\Docker\Stop', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Docker\Stop('cid'))->run();
$docker->verifyInvoked('executeCommand', ['docker stop cid']);
}
}

View File

@@ -0,0 +1,73 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class ExecTaskTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $process;
protected function _before()
{
$this->process = test::double('Symfony\Component\Process\Process', [
'run' => false,
'start' => false,
'getOutput' => 'Hello world',
'getExitCode' => 0,
'logger' => new \Psr\Log\NullLogger(),
]);
test::double('Robo\Task\Base\Exec', ['output' => new \Symfony\Component\Console\Output\NullOutput()]);
}
public function testExec()
{
$task = new \Robo\Task\Base\Exec('ls');
$task->setLogger(new \Psr\Log\NullLogger());
$result = $task->run();
$this->process->verifyInvoked('run');
verify($result->getMessage())->equals('Hello world');
verify($result->getExitCode())->equals(0);
}
public function testExecInBackground()
{
$task = new \Robo\Task\Base\Exec('ls');
$task->setLogger(new \Psr\Log\NullLogger());
$result = $task->background()->run();
$this->process->verifyInvoked('start');
$this->process->verifyNeverInvoked('run');
verify('exit code was not received', $result->getExitCode())->notEquals(100);
}
public function testGetCommand()
{
verify((new \Robo\Task\Base\Exec('ls'))->getCommand())->equals('ls');
}
public function testExecStack()
{
$task = new \Robo\Task\Base\ExecStack();
$task->setLogger(new \Psr\Log\NullLogger());
$task
->exec('ls')
->exec('cd /')
->exec('cd home')
->run();
$this->process->verifyInvoked('run', 3);
}
public function testExecStackCommand()
{
verify((new \Robo\Task\Base\ExecStack())
->exec('ls')
->exec('cd /')
->exec('cd home')
->getCommand()
)->equals('ls && cd / && cd home');
}
};

View File

@@ -0,0 +1,62 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class GitTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $git;
protected function _before()
{
$this->git = test::double('Robo\Task\Vcs\GitStack', [
'executeCommand' => new \AspectMock\Proxy\Anything(),
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testGitStackRun()
{
(new \Robo\Task\Vcs\GitStack('git'))->stopOnFail()->add('-A')->pull()->run();
$this->git->verifyInvoked('executeCommand', ['git add -A']);
$this->git->verifyInvoked('executeCommand', ['git pull']);
(new \Robo\Task\Vcs\GitStack('git'))->add('-A')->pull()->run();
$this->git->verifyInvoked('executeCommand', ['git add -A && git pull']);
}
public function testGitStackCommands()
{
verify(
(new \Robo\Task\Vcs\GitStack())
->cloneRepo('http://github.com/consolidation-org/Robo')
->pull()
->add('-A')
->commit('changed')
->push()
->tag('0.6.0')
->push('origin', '0.6.0')
->getCommand()
)->equals("git clone http://github.com/consolidation-org/Robo && git pull && git add -A && git commit -m 'changed' && git push && git tag 0.6.0 && git push origin 0.6.0");
}
public function testGitStackCommandsWithTagMessage()
{
verify(
(new \Robo\Task\Vcs\GitStack())
->cloneRepo('http://github.com/consolidation-org/Robo')
->pull()
->add('-A')
->commit('changed')
->push()
->tag('0.6.0', 'message')
->push('origin', '0.6.0')
->getCommand()
)->equals("git clone http://github.com/consolidation-org/Robo && git pull && git add -A && git commit -m 'changed' && git push && git tag -m 'message' 0.6.0 && git push origin 0.6.0");
}
}

View File

@@ -0,0 +1,85 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class GulpTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $baseGulp;
protected function _before()
{
$this->baseGulp = test::double('Robo\Task\Gulp\Base', [
'output' => new \Symfony\Component\Console\Output\NullOutput()
]);
}
protected function adjustQuotes($expected)
{
$isWindows = defined('PHP_WINDOWS_VERSION_MAJOR');
if (!$isWindows) {
return strtr($expected, '"', "'");
}
return $expected;
}
// tests
public function testGulpGetCommand()
{
verify(
(new \Robo\Task\Gulp\Run('default','gulp'))->getCommand()
)->equals($this->adjustQuotes('gulp "default"'));
verify(
(new \Robo\Task\Gulp\Run('another','gulp'))->getCommand()
)->equals($this->adjustQuotes('gulp "another"'));
verify(
(new \Robo\Task\Gulp\Run('default','gulp'))->silent()->getCommand()
)->equals($this->adjustQuotes('gulp "default" --silent'));
verify(
(new \Robo\Task\Gulp\Run('default','gulp'))->noColor()->getCommand()
)->equals($this->adjustQuotes('gulp "default" --no-color'));
verify(
(new \Robo\Task\Gulp\Run('default','gulp'))->color()->getCommand()
)->equals($this->adjustQuotes('gulp "default" --color'));
verify(
(new \Robo\Task\Gulp\Run('default','gulp'))->simple()->getCommand()
)->equals($this->adjustQuotes('gulp "default" --tasks-simple'));
}
public function testGulpRun()
{
$gulp = test::double('Robo\Task\Gulp\Run', ['executeCommand' => null, 'getConfig' => new \Robo\Config(), 'logger' => new \Psr\Log\NullLogger()]);
$task = (new \Robo\Task\Gulp\Run('default','gulp'))->simple();
verify($task->getCommand())->equals($this->adjustQuotes('gulp "default" --tasks-simple'));
$task->run();
$gulp->verifyInvoked('executeCommand', [$this->adjustQuotes('gulp "default" --tasks-simple')]);
}
public function testGulpUnusualChars()
{
$isWindows = defined('PHP_WINDOWS_VERSION_MAJOR');
if ($isWindows) {
verify(
(new \Robo\Task\Gulp\Run('anotherWith weired!("\') Chars','gulp'))->getCommand()
)->equals('gulp "anotherWith weired!(\"\') Chars"');
} else {
verify(
(new \Robo\Task\Gulp\Run('anotherWith weired!("\') Chars','gulp'))->getCommand()
)->equals("gulp 'anotherWith weired!(\"'\\'') Chars'");
}
}
}

View File

@@ -0,0 +1,86 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class HgTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $hg;
/**
* @var \Robo\Task\Vcs\HgStack
*/
protected $hgStack;
protected function _before()
{
$this->hg = Test::double('Robo\Task\Vcs\HgStack', [
'executeCommand' => new \AspectMock\Proxy\Anything(),
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
$this->hgStack = (new \Robo\Task\Vcs\HgStack('hg'));
}
// tests
public function testHgStackRun()
{
$this->hgStack->stopOnFail()->add()->pull()->run();
$this->hg->verifyInvoked('executeCommand', ['hg add']);
$this->hg->verifyInvoked('executeCommand', ['hg pull']);
(new \Robo\Task\Vcs\HgStack('hg'))->add()->pull()->run();
$this->hg->verifyInvoked('executeCommand', ['hg add && hg pull']);
}
public function testHgStackPull()
{
verify(
$this->hgStack
->pull()
->getCommand()
)->equals('hg pull');
}
public function testHgStackAddFiles()
{
verify(
$this->hgStack
->add('*.php', '*.css')
->getCommand()
)->equals('hg add -I *.php -X *.css');
}
public function testHgStackCommands()
{
verify(
$this->hgStack
->cloneRepo('https://bitbucket.org/durin42/hgsubversion')
->pull()
->add()
->commit('changed')
->push()
->tag('0.6.0')
->push('0.6.0')
->getCommand()
)->equals("hg clone https://bitbucket.org/durin42/hgsubversion && hg pull && hg add && hg commit -m 'changed' && hg push && hg tag 0.6.0 && hg push -b '0.6.0'");
}
public function testHgStackCommandsWithTagMessage()
{
verify(
$this->hgStack
->cloneRepo('https://bitbucket.org/durin42/hgsubversion')
->pull()
->add()
->commit('changed')
->push()
->tag('0.6.0', 'message')
->push('0.6.0')
->getCommand()
)->equals("hg clone https://bitbucket.org/durin42/hgsubversion && hg pull && hg add && hg commit -m 'changed' && hg push && hg tag -m 'message' 0.6.0 && hg push -b '0.6.0'");
}
}

View File

@@ -0,0 +1,52 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class NpmTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $baseNpm;
protected function _before()
{
$this->baseNpm = test::double('Robo\Task\Npm\Base', [
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testNpmInstall()
{
$npm = test::double('Robo\Task\Npm\Install', ['executeCommand' => null, 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Npm\Install('npm'))->run();
$npm->verifyInvoked('executeCommand', ['npm install']);
}
public function testNpmUpdate()
{
$npm = test::double('Robo\Task\Npm\Update', ['executeCommand' => null, 'logger' => new \Psr\Log\NullLogger()]);
(new \Robo\Task\Npm\Update('npm'))->run();
$npm->verifyInvoked('executeCommand', ['npm update']);
}
public function testNpmInstallCommand()
{
verify(
(new \Robo\Task\Npm\Install('npm'))->getCommand()
)->equals('npm install');
verify(
(new \Robo\Task\Npm\Install('npm'))->getCommand()
)->equals('npm install');
verify(
(new \Robo\Task\Npm\Install('npm'))
->noDev()
->getCommand()
)->equals('npm install --production');
}
}

View File

@@ -0,0 +1,59 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class PHPServerTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $process;
protected function _before()
{
$this->process = test::double('Symfony\Component\Process\Process', [
'run' => false,
'start' => false,
'getOutput' => 'Hello world',
'getExitCode' => 0,
'logger' => new \Psr\Log\NullLogger(),
]);
test::double('Robo\Task\Development\PhpServer', ['output' => new \Symfony\Component\Console\Output\NullOutput()]);
}
public function testServerBackgroundRun()
{
$task = new \Robo\Task\Development\PhpServer('8000');
$task->setLogger(new \Psr\Log\NullLogger());
$task->background()->run();
$this->process->verifyInvoked('start');
}
public function testServerRun()
{
$task = new \Robo\Task\Development\PhpServer('8000');
$task->setLogger(new \Psr\Log\NullLogger());
$task->run();
$this->process->verifyInvoked('run');
}
public function testServerCommand()
{
if (strtolower(PHP_OS) === 'linux') {
$expectedCommand = 'exec php -S 127.0.0.1:8000 -t web';
} else {
$expectedCommand = 'php -S 127.0.0.1:8000 -t web';
}
verify(
(new \Robo\Task\Development\PhpServer('8000'))
->host('127.0.0.1')
->dir('web')
->getCommand()
)->equals($expectedCommand);
}
}

View File

@@ -0,0 +1,41 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class PHPUnitTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $phpunit;
protected function _before()
{
$this->phpunit = test::double('Robo\Task\Testing\PHPUnit', [
'executeCommand' => null,
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testPhpUnitRun()
{
(new \Robo\Task\Testing\PHPUnit())->run();
$this->phpunit->verifyInvoked('executeCommand');
}
public function testPHPUnitCommand()
{
$task = (new \Robo\Task\Testing\PHPUnit('phpunit'))
->bootstrap('bootstrap.php')
->filter('Model')
->group('important')
->xml('result.xml')
->debug();
verify($task->getCommand())->equals('phpunit --bootstrap bootstrap.php --filter Model --group important --log-junit result.xml --debug');
$task->run();
$this->phpunit->verifyInvoked('executeCommand', ['phpunit --bootstrap bootstrap.php --filter Model --group important --log-junit result.xml --debug']);
}
}

View File

@@ -0,0 +1,43 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class ParallelExecTest extends \Codeception\TestCase\Test
{
/**
* @var \CodeGuy
*/
protected $guy;
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $process;
protected function _before()
{
$this->process = test::double('Symfony\Component\Process\Process', [
'run' => false,
'start' => false,
'isRunning' => false,
'getOutput' => 'Hello world',
'getExitCode' => 0,
'logger' => new \Psr\Log\NullLogger(),
]);
}
public function testParallelExec()
{
$task = new \Robo\Task\Base\ParallelExec();
$task->setLogger($this->guy->logger());
$result = $task
->process('ls 1')
->process('ls 2')
->process('ls 3')
->run();
$this->process->verifyInvokedMultipleTimes('start', 3);
verify($result->getExitCode())->equals(0);
$this->guy->seeInOutput("3 processes finished");
}
}

View File

@@ -0,0 +1,42 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class PhpspecTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $phpspec;
protected function _before()
{
$this->phpspec = test::double('Robo\Task\Testing\Phpspec', [
'executeCommand' => null,
'output' => new \Symfony\Component\Console\Output\NullOutput(),
'logger' => new \Psr\Log\NullLogger(),
]);
}
// tests
public function testPhpSpecRun()
{
(new \Robo\Task\Testing\Phpspec('phpspec'))->run();
$this->phpspec->verifyInvoked('executeCommand', ['phpspec run']);
}
public function testPHPSpecCommand()
{
$task = (new \Robo\Task\Testing\Phpspec('phpspec'))
->stopOnFail()
->noCodeGeneration()
->quiet()
->verbose('vv')
->noAnsi()
->noInteraction()
->format('pretty');
verify($task->getCommand())->equals('phpspec run --stop-on-failure --no-code-generation --quiet -vv --no-ansi --no-interaction --format pretty');
$task->run();
$this->phpspec->verifyInvoked('executeCommand', ['phpspec run --stop-on-failure --no-code-generation --quiet -vv --no-ansi --no-interaction --format pretty']);
}
}

View File

@@ -0,0 +1,59 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class RsyncTest extends \Codeception\TestCase\Test
{
/**
* @var \CodeGuy
*/
protected $guy;
// tests
public function testRsync()
{
verify(
(new \Robo\Task\Remote\Rsync())
->fromPath('src/')
->toHost('localhost')
->toUser('dev')
->toPath('/var/www/html/app/')
->recursive()
->excludeVcs()
->checksum()
->wholeFile()
->verbose()
->progress()
->humanReadable()
->stats()
->getCommand()
)->equals(
'rsync --recursive --exclude .git --exclude .svn --exclude .hg --checksum --whole-file --verbose --progress --human-readable --stats src/ \'dev@localhost:/var/www/html/app/\''
);
// From the folder 'foo bar' (with space) in 'src' directory
verify(
(new \Robo\Task\Remote\Rsync())
->fromPath('src/foo bar/baz')
->toHost('localhost')
->toUser('dev')
->toPath('/var/path/with/a space')
->getCommand()
)->equals(
'rsync \'src/foo bar/baz\' \'dev@localhost:/var/path/with/a space\''
);
// Copy two folders, 'src/foo' and 'src/bar'
verify(
(new \Robo\Task\Remote\Rsync())
->fromPath(['src/foo', 'src/bar'])
->toHost('localhost')
->toUser('dev')
->toPath('/var/path/with/a space')
->getCommand()
)->equals(
'rsync src/foo src/bar \'dev@localhost:/var/path/with/a space\''
);
}
}

View File

@@ -0,0 +1,72 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class SemVerTest extends \Codeception\TestCase\Test
{
public function testSemver()
{
$semver = test::double('Robo\Task\Development\SemVer', ['dump' => null]);
$res = (new \Robo\Task\Development\SemVer())
->increment('major')
->prerelease('RC')
->increment('patch')
->run();
verify($res->getMessage())->equals('v1.0.1-RC.1');
$semver->verifyInvoked('dump');
}
public function testSemverIncrementMinorAfterIncrementedPatch()
{
$semver = test::double('Robo\Task\Development\SemVer', ['dump' => null]);
$res = (new \Robo\Task\Development\SemVer())
->increment('patch')
->run();
verify($res->getMessage())->equals('v0.0.1');
$res = (new \Robo\Task\Development\SemVer())
->increment('minor')
->run();
verify($res->getMessage())->equals('v0.1.0');
$semver->verifyInvoked('dump');
}
public function testSemverIncrementMajorAfterIncrementedMinorAndPatch()
{
$semver = test::double('Robo\Task\Development\SemVer', ['dump' => null]);
$res = (new \Robo\Task\Development\SemVer())
->increment('patch')
->run();
verify($res->getMessage())->equals('v0.0.1');
$res = (new \Robo\Task\Development\SemVer())
->increment('minor')
->run();
verify($res->getMessage())->equals('v0.1.0');
$res = (new \Robo\Task\Development\SemVer())
->increment('major')
->run();
verify($res->getMessage())->equals('v1.0.0');
$semver->verifyInvoked('dump');
}
public function testThrowsExceptionWhenIncrementWithWrongParameter()
{
\PHPUnit_Framework_TestCase::setExpectedExceptionRegExp(
'Robo\Exception\TaskException',
'/Bad argument, only one of the following is allowed: major, minor, patch/'
);
$res = (new \Robo\Task\Development\SemVer())
->increment('wrongParameter');
}
public function testThrowsExceptionWhenSemverFileNotWriteable()
{
\PHPUnit_Framework_TestCase::setExpectedExceptionRegExp(
'Robo\Exception\TaskException',
'/Failed to write semver file./'
);
(new \Robo\Task\Development\SemVer('/.semver'))
->increment('major')
->run();
}
}

View File

@@ -0,0 +1,61 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class SshTest extends \Codeception\TestCase\Test
{
// tests
public function testBasicCommand()
{
verify(
(new \Robo\Task\Remote\Ssh('remote.example.com', 'user'))
->exec('ls -la')
->exec('chmod g+x logs')
->getCommand()
)->equals("ssh user@remote.example.com 'ls -la && chmod g+x logs'");
}
public function testStopOnFail()
{
verify(
(new \Robo\Task\Remote\Ssh('remote.example.com', 'user'))
->stopOnFail(false)
->exec('one')
->exec('two')
->getCommand()
)->equals("ssh user@remote.example.com 'one ; two'");
}
/**
* Sets static configuration, then runs task without working dir, with working dir and again without.
*/
public function testWorkingDirectoryStaticConfiguration()
{
\Robo\Task\Remote\Ssh::configure('remoteDir', '/some-dir');
verify(
(new \Robo\Task\Remote\Ssh('remote.example.com', 'user'))
->setConfig(Robo::config())
->exec('echo test')
->getCommand()
)->equals("ssh user@remote.example.com 'cd \"/some-dir\" && echo test'");
verify(
(new \Robo\Task\Remote\Ssh('remote.example.com', 'user'))
->remoteDir('/other-dir')
->exec('echo test')
->getCommand()
)->equals("ssh user@remote.example.com 'cd \"/other-dir\" && echo test'");
verify(
(new \Robo\Task\Remote\Ssh('remote.example.com', 'user'))
->setConfig(Robo::config())
->exec('echo test')
->getCommand()
)->equals("ssh user@remote.example.com 'cd \"/some-dir\" && echo test'");
\Robo\Task\Remote\Ssh::configure('remoteDir', null);
verify(
(new \Robo\Task\Remote\Ssh('remote.example.com', 'user'))
->exec('echo test')
->getCommand()
)->equals("ssh user@remote.example.com 'echo test'");
}
}

View File

@@ -0,0 +1,49 @@
<?php
use AspectMock\Test as test;
use Robo\Robo;
class SvnTest extends \Codeception\TestCase\Test
{
/**
* @var \AspectMock\Proxy\ClassProxy
*/
protected $svn;
protected function _before()
{
$progressBar = test::double('Symfony\Component\Console\Helper\ProgressBar');
$nullOutput = new \Symfony\Component\Console\Output\NullOutput();
$progressIndicator = new \Robo\Common\ProgressIndicator($progressBar, $nullOutput);
$this->svn = test::double('Robo\Task\Vcs\SvnStack', [
'executeCommand' => new \AspectMock\Proxy\Anything(),
'output' => $nullOutput,
'logger' => new \Psr\Log\NullLogger(),
'logger' => Robo::logger(),
'getConfig' => Robo::config(),
'progressIndicator' => $progressIndicator,
]);
}
// tests
public function testSvnStackRun()
{
$this->svn->construct()->update()->add()->run();
$this->svn->verifyInvoked('executeCommand', ['svn update && svn add']);
}
public function testSvnStackCommands()
{
verify(
(new \Robo\Task\Vcs\SvnStack('guest', 'foo'))
->checkout('svn://server/trunk')
->update()
->add()
->commit('changed')
->getCommand()
)->equals("svn --username guest --password foo checkout svn://server/trunk && svn --username guest --password foo update && svn --username guest --password foo add && svn --username guest --password foo commit -m 'changed'");
}
}

View File

@@ -0,0 +1,2 @@
<?php
// Here you can initialize variables that will be available to your tests