9S_iL!eY&dodV=8r
z#(oHyxDVR>^!1dnAE*00>0Tdviw3~(#beGQ|qK5b8&_CCf|G+$8e)_Z$p
z#TSaj?qaNoHISc(R+A;EvvE77i?XvNlbv_+eR>pr-o*~UB94t%lm|SJ=i}66`MwNg
zw+Xhd@j<1G1?0Hq3-R+uai;x`viX#if!JNL?{2@Q(v8}{GovZ7NKf3SGWJ~FI*NnF
zkb|B~wWEJ-Qo}ZSwqTmkA67Mu`
zjix=L5#T58_RO?0iy3F>P1Hty7ybiS#P63Ztw&f3q$td%UvJ6T>`419DSL=X23R
zr*L~Xa2F>q_Ee59?R+7u3o`Z(In<1YAaCL)_#Rc0``g3)a-#|dWoj`M^U*XoxE7z;
z<@EWkh&Q_bK8i-~3;(p_g=V^=sn9)6_i#C$Pd+KXKN-Mx9hAK6Pak{f5z&puV4_k<
z^XWqqUhZ!~58Z%{Perpva_kU&Kl+bLcn8R5>|A;PcCv{v`X-m{SL8b()xp}B54DGF
zL2Dh`#5SV84)t2JsXS-?*;RURP6JV>%@`hcc_H&@N`?URAjUDlp2idwW>MA)Yhk~$7aM}!s_;8It~J#qJuvUADVrv6~Wdy*Ft$>sH;+|5-A{Ijel9x6#|!+`Mk%
z7q)NDG(PG7ZsmjSc*%rM%|eM#CaeMT_3uD4_
z!cpO*a9TJg7($`_bM}>X$-dsc$=+@su-{{Uz@D%lus>mc%6`~>(*CmjHTxU(|FFMn
zzhwWwp6{?Z?r?~X8b_m})!}pWIpU6I9WOXeIDX`K&GEY9ZO6Ng|8ZP$eCU`jep*~2
zE*AxHqu4I)5O<3`VnkHMuZZ`H4~dV62gJV-|5kiT{H}OJd`bMV_*3z1F(tky8lu@*
z>RjTy-MQRZ>s;eZIv;iZwR6OI$obFCMhIOI>BIU9N!Z0awEHq^qT>waQm@
zU)7^kU$0`-w^SEb-%)*c^}W?cs?Syby!w~b1@2<^5_i4Z
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Input\StringInput;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Process\ProcessBuilder;
+use Symfony\Component\Process\PhpExecutableFinder;
+
+/**
+ * A Shell wraps an Application to add shell capabilities to it.
+ *
+ * Support for history and completion only works with a PHP compiled
+ * with readline support (either --with-readline or --with-libedit)
+ *
+ * @author Fabien Potencier
+ * @author Martin Hasoň
+ */
+class Shell
+{
+ private $application;
+ private $history;
+ private $output;
+ private $hasReadline;
+ private $processIsolation = false;
+
+ /**
+ * Constructor.
+ *
+ * If there is no readline support for the current PHP executable
+ * a \RuntimeException exception is thrown.
+ *
+ * @param Application $application An application instance
+ */
+ public function __construct(Application $application)
+ {
+ $this->hasReadline = function_exists('readline');
+ $this->application = $application;
+ $this->history = getenv('HOME').'/.history_'.$application->getName();
+ $this->output = new ConsoleOutput();
+ }
+
+ /**
+ * Runs the shell.
+ */
+ public function run()
+ {
+ $this->application->setAutoExit(false);
+ $this->application->setCatchExceptions(true);
+
+ if ($this->hasReadline) {
+ readline_read_history($this->history);
+ readline_completion_function(array($this, 'autocompleter'));
+ }
+
+ $this->output->writeln($this->getHeader());
+ $php = null;
+ if ($this->processIsolation) {
+ $finder = new PhpExecutableFinder();
+ $php = $finder->find();
+ $this->output->writeln(<<Running with process isolation, you should consider this:
+ * each command is executed as separate process,
+ * commands don't support interactivity, all params must be passed explicitly,
+ * commands output is not colorized.
+
+EOF
+ );
+ }
+
+ while (true) {
+ $command = $this->readline();
+
+ if (false === $command) {
+ $this->output->writeln("\n");
+
+ break;
+ }
+
+ if ($this->hasReadline) {
+ readline_add_history($command);
+ readline_write_history($this->history);
+ }
+
+ if ($this->processIsolation) {
+ $pb = new ProcessBuilder();
+
+ $process = $pb
+ ->add($php)
+ ->add($_SERVER['argv'][0])
+ ->add($command)
+ ->inheritEnvironmentVariables(true)
+ ->getProcess()
+ ;
+
+ $output = $this->output;
+ $process->run(function ($type, $data) use ($output) {
+ $output->writeln($data);
+ });
+
+ $ret = $process->getExitCode();
+ } else {
+ $ret = $this->application->run(new StringInput($command), $this->output);
+ }
+
+ if (0 !== $ret) {
+ $this->output->writeln(sprintf('The command terminated with an error status (%s)', $ret));
+ }
+ }
+ }
+
+ /**
+ * Returns the shell header.
+ *
+ * @return string The header string
+ */
+ protected function getHeader()
+ {
+ return <<{$this->application->getName()} shell ({$this->application->getVersion()}).
+
+At the prompt, type help for some help,
+or list to get a list of available commands.
+
+To exit the shell, type ^D.
+
+EOF;
+ }
+
+ /**
+ * Renders a prompt.
+ *
+ * @return string The prompt
+ */
+ protected function getPrompt()
+ {
+ // using the formatter here is required when using readline
+ return $this->output->getFormatter()->format($this->application->getName().' > ');
+ }
+
+ protected function getOutput()
+ {
+ return $this->output;
+ }
+
+ protected function getApplication()
+ {
+ return $this->application;
+ }
+
+ /**
+ * Tries to return autocompletion for the current entered text.
+ *
+ * @param string $text The last segment of the entered text
+ *
+ * @return bool|array A list of guessed strings or true
+ */
+ private function autocompleter($text)
+ {
+ $info = readline_info();
+ $text = substr($info['line_buffer'], 0, $info['end']);
+
+ if ($info['point'] !== $info['end']) {
+ return true;
+ }
+
+ // task name?
+ if (false === strpos($text, ' ') || !$text) {
+ return array_keys($this->application->all());
+ }
+
+ // options and arguments?
+ try {
+ $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
+ } catch (\Exception $e) {
+ return true;
+ }
+
+ $list = array('--help');
+ foreach ($command->getDefinition()->getOptions() as $option) {
+ $list[] = '--'.$option->getName();
+ }
+
+ return $list;
+ }
+
+ /**
+ * Reads a single line from standard input.
+ *
+ * @return string The single line from standard input
+ */
+ private function readline()
+ {
+ if ($this->hasReadline) {
+ $line = readline($this->getPrompt());
+ } else {
+ $this->output->write($this->getPrompt());
+ $line = fgets(STDIN, 1024);
+ $line = (!$line && strlen($line) == 0) ? false : rtrim($line);
+ }
+
+ return $line;
+ }
+
+ public function getProcessIsolation()
+ {
+ return $this->processIsolation;
+ }
+
+ public function setProcessIsolation($processIsolation)
+ {
+ $this->processIsolation = (bool) $processIsolation;
+
+ if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
+ throw new \RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
+ }
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php b/core/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php
new file mode 100644
index 0000000..1630a97
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php
@@ -0,0 +1,128 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * Eases the testing of console applications.
+ *
+ * When testing an application, don't forget to disable the auto exit flag:
+ *
+ * $application = new Application();
+ * $application->setAutoExit(false);
+ *
+ * @author Fabien Potencier
+ */
+class ApplicationTester
+{
+ private $application;
+ private $input;
+ private $output;
+ private $statusCode;
+
+ /**
+ * Constructor.
+ *
+ * @param Application $application An Application instance to test.
+ */
+ public function __construct(Application $application)
+ {
+ $this->application = $application;
+ }
+
+ /**
+ * Executes the application.
+ *
+ * Available options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ *
+ * @param array $input An array of arguments and options
+ * @param array $options An array of options
+ *
+ * @return int The command exit code
+ */
+ public function run(array $input, $options = array())
+ {
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+
+ return $this->statusCode = $this->application->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the application.
+ *
+ * @param bool $normalize Whether to normalize end of lines to \n or not
+ *
+ * @return string The display
+ */
+ public function getDisplay($normalize = false)
+ {
+ rewind($this->output->getStream());
+
+ $display = stream_get_contents($this->output->getStream());
+
+ if ($normalize) {
+ $display = str_replace(PHP_EOL, "\n", $display);
+ }
+
+ return $display;
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the application.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the application.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+
+ /**
+ * Gets the status code returned by the last execution of the application.
+ *
+ * @return int The status code
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php b/core/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php
new file mode 100644
index 0000000..fe94d1e
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php
@@ -0,0 +1,132 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Eases the testing of console commands.
+ *
+ * @author Fabien Potencier
+ */
+class CommandTester
+{
+ private $command;
+ private $input;
+ private $output;
+ private $statusCode;
+
+ /**
+ * Constructor.
+ *
+ * @param Command $command A Command instance to test.
+ */
+ public function __construct(Command $command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * Executes the command.
+ *
+ * Available options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ *
+ * @param array $input An array of arguments and options
+ * @param array $options An array of options
+ *
+ * @return int The command exit code
+ */
+ public function execute(array $input, array $options = array())
+ {
+ // set the command name automatically if the application requires
+ // this argument and no command name was passed
+ if (!isset($input['command'])
+ && (null !== $application = $this->command->getApplication())
+ && $application->getDefinition()->hasArgument('command')
+ ) {
+ $input['command'] = $this->command->getName();
+ }
+
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+
+ return $this->statusCode = $this->command->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the command.
+ *
+ * @param bool $normalize Whether to normalize end of lines to \n or not
+ *
+ * @return string The display
+ */
+ public function getDisplay($normalize = false)
+ {
+ rewind($this->output->getStream());
+
+ $display = stream_get_contents($this->output->getStream());
+
+ if ($normalize) {
+ $display = str_replace(PHP_EOL, "\n", $display);
+ }
+
+ return $display;
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the command.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the command.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+
+ /**
+ * Gets the status code returned by the last execution of the application.
+ *
+ * @return int The status code
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php
new file mode 100644
index 0000000..32a23aa
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php
@@ -0,0 +1,951 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Tester\ApplicationTester;
+use Symfony\Component\Console\Event\ConsoleCommandEvent;
+use Symfony\Component\Console\Event\ConsoleExceptionEvent;
+use Symfony\Component\Console\Event\ConsoleTerminateEvent;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+
+class ApplicationTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixturesPath;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
+ require_once self::$fixturesPath.'/FooCommand.php';
+ require_once self::$fixturesPath.'/Foo1Command.php';
+ require_once self::$fixturesPath.'/Foo2Command.php';
+ require_once self::$fixturesPath.'/Foo3Command.php';
+ require_once self::$fixturesPath.'/Foo4Command.php';
+ require_once self::$fixturesPath.'/Foo5Command.php';
+ require_once self::$fixturesPath.'/FoobarCommand.php';
+ require_once self::$fixturesPath.'/BarBucCommand.php';
+ }
+
+ protected function normalizeLineBreaks($text)
+ {
+ return str_replace(PHP_EOL, "\n", $text);
+ }
+
+ /**
+ * Replaces the dynamic placeholders of the command help text with a static version.
+ * The placeholder %command.full_name% includes the script path that is not predictable
+ * and can not be tested against.
+ */
+ protected function ensureStaticCommandHelp(Application $application)
+ {
+ foreach ($application->all() as $command) {
+ $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
+ }
+ }
+
+ public function testConstructor()
+ {
+ $application = new Application('foo', 'bar');
+ $this->assertEquals('foo', $application->getName(), '__construct() takes the application name as its first argument');
+ $this->assertEquals('bar', $application->getVersion(), '__construct() takes the application version as its second argument');
+ $this->assertEquals(array('help', 'list'), array_keys($application->all()), '__construct() registered the help and list commands by default');
+ }
+
+ public function testSetGetName()
+ {
+ $application = new Application();
+ $application->setName('foo');
+ $this->assertEquals('foo', $application->getName(), '->setName() sets the name of the application');
+ }
+
+ public function testSetGetVersion()
+ {
+ $application = new Application();
+ $application->setVersion('bar');
+ $this->assertEquals('bar', $application->getVersion(), '->setVersion() sets the version of the application');
+ }
+
+ public function testGetLongVersion()
+ {
+ $application = new Application('foo', 'bar');
+ $this->assertEquals('foo version bar', $application->getLongVersion(), '->getLongVersion() returns the long version of the application');
+ }
+
+ public function testHelp()
+ {
+ $application = new Application();
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_gethelp.txt', $this->normalizeLineBreaks($application->getHelp()), '->setHelp() returns a help message');
+ }
+
+ public function testAll()
+ {
+ $application = new Application();
+ $commands = $application->all();
+ $this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands');
+
+ $application->add(new \FooCommand());
+ $commands = $application->all('foo');
+ $this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
+ }
+
+ public function testRegister()
+ {
+ $application = new Application();
+ $command = $application->register('foo');
+ $this->assertEquals('foo', $command->getName(), '->register() registers a new command');
+ }
+
+ public function testAdd()
+ {
+ $application = new Application();
+ $application->add($foo = new \FooCommand());
+ $commands = $application->all();
+ $this->assertEquals($foo, $commands['foo:bar'], '->add() registers a command');
+
+ $application = new Application();
+ $application->addCommands(array($foo = new \FooCommand(), $foo1 = new \Foo1Command()));
+ $commands = $application->all();
+ $this->assertEquals(array($foo, $foo1), array($commands['foo:bar'], $commands['foo:bar1']), '->addCommands() registers an array of commands');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Command class "Foo5Command" is not correctly initialized. You probably forgot to call the parent constructor.
+ */
+ public function testAddCommandWithEmptyConstructor()
+ {
+ $application = new Application();
+ $application->add(new \Foo5Command());
+ }
+
+ public function testHasGet()
+ {
+ $application = new Application();
+ $this->assertTrue($application->has('list'), '->has() returns true if a named command is registered');
+ $this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered');
+
+ $application->add($foo = new \FooCommand());
+ $this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered');
+ $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
+ $this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');
+
+ $application = new Application();
+ $application->add($foo = new \FooCommand());
+ // simulate --help
+ $r = new \ReflectionObject($application);
+ $p = $r->getProperty('wantHelps');
+ $p->setAccessible(true);
+ $p->setValue($application, true);
+ $command = $application->get('foo:bar');
+ $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input');
+ }
+
+ public function testSilentHelp()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('-h' => true, '-q' => true), array('decorated' => false));
+
+ $this->assertEmpty($tester->getDisplay(true));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The command "foofoo" does not exist.
+ */
+ public function testGetInvalidCommand()
+ {
+ $application = new Application();
+ $application->get('foofoo');
+ }
+
+ public function testGetNamespaces()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $this->assertEquals(array('foo'), $application->getNamespaces(), '->getNamespaces() returns an array of unique used namespaces');
+ }
+
+ public function testFindNamespace()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
+ $this->assertEquals('foo', $application->findNamespace('f'), '->findNamespace() finds a namespace given an abbreviation');
+ $application->add(new \Foo2Command());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The namespace "f" is ambiguous (foo, foo1).
+ */
+ public function testFindAmbiguousNamespace()
+ {
+ $application = new Application();
+ $application->add(new \BarBucCommand());
+ $application->add(new \FooCommand());
+ $application->add(new \Foo2Command());
+ $application->findNamespace('f');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage There are no commands defined in the "bar" namespace.
+ */
+ public function testFindInvalidNamespace()
+ {
+ $application = new Application();
+ $application->findNamespace('bar');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Command "foo1" is not defined
+ */
+ public function testFindUniqueNameButNamespaceName()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ $application->find($commandName = 'foo1');
+ }
+
+ public function testFind()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+
+ $this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
+ $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
+ $this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists');
+ $this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist');
+ $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
+ }
+
+ /**
+ * @dataProvider provideAmbiguousAbbreviations
+ */
+ public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage)
+ {
+ $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);
+
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ $application->find($abbreviation);
+ }
+
+ public function provideAmbiguousAbbreviations()
+ {
+ return array(
+ array('f', 'Command "f" is not defined.'),
+ array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'),
+ array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).')
+ );
+ }
+
+ public function testFindCommandEqualNamespace()
+ {
+ $application = new Application();
+ $application->add(new \Foo3Command());
+ $application->add(new \Foo4Command());
+
+ $this->assertInstanceOf('Foo3Command', $application->find('foo3:bar'), '->find() returns the good command even if a namespace has same name');
+ $this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name');
+ }
+
+ public function testFindCommandWithAmbiguousNamespacesButUniqueName()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \FoobarCommand());
+
+ $this->assertInstanceOf('FoobarCommand', $application->find('f:f'));
+ }
+
+ public function testFindCommandWithMissingNamespace()
+ {
+ $application = new Application();
+ $application->add(new \Foo4Command());
+
+ $this->assertInstanceOf('Foo4Command', $application->find('f::t'));
+ }
+
+ /**
+ * @dataProvider provideInvalidCommandNamesSingle
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Did you mean this
+ */
+ public function testFindAlternativeExceptionMessageSingle($name)
+ {
+ $application = new Application();
+ $application->add(new \Foo3Command());
+ $application->find($name);
+ }
+
+ public function provideInvalidCommandNamesSingle()
+ {
+ return array(
+ array('foo3:baR'),
+ array('foO3:bar')
+ );
+ }
+
+ public function testFindAlternativeExceptionMessageMultiple()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ // Command + plural
+ try {
+ $application->find('foo:baR');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/foo1:bar/', $e->getMessage());
+ $this->assertRegExp('/foo:bar/', $e->getMessage());
+ }
+
+ // Namespace + plural
+ try {
+ $application->find('foo2:bar');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/foo1/', $e->getMessage());
+ }
+
+ $application->add(new \Foo3Command());
+ $application->add(new \Foo4Command());
+
+ // Subnamespace + plural
+ try {
+ $a = $application->find('foo3:');
+ $this->fail('->find() should throw an \InvalidArgumentException if a command is ambiguous because of a subnamespace, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e);
+ $this->assertRegExp('/foo3:bar/', $e->getMessage());
+ $this->assertRegExp('/foo3:bar:toh/', $e->getMessage());
+ }
+ }
+
+ public function testFindAlternativeCommands()
+ {
+ $application = new Application();
+
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ try {
+ $application->find($commandName = 'Unknown command');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist');
+ $this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, without alternatives');
+ }
+
+ // Test if "bar1" command throw an "\InvalidArgumentException" and does not contain
+ // "foo:bar" as alternative because "bar1" is too far from "foo:bar"
+ try {
+ $application->find($commandName = 'bar1');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist');
+ $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "afoobar1"');
+ $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo:bar1"');
+ $this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, without "foo:bar" alternative');
+ }
+ }
+
+ public function testFindAlternativeCommandsWithAnAlias()
+ {
+ $fooCommand = new \FooCommand();
+ $fooCommand->setAliases(array('foo2'));
+
+ $application = new Application();
+ $application->add($fooCommand);
+
+ $result = $application->find('foo');
+
+ $this->assertSame($fooCommand, $result);
+ }
+
+ public function testFindAlternativeNamespace()
+ {
+ $application = new Application();
+
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+ $application->add(new \foo3Command());
+
+ try {
+ $application->find('Unknown-namespace:Unknown-command');
+ $this->fail('->find() throws an \InvalidArgumentException if namespace does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if namespace does not exist');
+ $this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, without alternatives');
+ }
+
+ try {
+ $application->find('foo2:command');
+ $this->fail('->find() throws an \InvalidArgumentException if namespace does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if namespace does not exist');
+ $this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative');
+ $this->assertRegExp('/foo/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo"');
+ $this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo1"');
+ $this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo3"');
+ }
+ }
+
+ public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getNamespaces'));
+ $application->expects($this->once())
+ ->method('getNamespaces')
+ ->will($this->returnValue(array('foo:sublong', 'bar:sub')));
+
+ $this->assertEquals('foo:sublong', $application->findNamespace('f:sub'));
+ }
+
+ public function testSetCatchExceptions()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $tester = new ApplicationTester($application);
+
+ $application->setCatchExceptions(true);
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->setCatchExceptions() sets the catch exception flag');
+
+ $application->setCatchExceptions(false);
+ try {
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->fail('->setCatchExceptions() sets the catch exception flag');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\Exception', $e, '->setCatchExceptions() sets the catch exception flag');
+ $this->assertEquals('Command "foo" is not defined.', $e->getMessage(), '->setCatchExceptions() sets the catch exception flag');
+ }
+ }
+
+ public function testAsText()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $this->ensureStaticCommandHelp($application);
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext1.txt', $this->normalizeLineBreaks($application->asText()), '->asText() returns a text representation of the application');
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext2.txt', $this->normalizeLineBreaks($application->asText('foo')), '->asText() returns a text representation of the application');
+ }
+
+ public function testAsXml()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $this->ensureStaticCommandHelp($application);
+ $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml1.txt', $application->asXml(), '->asXml() returns an XML representation of the application');
+ $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml2.txt', $application->asXml('foo'), '->asXml() returns an XML representation of the application');
+ }
+
+ public function testRenderException()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exception');
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
+ $this->assertContains('Exception trace', $tester->getDisplay(), '->renderException() renders a pretty exception with a stack trace when verbosity is verbose');
+
+ $tester->run(array('command' => 'list', '--foo' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $tester->getDisplay(true), '->renderException() renders the command synopsis when an exception occurs in the context of a command');
+
+ $application->add(new \Foo3Command());
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(32));
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
+ }
+
+ public function testRenderExceptionWithDoubleWidthCharacters()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $application->register('foo')->setCode(function () {
+ throw new \Exception('エラーメッセージ');
+ });
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1.txt', $tester->getDisplay(true), '->renderException() renderes a pretty exceptions with previous exceptions');
+
+ $tester->run(array('command' => 'foo'), array('decorated' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getDisplay(true), '->renderException() renderes a pretty exceptions with previous exceptions');
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(32));
+ $application->register('foo')->setCode(function () {
+ throw new \Exception('コマンドの実行中にエラーが発生しました。');
+ });
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
+ }
+
+ public function testRun()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add($command = new \Foo1Command());
+ $_SERVER['argv'] = array('cli.php', 'foo:bar1');
+
+ ob_start();
+ $application->run();
+ ob_end_clean();
+
+ $this->assertInstanceOf('Symfony\Component\Console\Input\ArgvInput', $command->input, '->run() creates an ArgvInput by default if none is given');
+ $this->assertInstanceOf('Symfony\Component\Console\Output\ConsoleOutput', $command->output, '->run() creates a ConsoleOutput by default if none is given');
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $this->ensureStaticCommandHelp($application);
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array(), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run1.txt', $tester->getDisplay(true), '->run() runs the list command if no argument is passed');
+
+ $tester->run(array('--help' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if --help is passed');
+
+ $tester->run(array('-h' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if -h is passed');
+
+ $tester->run(array('command' => 'list', '--help' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if --help is passed');
+
+ $tester->run(array('command' => 'list', '-h' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if -h is passed');
+
+ $tester->run(array('--ansi' => true));
+ $this->assertTrue($tester->getOutput()->isDecorated(), '->run() forces color output if --ansi is passed');
+
+ $tester->run(array('--no-ansi' => true));
+ $this->assertFalse($tester->getOutput()->isDecorated(), '->run() forces color output to be disabled if --no-ansi is passed');
+
+ $tester->run(array('--version' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if --version is passed');
+
+ $tester->run(array('-V' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if -v is passed');
+
+ $tester->run(array('command' => 'list', '--quiet' => true));
+ $this->assertSame('', $tester->getDisplay(), '->run() removes all output if --quiet is passed');
+
+ $tester->run(array('command' => 'list', '-q' => true));
+ $this->assertSame('', $tester->getDisplay(), '->run() removes all output if -q is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => true));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 1));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose=1 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 2));
+ $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to very verbose if --verbose=2 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 3));
+ $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to debug if --verbose=3 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 4));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if unknown --verbose level is passed');
+
+ $tester->run(array('command' => 'list', '-v' => true));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $tester->run(array('command' => 'list', '-vv' => true));
+ $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $tester->run(array('command' => 'list', '-vvv' => true));
+ $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add(new \FooCommand());
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo:bar', '--no-interaction' => true), array('decorated' => false));
+ $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if --no-interaction is passed');
+
+ $tester->run(array('command' => 'foo:bar', '-n' => true), array('decorated' => false));
+ $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed');
+ }
+
+ /**
+ * Issue #9285
+ *
+ * If the "verbose" option is just before an argument in ArgvInput,
+ * an argument value should not be treated as verbosity value.
+ * This test will fail with "Not enough arguments." if broken
+ */
+ public function testVerboseValueNotBreakArguments()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add(new \FooCommand());
+
+ $output = new StreamOutput(fopen('php://memory', 'w', false));
+
+ $input = new ArgvInput(array('cli.php', '-v', 'foo:bar'));
+ $application->run($input, $output);
+
+ $input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar'));
+ $application->run($input, $output);
+ }
+
+ public function testRunReturnsIntegerExitCode()
+ {
+ $exception = new \Exception('', 4);
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
+ $application->setAutoExit(false);
+ $application->expects($this->once())
+ ->method('doRun')
+ ->will($this->throwException($exception));
+
+ $exitCode = $application->run(new ArrayInput(array()), new NullOutput());
+
+ $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception');
+ }
+
+ public function testRunReturnsExitCodeOneForExceptionCodeZero()
+ {
+ $exception = new \Exception('', 0);
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
+ $application->setAutoExit(false);
+ $application->expects($this->once())
+ ->method('doRun')
+ ->will($this->throwException($exception));
+
+ $exitCode = $application->run(new ArrayInput(array()), new NullOutput());
+
+ $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @dataProvider getAddingAlreadySetDefinitionElementData
+ */
+ public function testAddingAlreadySetDefinitionElementData($def)
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application
+ ->register('foo')
+ ->setDefinition(array($def))
+ ->setCode(function (InputInterface $input, OutputInterface $output) {})
+ ;
+
+ $input = new ArrayInput(array('command' => 'foo'));
+ $output = new NullOutput();
+ $application->run($input, $output);
+ }
+
+ public function getAddingAlreadySetDefinitionElementData()
+ {
+ return array(
+ array(new InputArgument('command', InputArgument::REQUIRED)),
+ array(new InputOption('quiet', '', InputOption::VALUE_NONE)),
+ array(new InputOption('query', 'q', InputOption::VALUE_NONE)),
+ );
+ }
+
+ public function testGetDefaultHelperSetReturnsDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+ $this->assertTrue($helperSet->has('dialog'));
+ $this->assertTrue($helperSet->has('progress'));
+ }
+
+ public function testAddingSingleHelperSetOverwritesDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setHelperSet(new HelperSet(array(new FormatterHelper())));
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+
+ // no other default helper set should be returned
+ $this->assertFalse($helperSet->has('dialog'));
+ $this->assertFalse($helperSet->has('progress'));
+ }
+
+ public function testOverwritingDefaultHelperSetOverwritesDefaultValues()
+ {
+ $application = new CustomApplication();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setHelperSet(new HelperSet(array(new FormatterHelper())));
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+
+ // no other default helper set should be returned
+ $this->assertFalse($helperSet->has('dialog'));
+ $this->assertFalse($helperSet->has('progress'));
+ }
+
+ public function testGetDefaultInputDefinitionReturnsDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $inputDefinition = $application->getDefinition();
+
+ $this->assertTrue($inputDefinition->hasArgument('command'));
+
+ $this->assertTrue($inputDefinition->hasOption('help'));
+ $this->assertTrue($inputDefinition->hasOption('quiet'));
+ $this->assertTrue($inputDefinition->hasOption('verbose'));
+ $this->assertTrue($inputDefinition->hasOption('version'));
+ $this->assertTrue($inputDefinition->hasOption('ansi'));
+ $this->assertTrue($inputDefinition->hasOption('no-ansi'));
+ $this->assertTrue($inputDefinition->hasOption('no-interaction'));
+ }
+
+ public function testOverwritingDefaultInputDefinitionOverwritesDefaultValues()
+ {
+ $application = new CustomApplication();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $inputDefinition = $application->getDefinition();
+
+ // check whether the default arguments and options are not returned any more
+ $this->assertFalse($inputDefinition->hasArgument('command'));
+
+ $this->assertFalse($inputDefinition->hasOption('help'));
+ $this->assertFalse($inputDefinition->hasOption('quiet'));
+ $this->assertFalse($inputDefinition->hasOption('verbose'));
+ $this->assertFalse($inputDefinition->hasOption('version'));
+ $this->assertFalse($inputDefinition->hasOption('ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-interaction'));
+
+ $this->assertTrue($inputDefinition->hasOption('custom'));
+ }
+
+ public function testSettingCustomInputDefinitionOverwritesDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setDefinition(new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.'))));
+
+ $inputDefinition = $application->getDefinition();
+
+ // check whether the default arguments and options are not returned any more
+ $this->assertFalse($inputDefinition->hasArgument('command'));
+
+ $this->assertFalse($inputDefinition->hasOption('help'));
+ $this->assertFalse($inputDefinition->hasOption('quiet'));
+ $this->assertFalse($inputDefinition->hasOption('verbose'));
+ $this->assertFalse($inputDefinition->hasOption('version'));
+ $this->assertFalse($inputDefinition->hasOption('ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-interaction'));
+
+ $this->assertTrue($inputDefinition->hasOption('custom'));
+ }
+
+ public function testRunWithDispatcher()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setDispatcher($this->getDispatcher());
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ $this->assertEquals('before.foo.after.', $tester->getDisplay());
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage caught
+ */
+ public function testRunWithExceptionAndDispatcher()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher());
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ throw new \RuntimeException('foo');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ }
+
+ public function testRunDispatchesAllEventsWithException()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher());
+ $application->setAutoExit(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+
+ throw new \RuntimeException('foo');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ $this->assertContains('before.foo.after.caught.', $tester->getDisplay());
+ }
+
+ public function testTerminalDimensions()
+ {
+ $application = new Application();
+ $originalDimensions = $application->getTerminalDimensions();
+ $this->assertCount(2, $originalDimensions);
+
+ $width = 80;
+ if ($originalDimensions[0] == $width) {
+ $width = 100;
+ }
+
+ $application->setTerminalDimensions($width, 80);
+ $this->assertSame(array($width, 80), $application->getTerminalDimensions());
+ }
+
+ protected function getDispatcher()
+ {
+ $dispatcher = new EventDispatcher();
+ $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) {
+ $event->getOutput()->write('before.');
+ });
+ $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) {
+ $event->getOutput()->write('after.');
+
+ $event->setExitCode(128);
+ });
+ $dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) {
+ $event->getOutput()->writeln('caught.');
+
+ $event->setException(new \LogicException('caught.', $event->getExitCode(), $event->getException()));
+ });
+
+ return $dispatcher;
+ }
+}
+
+class CustomApplication extends Application
+{
+ /**
+ * Overwrites the default input definition.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ protected function getDefaultInputDefinition()
+ {
+ return new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')));
+ }
+
+ /**
+ * Gets the default helper set with the helpers that should always be available.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ protected function getDefaultHelperSet()
+ {
+ return new HelperSet(array(new FormatterHelper()));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php
new file mode 100644
index 0000000..872bb7f
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php
@@ -0,0 +1,338 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\StringInput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class CommandTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixturesPath;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixturesPath = __DIR__.'/../Fixtures/';
+ require_once self::$fixturesPath.'/TestCommand.php';
+ }
+
+ public function testConstructor()
+ {
+ $command = new Command('foo:bar');
+ $this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage The command name cannot be empty.
+ */
+ public function testCommandNameCannotBeEmpty()
+ {
+ new Command();
+ }
+
+ public function testSetApplication()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application');
+ }
+
+ public function testSetGetDefinition()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setDefinition($definition = new InputDefinition());
+ $this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface');
+ $this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance');
+ $command->setDefinition(array(new InputArgument('foo'), new InputOption('bar')));
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
+ $command->setDefinition(new InputDefinition());
+ }
+
+ public function testAddArgument()
+ {
+ $command = new \TestCommand();
+ $ret = $command->addArgument('foo');
+ $this->assertEquals($command, $ret, '->addArgument() implements a fluent interface');
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->addArgument() adds an argument to the command');
+ }
+
+ public function testAddOption()
+ {
+ $command = new \TestCommand();
+ $ret = $command->addOption('foo');
+ $this->assertEquals($command, $ret, '->addOption() implements a fluent interface');
+ $this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command');
+ }
+
+ public function testGetNamespaceGetNameSetName()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('namespace:name', $command->getName(), '->getName() returns the command name');
+ $command->setName('foo');
+ $this->assertEquals('foo', $command->getName(), '->setName() sets the command name');
+
+ $ret = $command->setName('foobar:bar');
+ $this->assertEquals($command, $ret, '->setName() implements a fluent interface');
+ $this->assertEquals('foobar:bar', $command->getName(), '->setName() sets the command name');
+ }
+
+ /**
+ * @dataProvider provideInvalidCommandNames
+ */
+ public function testInvalidCommandNames($name)
+ {
+ $this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name));
+
+ $command = new \TestCommand();
+ $command->setName($name);
+ }
+
+ public function provideInvalidCommandNames()
+ {
+ return array(
+ array(''),
+ array('foo:')
+ );
+ }
+
+ public function testGetSetDescription()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('description', $command->getDescription(), '->getDescription() returns the description');
+ $ret = $command->setDescription('description1');
+ $this->assertEquals($command, $ret, '->setDescription() implements a fluent interface');
+ $this->assertEquals('description1', $command->getDescription(), '->setDescription() sets the description');
+ }
+
+ public function testGetSetHelp()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('help', $command->getHelp(), '->getHelp() returns the help');
+ $ret = $command->setHelp('help1');
+ $this->assertEquals($command, $ret, '->setHelp() implements a fluent interface');
+ $this->assertEquals('help1', $command->getHelp(), '->setHelp() sets the help');
+ }
+
+ public function testGetProcessedHelp()
+ {
+ $command = new \TestCommand();
+ $command->setHelp('The %command.name% command does... Example: php %command.full_name%.');
+ $this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly');
+ $this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name%');
+ }
+
+ public function testGetSetAliases()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals(array('name'), $command->getAliases(), '->getAliases() returns the aliases');
+ $ret = $command->setAliases(array('name1'));
+ $this->assertEquals($command, $ret, '->setAliases() implements a fluent interface');
+ $this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases');
+ }
+
+ public function testGetSynopsis()
+ {
+ $command = new \TestCommand();
+ $command->addOption('foo');
+ $command->addArgument('foo');
+ $this->assertEquals('namespace:name [--foo] [foo]', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
+ }
+
+ public function testGetHelper()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $formatterHelper = new FormatterHelper();
+ $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper');
+ }
+
+ public function testGet()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $formatterHelper = new FormatterHelper();
+ $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->__get() returns the correct helper');
+ }
+
+ public function testMergeApplicationDefinition()
+ {
+ $application1 = new Application();
+ $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
+ $application1->getDefinition()->addOptions(array(new InputOption('bar')));
+ $command = new \TestCommand();
+ $command->setApplication($application1);
+ $command->setDefinition($definition = new InputDefinition(array(new InputArgument('bar'), new InputOption('foo'))));
+
+ $r = new \ReflectionObject($command);
+ $m = $r->getMethod('mergeApplicationDefinition');
+ $m->setAccessible(true);
+ $m->invoke($command);
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
+ $this->assertTrue($command->getDefinition()->hasArgument('bar'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
+ $this->assertTrue($command->getDefinition()->hasOption('foo'), '->mergeApplicationDefinition() merges the application options and the command options');
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition() merges the application options and the command options');
+
+ $m->invoke($command);
+ $this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options');
+ }
+
+ public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs()
+ {
+ $application1 = new Application();
+ $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
+ $application1->getDefinition()->addOptions(array(new InputOption('bar')));
+ $command = new \TestCommand();
+ $command->setApplication($application1);
+ $command->setDefinition($definition = new InputDefinition(array()));
+
+ $r = new \ReflectionObject($command);
+ $m = $r->getMethod('mergeApplicationDefinition');
+ $m->setAccessible(true);
+ $m->invoke($command, false);
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the commmand options');
+ $this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments');
+
+ $m->invoke($command, true);
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments');
+
+ $m->invoke($command);
+ $this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments');
+ }
+
+ public function testRunInteractive()
+ {
+ $tester = new CommandTester(new \TestCommand());
+
+ $tester->execute(array(), array('interactive' => true));
+
+ $this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive');
+ }
+
+ public function testRunNonInteractive()
+ {
+ $tester = new CommandTester(new \TestCommand());
+
+ $tester->execute(array(), array('interactive' => false));
+
+ $this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You must override the execute() method in the concrete command class.
+ */
+ public function testExecuteMethodNeedsToBeOverriden()
+ {
+ $command = new Command('foo');
+ $command->run(new StringInput(''), new NullOutput());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "--bar" option does not exist.
+ */
+ public function testRunWithInvalidOption()
+ {
+ $command = new \TestCommand();
+ $tester = new CommandTester($command);
+ $tester->execute(array('--bar' => true));
+ }
+
+ public function testRunReturnsIntegerExitCode()
+ {
+ $command = new \TestCommand();
+ $exitCode = $command->run(new StringInput(''), new NullOutput());
+ $this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)');
+
+ $command = $this->getMock('TestCommand', array('execute'));
+ $command->expects($this->once())
+ ->method('execute')
+ ->will($this->returnValue('2.3'));
+ $exitCode = $command->run(new StringInput(''), new NullOutput());
+ $this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)');
+ }
+
+ public function testRunReturnsAlwaysInteger()
+ {
+ $command = new \TestCommand();
+
+ $this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
+ }
+
+ public function testSetCode()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->writeln('from the code...');
+ });
+ $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
+ $tester = new CommandTester($command);
+ $tester->execute(array());
+ $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
+ }
+
+ public function testSetCodeWithNonClosureCallable()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setCode(array($this, 'callableMethodCommand'));
+ $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
+ $tester = new CommandTester($command);
+ $tester->execute(array());
+ $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Invalid callable provided to Command::setCode.
+ */
+ public function testSetCodeWithNonCallable()
+ {
+ $command = new \TestCommand();
+ $command->setCode(array($this, 'nonExistentMethod'));
+ }
+
+ public function callableMethodCommand(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('from the code...');
+ }
+
+ public function testAsText()
+ {
+ $command = new \TestCommand();
+ $command->setApplication(new Application());
+ $tester = new CommandTester($command);
+ $tester->execute(array('command' => $command->getName()));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/command_astext.txt', $command->asText(), '->asText() returns a text representation of the command');
+ }
+
+ public function testAsXml()
+ {
+ $command = new \TestCommand();
+ $command->setApplication(new Application());
+ $tester = new CommandTester($command);
+ $tester->execute(array('command' => $command->getName()));
+ $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/command_asxml.txt', $command->asXml(), '->asXml() returns an XML representation of the command');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php
new file mode 100644
index 0000000..ea69c8b
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Console\Command\HelpCommand;
+use Symfony\Component\Console\Command\ListCommand;
+use Symfony\Component\Console\Application;
+
+class HelpCommandTest extends \PHPUnit_Framework_TestCase
+{
+ public function testExecuteForCommandAlias()
+ {
+ $command = new HelpCommand();
+ $command->setApplication(new Application());
+ $commandTester = new CommandTester($command);
+ $commandTester->execute(array('command_name' => 'li'));
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
+ }
+
+ public function testExecuteForCommand()
+ {
+ $command = new HelpCommand();
+ $commandTester = new CommandTester($command);
+ $command->setCommand(new ListCommand());
+ $commandTester->execute(array());
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ }
+
+ public function testExecuteForCommandWithXmlOption()
+ {
+ $command = new HelpCommand();
+ $commandTester = new CommandTester($command);
+ $command->setCommand(new ListCommand());
+ $commandTester->execute(array('--format' => 'xml'));
+ $this->assertRegExp('/getDisplay(), '->execute() returns an XML help text if --xml is passed');
+ }
+
+ public function testExecuteForApplicationCommand()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($application->get('help'));
+ $commandTester->execute(array('command_name' => 'list'));
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ }
+
+ public function testExecuteForApplicationCommandWithXmlOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($application->get('help'));
+ $commandTester->execute(array('command_name' => 'list', '--format' => 'xml'));
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ $this->assertRegExp('/getDisplay(), '->execute() returns an XML help text if --format=xml is passed');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php
new file mode 100644
index 0000000..1df06f5
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php
@@ -0,0 +1,65 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Console\Application;
+
+class ListCommandTest extends \PHPUnit_Framework_TestCase
+{
+ public function testExecuteListsCommands()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName()), array('decorated' => false));
+
+ $this->assertRegExp('/help Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands');
+ }
+
+ public function testExecuteListsCommandsWithXmlOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), '--format' => 'xml'));
+ $this->assertRegExp('//', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
+ }
+
+ public function testExecuteListsCommandsWithRawOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), '--raw' => true));
+ $output = <<assertEquals($output, $commandTester->getDisplay(true));
+ }
+
+ public function testExecuteListsCommandsWithNamespaceArgument()
+ {
+
+ require_once(realpath(__DIR__.'/../Fixtures/FooCommand.php'));
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), 'namespace' => 'foo', '--raw' => true));
+ $output = <<assertEquals($output, $commandTester->getDisplay(true));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php
new file mode 100644
index 0000000..406c659
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php
@@ -0,0 +1,105 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\BufferedOutput;
+
+abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
+{
+ /** @dataProvider getDescribeInputArgumentTestData */
+ public function testDescribeInputArgument(InputArgument $argument, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $argument);
+ }
+
+ /** @dataProvider getDescribeInputOptionTestData */
+ public function testDescribeInputOption(InputOption $option, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $option);
+ }
+
+ /** @dataProvider getDescribeInputDefinitionTestData */
+ public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $definition);
+ }
+
+ /** @dataProvider getDescribeCommandTestData */
+ public function testDescribeCommand(Command $command, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $command);
+ }
+
+ /** @dataProvider getDescribeApplicationTestData */
+ public function testDescribeApplication(Application $application, $expectedDescription)
+ {
+ // Replaces the dynamic placeholders of the command help text with a static version.
+ // The placeholder %command.full_name% includes the script path that is not predictable
+ // and can not be tested against.
+ foreach ($application->all() as $command) {
+ $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
+ }
+
+ $this->assertDescription($expectedDescription, $application);
+ }
+
+ public function getDescribeInputArgumentTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputArguments());
+ }
+
+ public function getDescribeInputOptionTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputOptions());
+ }
+
+ public function getDescribeInputDefinitionTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputDefinitions());
+ }
+
+ public function getDescribeCommandTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getCommands());
+ }
+
+ public function getDescribeApplicationTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getApplications());
+ }
+
+ abstract protected function getDescriptor();
+ abstract protected function getFormat();
+
+ private function getDescriptionTestData(array $objects)
+ {
+ $data = array();
+ foreach ($objects as $name => $object) {
+ $description = file_get_contents(sprintf('%s/../Fixtures/%s.%s', __DIR__, $name, $this->getFormat()));
+ $data[] = array($object, $description);
+ }
+
+ return $data;
+ }
+
+ private function assertDescription($expectedDescription, $describedObject)
+ {
+ $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
+ $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
+ $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch())));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php
new file mode 100644
index 0000000..943ea29
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\JsonDescriptor;
+
+class JsonDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new JsonDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'json';
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php
new file mode 100644
index 0000000..c85e8a5
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+
+class MarkdownDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new MarkdownDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'md';
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
new file mode 100644
index 0000000..a3c49d7
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
@@ -0,0 +1,74 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand2;
+
+/**
+ * @author Jean-François Simon
+ */
+class ObjectsProvider
+{
+ public static function getInputArguments()
+ {
+ return array(
+ 'input_argument_1' => new InputArgument('argument_name', InputArgument::REQUIRED),
+ 'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'),
+ 'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
+ );
+ }
+
+ public static function getInputOptions()
+ {
+ return array(
+ 'input_option_1' => new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+ 'input_option_2' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', 'default_value'),
+ 'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'),
+ 'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
+ );
+ }
+
+ public static function getInputDefinitions()
+ {
+ return array(
+ 'input_definition_1' => new InputDefinition(),
+ 'input_definition_2' => new InputDefinition(array(new InputArgument('argument_name', InputArgument::REQUIRED))),
+ 'input_definition_3' => new InputDefinition(array(new InputOption('option_name', 'o', InputOption::VALUE_NONE))),
+ 'input_definition_4' => new InputDefinition(array(
+ new InputArgument('argument_name', InputArgument::REQUIRED),
+ new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+ )),
+ );
+ }
+
+ public static function getCommands()
+ {
+ return array(
+ 'command_1' => new DescriptorCommand1(),
+ 'command_2' => new DescriptorCommand2(),
+ );
+ }
+
+ public static function getApplications()
+ {
+ return array(
+ 'application_1' => new DescriptorApplication1(),
+ 'application_2' => new DescriptorApplication2(),
+ );
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php
new file mode 100644
index 0000000..350b679
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+
+class TextDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new TextDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'txt';
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php
new file mode 100644
index 0000000..59a5d1e
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+
+class XmlDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new XmlDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'xml';
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php
new file mode 100644
index 0000000..52b619e
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php
@@ -0,0 +1,11 @@
+setName('bar:buc');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php
new file mode 100644
index 0000000..132b6d5
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php
@@ -0,0 +1,18 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication1 extends Application
+{
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php
new file mode 100644
index 0000000..ff55135
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication2 extends Application
+{
+ public function __construct()
+ {
+ parent::__construct('My Symfony application', 'v1.0');
+ $this->add(new DescriptorCommand1());
+ $this->add(new DescriptorCommand2());
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php
new file mode 100644
index 0000000..ede05d7
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+
+class DescriptorCommand1 extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('descriptor:command1')
+ ->setAliases(array('alias1', 'alias2'))
+ ->setDescription('command 1 description')
+ ->setHelp('command 1 help')
+ ;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php
new file mode 100644
index 0000000..bc04ca9
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class DescriptorCommand2 extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('descriptor:command2')
+ ->setDescription('command 2 description')
+ ->setHelp('command 2 help')
+ ->addArgument('argument_name', InputArgument::REQUIRED)
+ ->addOption('option_name', 'o', InputOption::VALUE_NONE)
+ ;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php
new file mode 100644
index 0000000..254162f
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php
@@ -0,0 +1,26 @@
+setName('foo:bar1')
+ ->setDescription('The foo:bar1 command')
+ ->setAliases(array('afoobar1'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php
new file mode 100644
index 0000000..8071dc8
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php
@@ -0,0 +1,21 @@
+setName('foo1:bar')
+ ->setDescription('The foo1:bar command')
+ ->setAliases(array('afoobar2'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php
new file mode 100644
index 0000000..43a3507
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php
@@ -0,0 +1,29 @@
+setName('foo3:bar')
+ ->setDescription('The foo3:bar command')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ try {
+ try {
+ throw new \Exception("First exception this is html
");
+ } catch (\Exception $e) {
+ throw new \Exception("Second exception comment", 0, $e);
+ }
+ } catch (\Exception $e) {
+ throw new \Exception("Third exception comment>", 0, $e);
+ }
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php
new file mode 100644
index 0000000..1c54639
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php
@@ -0,0 +1,11 @@
+setName('foo3:bar:toh');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php
new file mode 100644
index 0000000..a1c6082
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php
@@ -0,0 +1,10 @@
+setName('foo:bar')
+ ->setDescription('The foo:bar command')
+ ->setAliases(array('afoobar'))
+ ;
+ }
+
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('interact called');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+
+ $output->writeln('called');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php
new file mode 100644
index 0000000..9681628
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php
@@ -0,0 +1,25 @@
+setName('foobar:foo')
+ ->setDescription('The foobar:foo command')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php
new file mode 100644
index 0000000..dcd3273
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php
@@ -0,0 +1,28 @@
+setName('namespace:name')
+ ->setAliases(array('name'))
+ ->setDescription('description')
+ ->setHelp('help')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('execute called');
+ }
+
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('interact called');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json
new file mode 100644
index 0000000..09adbd4
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json
@@ -0,0 +1 @@
+{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":"txt"}}}}],"namespaces":[{"id":"_global","commands":["help","list"]}]}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md
new file mode 100644
index 0000000..a789251
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md
@@ -0,0 +1,199 @@
+UNKNOWN
+=======
+
+* help
+* list
+
+help
+----
+
+* Description: Displays help for a command
+* Usage: `help [--xml] [--format="..."] [--raw] [command_name]`
+* Aliases:
+
+The help command displays help for a given command:
+
+ php app/console help list
+
+You can also output the help in other formats by using the --format option:
+
+ php app/console help --format=xml list
+
+To display the list of available commands, please use the list command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output help as XML
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output help in other formats
+* Default: `'txt'`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage: `list [--xml] [--raw] [--format="..."] [namespace]`
+* Aliases:
+
+The list command lists all commands:
+
+ php app/console list
+
+You can also display the commands for a specific namespace:
+
+ php app/console list test
+
+You can also output the information in other formats by using the --format option:
+
+ php app/console list --format=xml
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php app/console list --raw
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output list as XML
+* Default: `false`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output list in other formats
+* Default: `'txt'`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt
new file mode 100644
index 0000000..24ab4a0
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt
@@ -0,0 +1,17 @@
+Console Tool
+
+Usage:
+ [options] command [arguments]
+
+Options:
+ --help -h Display this help message.
+ --quiet -q Do not output any message.
+ --verbose -v|vv|vvv Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version -V Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction -n Do not ask any interactive question.
+
+Available commands:
+ help Displays help for a command
+ list Lists commands
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml
new file mode 100644
index 0000000..bfe5de0
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml
@@ -0,0 +1,108 @@
+
+
+
+
+ help [--xml] [--format="..."] [--raw] [command_name]
+ Displays help for a command
+ The <info>help</info> command displays help for a given command:
+
+ <info>php app/console help list</info>
+
+ You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console help --format=xml list</info>
+
+ To display the list of available commands, please use the <info>list</info> command.
+
+
+
+ The command name
+
+ help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ list [--xml] [--raw] [--format="..."] [namespace]
+ Lists commands
+ The <info>list</info> command lists all commands:
+
+ <info>php app/console list</info>
+
+ You can also display the commands for a specific namespace:
+
+ <info>php app/console list test</info>
+
+ You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console list --format=xml</info>
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php app/console list --raw</info>
+
+
+
+ The namespace name
+
+
+
+
+
+
+
+
+
+
+
+
+ help
+ list
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json
new file mode 100644
index 0000000..27745c1
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json
@@ -0,0 +1 @@
+{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":"txt"}}}},{"name":"descriptor:command1","usage":"descriptor:command1","description":"command 1 description","help":"command 1 help","aliases":["alias1","alias2"],"definition":{"arguments":[],"options":{"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"descriptor:command2","usage":"descriptor:command2 [-o|--option_name] argument_name","description":"command 2 description","help":"command 2 help","aliases":[],"definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}}],"namespaces":[{"id":"_global","commands":["alias1","alias2","help","list"]},{"id":"descriptor","commands":["descriptor:command1","descriptor:command2"]}]}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md
new file mode 100644
index 0000000..e52ecd3
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md
@@ -0,0 +1,388 @@
+My Symfony application
+======================
+
+* alias1
+* alias2
+* help
+* list
+
+**descriptor:**
+
+* descriptor:command1
+* descriptor:command2
+
+help
+----
+
+* Description: Displays help for a command
+* Usage: `help [--xml] [--format="..."] [--raw] [command_name]`
+* Aliases:
+
+The help command displays help for a given command:
+
+ php app/console help list
+
+You can also output the help in other formats by using the --format option:
+
+ php app/console help --format=xml list
+
+To display the list of available commands, please use the list command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output help as XML
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output help in other formats
+* Default: `'txt'`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage: `list [--xml] [--raw] [--format="..."] [namespace]`
+* Aliases:
+
+The list command lists all commands:
+
+ php app/console list
+
+You can also display the commands for a specific namespace:
+
+ php app/console list test
+
+You can also output the information in other formats by using the --format option:
+
+ php app/console list --format=xml
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php app/console list --raw
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output list as XML
+* Default: `false`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output list in other formats
+* Default: `'txt'`
+
+descriptor:command1
+-------------------
+
+* Description: command 1 description
+* Usage: `descriptor:command1`
+* Aliases: `alias1`, `alias2`
+
+command 1 help
+
+### Options:
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`
+
+descriptor:command2
+-------------------
+
+* Description: command 2 description
+* Usage: `descriptor:command2 [-o|--option_name] argument_name`
+* Aliases:
+
+command 2 help
+
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description:
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description:
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt
new file mode 100644
index 0000000..78580d0
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt
@@ -0,0 +1,22 @@
+My Symfony application version v1.0
+
+Usage:
+ [options] command [arguments]
+
+Options:
+ --help -h Display this help message.
+ --quiet -q Do not output any message.
+ --verbose -v|vv|vvv Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version -V Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction -n Do not ask any interactive question.
+
+Available commands:
+ alias1 command 1 description
+ alias2 command 1 description
+ help Displays help for a command
+ list Lists commands
+descriptor
+ descriptor:command1 command 1 description
+ descriptor:command2 command 2 description
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml
new file mode 100644
index 0000000..9fc3a21
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml
@@ -0,0 +1,185 @@
+
+
+
+
+ help [--xml] [--format="..."] [--raw] [command_name]
+ Displays help for a command
+ The <info>help</info> command displays help for a given command:
+
+ <info>php app/console help list</info>
+
+ You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console help --format=xml list</info>
+
+ To display the list of available commands, please use the <info>list</info> command.
+
+
+
+ The command name
+
+ help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ list [--xml] [--raw] [--format="..."] [namespace]
+ Lists commands
+ The <info>list</info> command lists all commands:
+
+ <info>php app/console list</info>
+
+ You can also display the commands for a specific namespace:
+
+ <info>php app/console list test</info>
+
+ You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console list --format=xml</info>
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php app/console list --raw</info>
+
+
+
+ The namespace name
+
+
+
+
+
+
+
+
+
+
+ descriptor:command1
+ command 1 description
+ command 1 help
+
+ alias1
+ alias2
+
+
+
+
+
+
+
+
+
+
+
+
+
+ descriptor:command2 [-o|--option_name] argument_name
+ command 2 description
+ command 2 help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ alias1
+ alias2
+ help
+ list
+
+
+ descriptor:command1
+ descriptor:command2
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt
new file mode 100644
index 0000000..dca37e2
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt
@@ -0,0 +1,20 @@
+Console Tool
+
+Usage:
+ [options] command [arguments]
+
+Options:
+ --help -h Display this help message.
+ --quiet -q Do not output any message.
+ --verbose -v|vv|vvv Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version -V Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction -n Do not ask any interactive question.
+
+Available commands:
+ afoobar The foo:bar command
+ help Displays help for a command
+ list Lists commands
+foo
+ foo:bar The foo:bar command
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt
new file mode 100644
index 0000000..827c406
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt
@@ -0,0 +1,16 @@
+Console Tool
+
+Usage:
+ [options] command [arguments]
+
+Options:
+ --help -h Display this help message.
+ --quiet -q Do not output any message.
+ --verbose -v|vv|vvv Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version -V Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction -n Do not ask any interactive question.
+
+Available commands for the "foo" namespace:
+ foo:bar The foo:bar command
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt
new file mode 100644
index 0000000..94a6863
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt
@@ -0,0 +1,144 @@
+
+
+
+
+ help [--xml] [--format="..."] [--raw] [command_name]
+ Displays help for a command
+ The <info>help</info> command displays help for a given command:
+
+ <info>php app/console help list</info>
+
+ You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console help --format=xml list</info>
+
+ To display the list of available commands, please use the <info>list</info> command.
+
+
+
+ The command name
+
+ help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ list [--xml] [--raw] [--format="..."] [namespace]
+ Lists commands
+ The <info>list</info> command lists all commands:
+
+ <info>php app/console list</info>
+
+ You can also display the commands for a specific namespace:
+
+ <info>php app/console list test</info>
+
+ You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console list --format=xml</info>
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php app/console list --raw</info>
+
+
+
+ The namespace name
+
+
+
+
+
+
+
+
+
+
+ foo:bar
+ The foo:bar command
+
+
+ afoobar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ afoobar
+ help
+ list
+
+
+ foo:bar
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt
new file mode 100644
index 0000000..5d61d2a
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt
@@ -0,0 +1,37 @@
+
+
+
+
+ foo:bar
+ The foo:bar command
+
+
+ afoobar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt
new file mode 100644
index 0000000..79c36f9
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt
@@ -0,0 +1,13 @@
+Console Tool
+
+Usage:
+ [options] command [arguments]
+
+Options:
+ --help -h Display this help message.
+ --quiet -q Do not output any message.
+ --verbose -v|vv|vvv Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version -V Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction -n Do not ask any interactive question.
\ No newline at end of file
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt
new file mode 100644
index 0000000..4629345
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt
@@ -0,0 +1,8 @@
+
+
+
+ [InvalidArgumentException]
+ Command "foo" is not defined.
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt
new file mode 100644
index 0000000..c758129
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt
@@ -0,0 +1,11 @@
+
+
+
+ [InvalidArgumentException]
+ The "--foo" option does not exist.
+
+
+
+list [--xml] [--raw] [--format="..."] [namespace]
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt
new file mode 100644
index 0000000..72a7286
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt
@@ -0,0 +1,27 @@
+
+
+
+ [Exception]
+ Third exception comment
+
+
+
+
+
+
+ [Exception]
+ Second exception comment
+
+
+
+
+
+
+ [Exception]
+ First exception this is html
+
+
+
+foo3:bar
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt
new file mode 100644
index 0000000..4bdcd77
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt
@@ -0,0 +1,27 @@
+
+
+[37;41m [0m
+[37;41m [Exception] [0m
+[37;41m Third exception [0m[34;41mcomment[0m[37;41m [0m
+[37;41m [0m
+
+
+
+
+[37;41m [0m
+[37;41m [Exception] [0m
+[37;41m Second exception [0m[33mcomment[0m[37;41m [0m
+[37;41m [0m
+
+
+
+
+[37;41m [0m
+[37;41m [Exception] [0m
+[37;41m First exception [0m[37;41m[0m[37;41mthis is html[0m[37;41m
[0m[37;41m [0m
+[37;41m [0m
+
+
+[32mfoo3:bar[0m
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt
new file mode 100644
index 0000000..19f893b
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt
@@ -0,0 +1,9 @@
+
+
+
+ [InvalidArgumentException]
+ Command "foo" is not define
+ d.
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt
new file mode 100644
index 0000000..6a98660
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt
@@ -0,0 +1,11 @@
+
+
+
+ [Exception]
+ エラーメッセージ
+
+
+
+foo
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt
new file mode 100644
index 0000000..c68a60f
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt
@@ -0,0 +1,11 @@
+
+
+[37;41m [0m
+[37;41m [Exception] [0m
+[37;41m エラーメッセージ [0m
+[37;41m [0m
+
+
+[32mfoo[0m
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt
new file mode 100644
index 0000000..545cd7b0
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt
@@ -0,0 +1,12 @@
+
+
+
+ [Exception]
+ コマンドの実行中にエラーが
+ 発生しました。
+
+
+
+foo
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt
new file mode 100644
index 0000000..5e9554f
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt
@@ -0,0 +1,17 @@
+Console Tool
+
+Usage:
+ [options] command [arguments]
+
+Options:
+ --help -h Display this help message.
+ --quiet -q Do not output any message.
+ --verbose -v|vv|vvv Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version -V Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction -n Do not ask any interactive question.
+
+Available commands:
+ help Displays help for a command
+ list Lists commands
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt
new file mode 100644
index 0000000..33c2442
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt
@@ -0,0 +1,29 @@
+Usage:
+ help [--xml] [--format="..."] [--raw] [command_name]
+
+Arguments:
+ command The command to execute
+ command_name The command name (default: "help")
+
+Options:
+ --xml To output help as XML
+ --format To output help in other formats (default: "txt")
+ --raw To output raw command help
+ --help (-h) Display this help message.
+ --quiet (-q) Do not output any message.
+ --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version (-V) Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction (-n) Do not ask any interactive question.
+
+Help:
+ The help command displays help for a given command:
+
+ php app/console help list
+
+ You can also output the help in other formats by using the --format option:
+
+ php app/console help --format=xml list
+
+ To display the list of available commands, please use the list command.
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt
new file mode 100644
index 0000000..0139775
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt
@@ -0,0 +1,27 @@
+Usage:
+ list [--xml] [--raw] [--format="..."] [namespace]
+
+Arguments:
+ namespace The namespace name
+
+Options:
+ --xml To output list as XML
+ --raw To output raw command list
+ --format To output list in other formats (default: "txt")
+
+Help:
+ The list command lists all commands:
+
+ php app/console list
+
+ You can also display the commands for a specific namespace:
+
+ php app/console list test
+
+ You can also output the information in other formats by using the --format option:
+
+ php app/console list --format=xml
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php app/console list --raw
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt
new file mode 100644
index 0000000..47187fc
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt
@@ -0,0 +1 @@
+Console Tool
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json
new file mode 100644
index 0000000..0c1675d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json
@@ -0,0 +1 @@
+{"name":"descriptor:command1","usage":"descriptor:command1","description":"command 1 description","help":"command 1 help","aliases":["alias1","alias2"],"definition":{"arguments":[],"options":[]}}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md
new file mode 100644
index 0000000..2cef9a2
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md
@@ -0,0 +1,8 @@
+descriptor:command1
+-------------------
+
+* Description: command 1 description
+* Usage: `descriptor:command1`
+* Aliases: `alias1`, `alias2`
+
+command 1 help
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt
new file mode 100644
index 0000000..2375ac0
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt
@@ -0,0 +1,7 @@
+Usage:
+ descriptor:command1
+
+Aliases: alias1, alias2
+
+Help:
+ command 1 help
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml
new file mode 100644
index 0000000..dcfa6fa
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml
@@ -0,0 +1,12 @@
+
+
+ descriptor:command1
+ command 1 description
+ command 1 help
+
+ alias1
+ alias2
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json
new file mode 100644
index 0000000..493b584
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json
@@ -0,0 +1 @@
+{"name":"descriptor:command2","usage":"descriptor:command2 [-o|--option_name] argument_name","description":"command 2 description","help":"command 2 help","aliases":[],"definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md
new file mode 100644
index 0000000..5257c0d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md
@@ -0,0 +1,30 @@
+descriptor:command2
+-------------------
+
+* Description: command 2 description
+* Usage: `descriptor:command2 [-o|--option_name] argument_name`
+* Aliases:
+
+command 2 help
+
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description:
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description:
+* Default: `false`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt
new file mode 100644
index 0000000..1da9f3d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt
@@ -0,0 +1,11 @@
+Usage:
+ descriptor:command2 [-o|--option_name] argument_name
+
+Arguments:
+ argument_name
+
+Options:
+ --option_name (-o)
+
+Help:
+ command 2 help
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml
new file mode 100644
index 0000000..c411c36
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml
@@ -0,0 +1,18 @@
+
+
+ descriptor:command2 [-o|--option_name] argument_name
+ command 2 description
+ command 2 help
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt
new file mode 100644
index 0000000..8b6c74c
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt
@@ -0,0 +1,18 @@
+Usage:
+ namespace:name
+
+Aliases: name
+Arguments:
+ command The command to execute
+
+Options:
+ --help (-h) Display this help message.
+ --quiet (-q) Do not output any message.
+ --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version (-V) Display this application version.
+ --ansi Force ANSI output.
+ --no-ansi Disable ANSI output.
+ --no-interaction (-n) Do not ask any interactive question.
+
+Help:
+ help
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt
new file mode 100644
index 0000000..4b0012d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt
@@ -0,0 +1,38 @@
+
+
+ namespace:name
+ description
+ help
+
+ name
+
+
+
+ The command to execute
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt
new file mode 100644
index 0000000..a7d7e0d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt
@@ -0,0 +1,11 @@
+Arguments:
+ foo The foo argument
+ baz The baz argument (default: true)
+ bar The bar argument (default: ["http://foo.com/"])
+
+Options:
+ --foo (-f) The foo option
+ --baz The baz option (default: false)
+ --bar (-b) The bar option (default: "bar")
+ --qux The qux option (default: ["http://foo.com/","bar"]) (multiple values allowed)
+ --qux2 The qux2 option (default: {"foo":"bar"}) (multiple values allowed)
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt
new file mode 100644
index 0000000..eec8c07
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt
@@ -0,0 +1,39 @@
+
+
+
+
+ The foo argument
+
+
+
+ The baz argument
+
+ true
+
+
+
+ The bar argument
+
+ bar
+
+
+
+
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json
new file mode 100644
index 0000000..b8173b6
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json
@@ -0,0 +1 @@
+{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md
new file mode 100644
index 0000000..88f311a
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md
@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description:
+* Default: `NULL`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt
new file mode 100644
index 0000000..111e515
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt
@@ -0,0 +1 @@
+ argument_name
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml
new file mode 100644
index 0000000..cb37f81
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json
new file mode 100644
index 0000000..ef06b09
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json
@@ -0,0 +1 @@
+{"name":"argument_name","is_required":false,"is_array":true,"description":"argument description","default":[]}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md
new file mode 100644
index 0000000..3cdb00c
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md
@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: no
+* Is array: yes
+* Description: argument description
+* Default: `array ()`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt
new file mode 100644
index 0000000..9497b1c
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt
@@ -0,0 +1 @@
+ argument_name argument description
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml
new file mode 100644
index 0000000..629da5a
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml
@@ -0,0 +1,5 @@
+
+
+ argument description
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json
new file mode 100644
index 0000000..de8484e
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json
@@ -0,0 +1 @@
+{"name":"argument_name","is_required":false,"is_array":false,"description":"argument description","default":"default_value"}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md
new file mode 100644
index 0000000..be1c443
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md
@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: no
+* Is array: no
+* Description: argument description
+* Default: `'default_value'`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt
new file mode 100644
index 0000000..c421fc9
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt
@@ -0,0 +1 @@
+ argument_name argument description (default: "default_value")
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml
new file mode 100644
index 0000000..399a5c8
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml
@@ -0,0 +1,7 @@
+
+
+ argument description
+
+ default_value
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json
new file mode 100644
index 0000000..c7a7d83
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json
@@ -0,0 +1 @@
+{"arguments":[],"options":[]}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml
new file mode 100644
index 0000000..b5481ce
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json
new file mode 100644
index 0000000..9964a55
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json
@@ -0,0 +1 @@
+{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":[]}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md
new file mode 100644
index 0000000..923191c
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md
@@ -0,0 +1,9 @@
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description:
+* Default: `NULL`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt
new file mode 100644
index 0000000..0db9f66
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt
@@ -0,0 +1,2 @@
+Arguments:
+ argument_name
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml
new file mode 100644
index 0000000..102efc1
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json
new file mode 100644
index 0000000..6a86056
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json
@@ -0,0 +1 @@
+{"arguments":[],"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md
new file mode 100644
index 0000000..40fd7b0
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md
@@ -0,0 +1,11 @@
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description:
+* Default: `false`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt
new file mode 100644
index 0000000..c6fb2cc
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt
@@ -0,0 +1,2 @@
+Options:
+ --option_name (-o)
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml
new file mode 100644
index 0000000..bc95151
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json
new file mode 100644
index 0000000..c5a0019
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json
@@ -0,0 +1 @@
+{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md
new file mode 100644
index 0000000..a31feea
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md
@@ -0,0 +1,21 @@
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description:
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description:
+* Default: `false`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt
new file mode 100644
index 0000000..e17c61c
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt
@@ -0,0 +1,5 @@
+Arguments:
+ argument_name
+
+Options:
+ --option_name (-o)
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml
new file mode 100644
index 0000000..cffceec
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json
new file mode 100644
index 0000000..60c5b56
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md
new file mode 100644
index 0000000..6f9e9a7
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description:
+* Default: `false`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt
new file mode 100644
index 0000000..daf83d0
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt
@@ -0,0 +1 @@
+ --option_name (-o)
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml
new file mode 100644
index 0000000..8a64ea6
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml
@@ -0,0 +1,4 @@
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json
new file mode 100644
index 0000000..04e4228
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":false,"description":"option description","default":"default_value"}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md
new file mode 100644
index 0000000..634ac0b
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: no
+* Is multiple: no
+* Description: option description
+* Default: `'default_value'`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt
new file mode 100644
index 0000000..627e3c1
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt
@@ -0,0 +1 @@
+ --option_name (-o) option description (default: "default_value")
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml
new file mode 100644
index 0000000..4afac5b
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml
@@ -0,0 +1,7 @@
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json
new file mode 100644
index 0000000..c1ea120
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"option description","default":null}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md
new file mode 100644
index 0000000..3428289
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: option description
+* Default: `NULL`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt
new file mode 100644
index 0000000..b88b12d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt
@@ -0,0 +1 @@
+ --option_name (-o) option description
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml
new file mode 100644
index 0000000..dcc0631
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json
new file mode 100644
index 0000000..1b671d8
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":true,"description":"option description","default":[]}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md
new file mode 100644
index 0000000..8ffba56
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: no
+* Is multiple: yes
+* Description: option description
+* Default: `array ()`
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt
new file mode 100644
index 0000000..5dba5e6
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt
@@ -0,0 +1 @@
+ --option_name (-o) option description (multiple values allowed)
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml
new file mode 100644
index 0000000..5e2418b
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php
new file mode 100644
index 0000000..774df26
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php
@@ -0,0 +1,70 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Formatter;
+
+use Symfony\Component\Console\Formatter\OutputFormatterStyleStack;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputFormatterStyleStackTest extends \PHPUnit_Framework_TestCase
+{
+ public function testPush()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
+ $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
+
+ $this->assertEquals($s2, $stack->getCurrent());
+
+ $stack->push($s3 = new OutputFormatterStyle('green', 'red'));
+
+ $this->assertEquals($s3, $stack->getCurrent());
+ }
+
+ public function testPop()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
+ $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
+
+ $this->assertEquals($s2, $stack->pop());
+ $this->assertEquals($s1, $stack->pop());
+ }
+
+ public function testPopEmpty()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $style = new OutputFormatterStyle();
+
+ $this->assertEquals($style, $stack->pop());
+ }
+
+ public function testPopNotLast()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
+ $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
+ $stack->push($s3 = new OutputFormatterStyle('green', 'red'));
+
+ $this->assertEquals($s2, $stack->pop($s2));
+ $this->assertEquals($s1, $stack->pop());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInvalidPop()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push(new OutputFormatterStyle('white', 'black'));
+ $stack->pop(new OutputFormatterStyle('yellow', 'blue'));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php
new file mode 100644
index 0000000..6890a9b
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php
@@ -0,0 +1,93 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Formatter;
+
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputFormatterStyleTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $style = new OutputFormatterStyle('green', 'black', array('bold', 'underscore'));
+ $this->assertEquals("\033[32;40;1;4mfoo\033[0m", $style->apply('foo'));
+
+ $style = new OutputFormatterStyle('red', null, array('blink'));
+ $this->assertEquals("\033[31;5mfoo\033[0m", $style->apply('foo'));
+
+ $style = new OutputFormatterStyle(null, 'white');
+ $this->assertEquals("\033[47mfoo\033[0m", $style->apply('foo'));
+ }
+
+ public function testForeground()
+ {
+ $style = new OutputFormatterStyle();
+
+ $style->setForeground('black');
+ $this->assertEquals("\033[30mfoo\033[0m", $style->apply('foo'));
+
+ $style->setForeground('blue');
+ $this->assertEquals("\033[34mfoo\033[0m", $style->apply('foo'));
+
+ $this->setExpectedException('InvalidArgumentException');
+ $style->setForeground('undefined-color');
+ }
+
+ public function testBackground()
+ {
+ $style = new OutputFormatterStyle();
+
+ $style->setBackground('black');
+ $this->assertEquals("\033[40mfoo\033[0m", $style->apply('foo'));
+
+ $style->setBackground('yellow');
+ $this->assertEquals("\033[43mfoo\033[0m", $style->apply('foo'));
+
+ $this->setExpectedException('InvalidArgumentException');
+ $style->setBackground('undefined-color');
+ }
+
+ public function testOptions()
+ {
+ $style = new OutputFormatterStyle();
+
+ $style->setOptions(array('reverse', 'conceal'));
+ $this->assertEquals("\033[7;8mfoo\033[0m", $style->apply('foo'));
+
+ $style->setOption('bold');
+ $this->assertEquals("\033[7;8;1mfoo\033[0m", $style->apply('foo'));
+
+ $style->unsetOption('reverse');
+ $this->assertEquals("\033[8;1mfoo\033[0m", $style->apply('foo'));
+
+ $style->setOption('bold');
+ $this->assertEquals("\033[8;1mfoo\033[0m", $style->apply('foo'));
+
+ $style->setOptions(array('bold'));
+ $this->assertEquals("\033[1mfoo\033[0m", $style->apply('foo'));
+
+ try {
+ $style->setOption('foo');
+ $this->fail('->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ }
+
+ try {
+ $style->unsetOption('foo');
+ $this->fail('->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ }
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
new file mode 100644
index 0000000..c8f0b98
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
@@ -0,0 +1,252 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Formatter;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputFormatterTest extends \PHPUnit_Framework_TestCase
+{
+ public function testEmptyTag()
+ {
+ $formatter = new OutputFormatter(true);
+ $this->assertEquals("foo<>bar", $formatter->format('foo<>bar'));
+ }
+
+ public function testLGCharEscaping()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals("fooformat('foo\\assertEquals("some info", $formatter->format('\\some info\\'));
+ $this->assertEquals("\\some info\\", OutputFormatter::escape('some info'));
+
+ $this->assertEquals(
+ "\033[33mSymfony\\Component\\Console does work very well!\033[0m",
+ $formatter->format('Symfony\Component\Console does work very well!')
+ );
+ }
+
+ public function testBundledStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertTrue($formatter->hasStyle('error'));
+ $this->assertTrue($formatter->hasStyle('info'));
+ $this->assertTrue($formatter->hasStyle('comment'));
+ $this->assertTrue($formatter->hasStyle('question'));
+
+ $this->assertEquals(
+ "\033[37;41msome error\033[0m",
+ $formatter->format('some error')
+ );
+ $this->assertEquals(
+ "\033[32msome info\033[0m",
+ $formatter->format('some info')
+ );
+ $this->assertEquals(
+ "\033[33msome comment\033[0m",
+ $formatter->format('some comment')
+ );
+ $this->assertEquals(
+ "\033[30;46msome question\033[0m",
+ $formatter->format('some question')
+ );
+ }
+
+ public function testNestedStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "\033[37;41msome \033[0m\033[32msome info\033[0m\033[37;41m error\033[0m",
+ $formatter->format('some some info error')
+ );
+ }
+
+ public function testAdjacentStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "\033[37;41msome error\033[0m\033[32msome info\033[0m",
+ $formatter->format('some errorsome info')
+ );
+ }
+
+ public function testStyleMatchingNotGreedy()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "(\033[32m>=2.0,<2.3\033[0m)",
+ $formatter->format('(>=2.0,<2.3)')
+ );
+ }
+
+ public function testStyleEscaping()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "(\033[32mz>=2.0,format('('.$formatter->escape('z>=2.0,)')
+ );
+ }
+
+ public function testDeepNestedStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "\033[37;41merror\033[0m\033[32minfo\033[0m\033[33mcomment\033[0m\033[37;41merror\033[0m",
+ $formatter->format('errorinfocommenterror')
+ );
+ }
+
+ public function testNewStyle()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $style = new OutputFormatterStyle('blue', 'white');
+ $formatter->setStyle('test', $style);
+
+ $this->assertEquals($style, $formatter->getStyle('test'));
+ $this->assertNotEquals($style, $formatter->getStyle('info'));
+
+ $style = new OutputFormatterStyle('blue', 'white');
+ $formatter->setStyle('b', $style);
+
+ $this->assertEquals("\033[34;47msome \033[0m\033[34;47mcustom\033[0m\033[34;47m msg\033[0m", $formatter->format('some custom msg'));
+ }
+
+ public function testRedefineStyle()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $style = new OutputFormatterStyle('blue', 'white');
+ $formatter->setStyle('info', $style);
+
+ $this->assertEquals("\033[34;47msome custom msg\033[0m", $formatter->format('some custom msg'));
+ }
+
+ public function testInlineStyle()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals("\033[34;41msome text\033[0m", $formatter->format('some text>'));
+ $this->assertEquals("\033[34;41msome text\033[0m", $formatter->format('some text'));
+ }
+
+ public function testNonStyleTag()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals("\033[32msome \033[0m\033[32m\033[0m\033[32m styled \033[0m\033[32m\033[0m\033[32msingle-char tag\033[0m\033[32m
\033[0m", $formatter->format('some styled single-char tag
'));
+ }
+
+ public function testFormatLongString()
+ {
+ $formatter = new OutputFormatter(true);
+ $long = str_repeat("\\", 14000);
+ $this->assertEquals("\033[37;41msome error\033[0m".$long, $formatter->format('some error'.$long));
+ }
+
+ public function testNotDecoratedFormatter()
+ {
+ $formatter = new OutputFormatter(false);
+
+ $this->assertTrue($formatter->hasStyle('error'));
+ $this->assertTrue($formatter->hasStyle('info'));
+ $this->assertTrue($formatter->hasStyle('comment'));
+ $this->assertTrue($formatter->hasStyle('question'));
+
+ $this->assertEquals(
+ "some error", $formatter->format('some error')
+ );
+ $this->assertEquals(
+ "some info", $formatter->format('some info')
+ );
+ $this->assertEquals(
+ "some comment", $formatter->format('some comment')
+ );
+ $this->assertEquals(
+ "some question", $formatter->format('some question')
+ );
+
+ $formatter->setDecorated(true);
+
+ $this->assertEquals(
+ "\033[37;41msome error\033[0m", $formatter->format('some error')
+ );
+ $this->assertEquals(
+ "\033[32msome info\033[0m", $formatter->format('some info')
+ );
+ $this->assertEquals(
+ "\033[33msome comment\033[0m", $formatter->format('some comment')
+ );
+ $this->assertEquals(
+ "\033[30;46msome question\033[0m", $formatter->format('some question')
+ );
+ }
+
+ public function testContentWithLineBreaks()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(<<format(<<
+some text
+EOF
+ ));
+
+ $this->assertEquals(<<format(<<some text
+
+EOF
+ ));
+
+ $this->assertEquals(<<format(<<
+some text
+
+EOF
+ ));
+
+ $this->assertEquals(<<format(<<
+some text
+more text
+
+EOF
+ ));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php
new file mode 100644
index 0000000..5364f38
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php
@@ -0,0 +1,192 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Helper\DialogHelper;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class DialogHelperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testSelect()
+ {
+ $dialog = new DialogHelper();
+
+ $helperSet = new HelperSet(array(new FormatterHelper()));
+ $dialog->setHelperSet($helperSet);
+
+ $heroes = array('Superman', 'Batman', 'Spiderman');
+
+ $dialog->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n"));
+ $this->assertEquals('2', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '2'));
+ $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
+ $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
+ $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false));
+
+ rewind($output->getStream());
+ $this->assertContains('Input "Fabien" is not a superhero!', stream_get_contents($output->getStream()));
+
+ try {
+ $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, 1));
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
+ }
+
+ $this->assertEquals(array('1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '0,1', false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, ' 0 , 1 ', false, 'Input "%s" is not a superhero!', true));
+ }
+
+ public function testAsk()
+ {
+ $dialog = new DialogHelper();
+
+ $dialog->setInputStream($this->getInputStream("\n8AM\n"));
+
+ $this->assertEquals('2PM', $dialog->ask($this->getOutputStream(), 'What time is it?', '2PM'));
+ $this->assertEquals('8AM', $dialog->ask($output = $this->getOutputStream(), 'What time is it?', '2PM'));
+
+ rewind($output->getStream());
+ $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
+ }
+
+ public function testAskWithAutocomplete()
+ {
+ if (!$this->hasSttyAvailable()) {
+ $this->markTestSkipped('`stty` is required to test autocomplete functionality');
+ }
+
+ // Acm
+ // AcsTest
+ //
+ //
+ // Test
+ //
+ // S
+ // F00oo
+ $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
+
+ $dialog = new DialogHelper();
+ $dialog->setInputStream($inputStream);
+
+ $bundles = array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle');
+
+ $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('AsseticBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('FrameworkBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('SecurityBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('FooBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('AsseticBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('FooBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ }
+
+ /**
+ * @group tty
+ */
+ public function testAskHiddenResponse()
+ {
+ if (defined('PHP_WINDOWS_VERSION_BUILD')) {
+ $this->markTestSkipped('This test is not supported on Windows');
+ }
+
+ $dialog = new DialogHelper();
+
+ $dialog->setInputStream($this->getInputStream("8AM\n"));
+
+ $this->assertEquals('8AM', $dialog->askHiddenResponse($this->getOutputStream(), 'What time is it?'));
+ }
+
+ public function testAskConfirmation()
+ {
+ $dialog = new DialogHelper();
+
+ $dialog->setInputStream($this->getInputStream("\n\n"));
+ $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?'));
+ $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
+
+ $dialog->setInputStream($this->getInputStream("y\nyes\n"));
+ $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
+ $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
+
+ $dialog->setInputStream($this->getInputStream("n\nno\n"));
+ $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
+ $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
+ }
+
+ public function testAskAndValidate()
+ {
+ $dialog = new DialogHelper();
+ $helperSet = new HelperSet(array(new FormatterHelper()));
+ $dialog->setHelperSet($helperSet);
+
+ $question ='What color was the white horse of Henry IV?';
+ $error = 'This is not a color!';
+ $validator = function ($color) use ($error) {
+ if (!in_array($color, array('white', 'black'))) {
+ throw new \InvalidArgumentException($error);
+ }
+
+ return $color;
+ };
+
+ $dialog->setInputStream($this->getInputStream("\nblack\n"));
+ $this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
+ $this->assertEquals('black', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
+
+ $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
+ try {
+ $this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals($error, $e->getMessage());
+ }
+ }
+
+ public function testNoInteraction()
+ {
+ $dialog = new DialogHelper();
+
+ $input = new ArrayInput(array());
+ $input->setInteractive(false);
+
+ $dialog->setInput($input);
+
+ $this->assertEquals('not yet', $dialog->ask($this->getOutputStream(), 'Do you have a job?', 'not yet'));
+ }
+
+ protected function getInputStream($input)
+ {
+ $stream = fopen('php://memory', 'r+', false);
+ fputs($stream, $input);
+ rewind($stream);
+
+ return $stream;
+ }
+
+ protected function getOutputStream()
+ {
+ return new StreamOutput(fopen('php://memory', 'r+', false));
+ }
+
+ private function hasSttyAvailable()
+ {
+ exec('stty 2>&1', $output, $exitcode);
+
+ return $exitcode === 0;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php
new file mode 100644
index 0000000..db61de4
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php
@@ -0,0 +1,99 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\FormatterHelper;
+
+class FormatterHelperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testFormatSection()
+ {
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ '[cli] Some text to display',
+ $formatter->formatSection('cli', 'Some text to display'),
+ '::formatSection() formats a message in a section'
+ );
+ }
+
+ public function testFormatBlock()
+ {
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ ' Some text to display ',
+ $formatter->formatBlock('Some text to display', 'error'),
+ '::formatBlock() formats a message in a block'
+ );
+
+ $this->assertEquals(
+ ' Some text to display '."\n" .
+ ' foo bar ',
+ $formatter->formatBlock(array('Some text to display', 'foo bar'), 'error'),
+ '::formatBlock() formats a message in a block'
+ );
+
+ $this->assertEquals(
+ ' '."\n" .
+ ' Some text to display '."\n" .
+ ' ',
+ $formatter->formatBlock('Some text to display', 'error', true),
+ '::formatBlock() formats a message in a block'
+ );
+ }
+
+ public function testFormatBlockWithDiacriticLetters()
+ {
+ if (!function_exists('mb_detect_encoding')) {
+ $this->markTestSkipped('This test requires mbstring to work.');
+ }
+
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ ' '."\n" .
+ ' Du texte à afficher '."\n" .
+ ' ',
+ $formatter->formatBlock('Du texte à afficher', 'error', true),
+ '::formatBlock() formats a message in a block'
+ );
+ }
+
+ public function testFormatBlockWithDoubleWidthDiacriticLetters()
+ {
+ if (!extension_loaded('mbstring')) {
+ $this->markTestSkipped('This test requires mbstring to work.');
+ }
+ $formatter = new FormatterHelper();
+ $this->assertEquals(
+ ' '."\n" .
+ ' 表示するテキスト '."\n" .
+ ' ',
+ $formatter->formatBlock('表示するテキスト', 'error', true),
+ '::formatBlock() formats a message in a block'
+ );
+ }
+
+ public function testFormatBlockLGEscaping()
+ {
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ ' '."\n" .
+ ' \some info\ '."\n" .
+ ' ',
+ $formatter->formatBlock('some info', 'error', true),
+ '::formatBlock() escapes \'<\' chars'
+ );
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php
new file mode 100644
index 0000000..a6ccde2
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php
@@ -0,0 +1,153 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Command\Command;
+
+class HelperSetTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::__construct
+ */
+ public function testConstructor()
+ {
+ $mock_helper = $this->getGenericMockHelper('fake_helper');
+ $helperset = new HelperSet(array('fake_helper_alias' => $mock_helper));
+
+ $this->assertEquals($mock_helper, $helperset->get('fake_helper_alias'), '__construct sets given helper to helpers');
+ $this->assertTrue($helperset->has('fake_helper_alias'), '__construct sets helper alias for given helper');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::set
+ */
+ public function testSet()
+ {
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper', $helperset));
+ $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper to helpers');
+
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
+ $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));
+ $this->assertTrue($helperset->has('fake_helper_01'), '->set() will set multiple helpers on consecutive calls');
+ $this->assertTrue($helperset->has('fake_helper_02'), '->set() will set multiple helpers on consecutive calls');
+
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper', $helperset), 'fake_helper_alias');
+ $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper alias when set');
+ $this->assertTrue($helperset->has('fake_helper_alias'), '->set() adds helper alias when set');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::has
+ */
+ public function testHas()
+ {
+ $helperset = new HelperSet(array('fake_helper_alias' => $this->getGenericMockHelper('fake_helper')));
+ $this->assertTrue($helperset->has('fake_helper'), '->has() finds set helper');
+ $this->assertTrue($helperset->has('fake_helper_alias'), '->has() finds set helper by alias');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::get
+ */
+ public function testGet()
+ {
+ $helper_01 = $this->getGenericMockHelper('fake_helper_01');
+ $helper_02 = $this->getGenericMockHelper('fake_helper_02');
+ $helperset = new HelperSet(array('fake_helper_01_alias' => $helper_01, 'fake_helper_02_alias' => $helper_02));
+ $this->assertEquals($helper_01, $helperset->get('fake_helper_01'), '->get() returns correct helper by name');
+ $this->assertEquals($helper_01, $helperset->get('fake_helper_01_alias'), '->get() returns correct helper by alias');
+ $this->assertEquals($helper_02, $helperset->get('fake_helper_02'), '->get() returns correct helper by name');
+ $this->assertEquals($helper_02, $helperset->get('fake_helper_02_alias'), '->get() returns correct helper by alias');
+
+ $helperset = new HelperSet();
+ try {
+ $helperset->get('foo');
+ $this->fail('->get() throws \InvalidArgumentException when helper not found');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws \InvalidArgumentException when helper not found');
+ $this->assertContains('The helper "foo" is not defined.', $e->getMessage(), '->get() throws \InvalidArgumentException when helper not found');
+ }
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::setCommand
+ */
+ public function testSetCommand()
+ {
+ $cmd_01 = new Command('foo');
+ $cmd_02 = new Command('bar');
+
+ $helperset = new HelperSet();
+ $helperset->setCommand($cmd_01);
+ $this->assertEquals($cmd_01, $helperset->getCommand(), '->setCommand() stores given command');
+
+ $helperset = new HelperSet();
+ $helperset->setCommand($cmd_01);
+ $helperset->setCommand($cmd_02);
+ $this->assertEquals($cmd_02, $helperset->getCommand(), '->setCommand() overwrites stored command with consecutive calls');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::getCommand
+ */
+ public function testGetCommand()
+ {
+ $cmd = new Command('foo');
+ $helperset = new HelperSet();
+ $helperset->setCommand($cmd);
+ $this->assertEquals($cmd, $helperset->getCommand(), '->getCommand() retrieves stored command');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::getIterator
+ */
+ public function testIteration()
+ {
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
+ $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));
+
+ $helpers = array('fake_helper_01', 'fake_helper_02');
+ $i = 0;
+
+ foreach ($helperset as $helper) {
+ $this->assertEquals($helpers[$i++], $helper->getName());
+ }
+ }
+
+ /**
+ * Create a generic mock for the helper interface. Optionally check for a call to setHelperSet with a specific
+ * helperset instance.
+ *
+ * @param string $name
+ * @param HelperSet $helperset allows a mock to verify a particular helperset set is being added to the Helper
+ */
+ private function getGenericMockHelper($name, HelperSet $helperset = null)
+ {
+ $mock_helper = $this->getMock('\Symfony\Component\Console\Helper\HelperInterface');
+ $mock_helper->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue($name));
+
+ if ($helperset) {
+ $mock_helper->expects($this->any())
+ ->method('setHelperSet')
+ ->with($this->equalTo($helperset));
+ }
+
+ return $mock_helper;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressHelperTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressHelperTest.php
new file mode 100644
index 0000000..40d856f
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressHelperTest.php
@@ -0,0 +1,214 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\ProgressHelper;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class ProgressHelperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testAdvance()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 1 [->--------------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testAdvanceWithStep()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->advance(5);
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 5 [----->----------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testAdvanceMultipleTimes()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->advance(3);
+ $progress->advance(2);
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 3 [--->------------------------]').$this->generateOutput(' 5 [----->----------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testCustomizations()
+ {
+ $progress = new ProgressHelper();
+ $progress->setBarWidth(10);
+ $progress->setBarCharacter('_');
+ $progress->setEmptyBarCharacter(' ');
+ $progress->setProgressCharacter('/');
+ $progress->setFormat(' %current%/%max% [%bar%] %percent%%');
+ $progress->start($output = $this->getOutputStream(), 10);
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 1/10 [_/ ] 10%'), stream_get_contents($output->getStream()));
+ }
+
+ public function testPercent()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->display();
+ $progress->advance();
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 0/50 [>---------------------------] 0%').$this->generateOutput(' 1/50 [>---------------------------] 2%').$this->generateOutput(' 2/50 [=>--------------------------] 4%'), stream_get_contents($output->getStream()));
+ }
+
+ public function testOverwriteWithShorterLine()
+ {
+ $progress = new ProgressHelper();
+ $progress->setFormat(' %current%/%max% [%bar%] %percent%%');
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->display();
+ $progress->advance();
+
+ // set shorter format
+ $progress->setFormat(' %current%/%max% [%bar%]');
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%') .
+ $this->generateOutput(' 1/50 [>---------------------------] 2%') .
+ $this->generateOutput(' 2/50 [=>--------------------------] '),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testSetCurrentProgress()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->display();
+ $progress->advance();
+ $progress->setCurrent(15);
+ $progress->setCurrent(25);
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%') .
+ $this->generateOutput(' 1/50 [>---------------------------] 2%') .
+ $this->generateOutput(' 15/50 [========>-------------------] 30%') .
+ $this->generateOutput(' 25/50 [==============>-------------] 50%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You must start the progress bar
+ */
+ public function testSetCurrentBeforeStarting()
+ {
+ $progress = new ProgressHelper();
+ $progress->setCurrent(15);
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You can't regress the progress bar
+ */
+ public function testRegressProgress()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->setCurrent(15);
+ $progress->setCurrent(10);
+ }
+
+ public function testRedrawFrequency()
+ {
+ $progress = $this->getMock('Symfony\Component\Console\Helper\ProgressHelper', array('display'));
+ $progress->expects($this->exactly(4))
+ ->method('display');
+
+ $progress->setRedrawFrequency(2);
+
+ $progress->start($output = $this->getOutputStream(), 6);
+ $progress->setCurrent(1);
+ $progress->advance(2);
+ $progress->advance(2);
+ $progress->advance(1);
+ }
+
+ public function testMultiByteSupport()
+ {
+ if (!function_exists('mb_strlen') || (false === $encoding = mb_detect_encoding('■'))) {
+ $this->markTestSkipped('The mbstring extension is needed for multi-byte support');
+ }
+
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->setBarCharacter('■');
+ $progress->advance(3);
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 3 [■■■>------------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testClear()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->setCurrent(25);
+ $progress->clear();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 25/50 [==============>-------------] 50%') . $this->generateOutput(''),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testPercentNotHundredBeforeComplete()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 200);
+ $progress->display();
+ $progress->advance(199);
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 0/200 [>---------------------------] 0%').$this->generateOutput(' 199/200 [===========================>] 99%').$this->generateOutput(' 200/200 [============================] 100%'), stream_get_contents($output->getStream()));
+ }
+
+ protected function getOutputStream()
+ {
+ return new StreamOutput(fopen('php://memory', 'r+', false));
+ }
+
+ protected $lastMessagesLength;
+
+ protected function generateOutput($expected)
+ {
+ $expectedout = $expected;
+
+ if ($this->lastMessagesLength !== null) {
+ $expectedout = str_pad($expected, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
+ }
+
+ $this->lastMessagesLength = strlen($expectedout);
+
+ return "\x0D".$expectedout;
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableHelperTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableHelperTest.php
new file mode 100644
index 0000000..f3cda0d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableHelperTest.php
@@ -0,0 +1,294 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\TableHelper;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class TableHelperTest extends \PHPUnit_Framework_TestCase
+{
+ protected $stream;
+
+ protected function setUp()
+ {
+ $this->stream = fopen('php://memory', 'r+');
+ }
+
+ protected function tearDown()
+ {
+ fclose($this->stream);
+ $this->stream = null;
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRender($headers, $rows, $layout, $expected)
+ {
+ $table = new TableHelper();
+ $table
+ ->setHeaders($headers)
+ ->setRows($rows)
+ ->setLayout($layout)
+ ;
+ $table->render($output = $this->getOutputStream());
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRenderAddRows($headers, $rows, $layout, $expected)
+ {
+ $table = new TableHelper();
+ $table
+ ->setHeaders($headers)
+ ->addRows($rows)
+ ->setLayout($layout)
+ ;
+ $table->render($output = $this->getOutputStream());
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRenderAddRowsOneByOne($headers, $rows, $layout, $expected)
+ {
+ $table = new TableHelper();
+ $table
+ ->setHeaders($headers)
+ ->setLayout($layout)
+ ;
+ foreach ($rows as $row) {
+ $table->addRow($row);
+ }
+ $table->render($output = $this->getOutputStream());
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testRenderProvider()
+ {
+ $books = array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
+ array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
+ array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
+ );
+
+ return array(
+ array(
+ array('ISBN', 'Title', 'Author'),
+ $books,
+ TableHelper::LAYOUT_DEFAULT,
+<< array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens>'),
+ ),
+ TableHelper::LAYOUT_DEFAULT,
+<< array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array('99921-58-10-700', 'Divine Com', 'Dante Alighieri'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
+ ),
+ TableHelper::LAYOUT_DEFAULT,
+<<99921-58-10-700 | Divine Com | Dante Alighieri |
+| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
++----------------------------------+----------------------+-----------------+
+
+TABLE
+ ),
+ );
+ }
+
+ public function testRenderMultiByte()
+ {
+ if (!function_exists('mb_strlen')) {
+ $this->markTestSkipped('The "mbstring" extension is not available');
+ }
+
+ $table = new TableHelper();
+ $table
+ ->setHeaders(array('■■'))
+ ->setRows(array(array(1234)))
+ ->setLayout(TableHelper::LAYOUT_DEFAULT)
+ ;
+ $table->render($output = $this->getOutputStream());
+
+ $expected =
+<<assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ protected function getOutputStream()
+ {
+ return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
+ }
+
+ protected function getOutputContent(StreamOutput $output)
+ {
+ rewind($output->getStream());
+
+ return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
new file mode 100644
index 0000000..507990d
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
@@ -0,0 +1,316 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class ArgvInputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $_SERVER['argv'] = array('cli.php', 'foo');
+ $input = new ArgvInput();
+ $r = new \ReflectionObject($input);
+ $p = $r->getProperty('tokens');
+ $p->setAccessible(true);
+
+ $this->assertEquals(array('foo'), $p->getValue($input), '__construct() automatically get its input from the argv server variable');
+ }
+
+ public function testParseArguments()
+ {
+ $input = new ArgvInput(array('cli.php', 'foo'));
+ $input->bind(new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');
+
+ $input->bind(new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() is stateless');
+ }
+
+ /**
+ * @dataProvider provideOptions
+ */
+ public function testParseOptions($input, $options, $expectedOptions, $message)
+ {
+ $input = new ArgvInput($input);
+ $input->bind(new InputDefinition($options));
+
+ $this->assertEquals($expectedOptions, $input->getOptions(), $message);
+ }
+
+ public function provideOptions()
+ {
+ return array(
+ array(
+ array('cli.php', '--foo'),
+ array(new InputOption('foo')),
+ array('foo' => true),
+ '->parse() parses long options without a value'
+ ),
+ array(
+ array('cli.php', '--foo=bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses long options with a required value (with a = separator)'
+ ),
+ array(
+ array('cli.php', '--foo', 'bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses long options with a required value (with a space separator)'
+ ),
+ array(
+ array('cli.php', '-f'),
+ array(new InputOption('foo', 'f')),
+ array('foo' => true),
+ '->parse() parses short options without a value'
+ ),
+ array(
+ array('cli.php', '-fbar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses short options with a required value (with no separator)'
+ ),
+ array(
+ array('cli.php', '-f', 'bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses short options with a required value (with a space separator)'
+ ),
+ array(
+ array('cli.php', '-f', ''),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
+ array('foo' => ''),
+ '->parse() parses short options with an optional empty value'
+ ),
+ array(
+ array('cli.php', '-f', '', 'foo'),
+ array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
+ array('foo' => ''),
+ '->parse() parses short options with an optional empty value followed by an argument'
+ ),
+ array(
+ array('cli.php', '-f', '', '-b'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
+ array('foo' => '', 'bar' => true),
+ '->parse() parses short options with an optional empty value followed by an option'
+ ),
+ array(
+ array('cli.php', '-f', '-b', 'foo'),
+ array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
+ array('foo' => null, 'bar' => true),
+ '->parse() parses short options with an optional value which is not present'
+ ),
+ array(
+ array('cli.php', '-fb'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b')),
+ array('foo' => true, 'bar' => true),
+ '->parse() parses short options when they are aggregated as a single one'
+ ),
+ array(
+ array('cli.php', '-fb', 'bar'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_REQUIRED)),
+ array('foo' => true, 'bar' => 'bar'),
+ '->parse() parses short options when they are aggregated as a single one and the last one has a required value'
+ ),
+ array(
+ array('cli.php', '-fb', 'bar'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
+ array('foo' => true, 'bar' => 'bar'),
+ '->parse() parses short options when they are aggregated as a single one and the last one has an optional value'
+ ),
+ array(
+ array('cli.php', '-fbbar'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
+ array('foo' => true, 'bar' => 'bar'),
+ '->parse() parses short options when they are aggregated as a single one and the last one has an optional value with no separator'
+ ),
+ array(
+ array('cli.php', '-fbbar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
+ array('foo' => 'bbar', 'bar' => null),
+ '->parse() parses short options when they are aggregated as a single one and one of them takes a value'
+ )
+ );
+ }
+
+ /**
+ * @dataProvider provideInvalidInput
+ */
+ public function testInvalidInput($argv, $definition, $expectedExceptionMessage)
+ {
+ $this->setExpectedException('RuntimeException', $expectedExceptionMessage);
+
+ $input = new ArgvInput($argv);
+ $input->bind($definition);
+ }
+
+ public function provideInvalidInput()
+ {
+ return array(
+ array(
+ array('cli.php', '--foo'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
+ 'The "--foo" option requires a value.'
+ ),
+ array(
+ array('cli.php', '-f'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
+ 'The "--foo" option requires a value.'
+ ),
+ array(
+ array('cli.php', '-ffoo'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
+ 'The "-o" option does not exist.'
+ ),
+ array(
+ array('cli.php', '--foo=bar'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
+ 'The "--foo" option does not accept a value.'
+ ),
+ array(
+ array('cli.php', 'foo', 'bar'),
+ new InputDefinition(),
+ 'Too many arguments.'
+ ),
+ array(
+ array('cli.php', '--foo'),
+ new InputDefinition(),
+ 'The "--foo" option does not exist.'
+ ),
+ array(
+ array('cli.php', '-f'),
+ new InputDefinition(),
+ 'The "-f" option does not exist.'
+ ),
+ array(
+ array('cli.php', '-1'),
+ new InputDefinition(array(new InputArgument('number'))),
+ 'The "-1" option does not exist.'
+ )
+ );
+ }
+
+ public function testParseArrayArgument()
+ {
+ $input = new ArgvInput(array('cli.php', 'foo', 'bar', 'baz', 'bat'));
+ $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::IS_ARRAY))));
+
+ $this->assertEquals(array('name' => array('foo', 'bar', 'baz', 'bat')), $input->getArguments(), '->parse() parses array arguments');
+ }
+
+ public function testParseArrayOption()
+ {
+ $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
+ $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
+
+ $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)');
+
+ $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz'));
+ $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
+ $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)');
+
+ $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
+ $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
+ $this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');
+
+ $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
+ $input->bind(new InputDefinition(array(
+ new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
+ new InputOption('anotherOption', null, InputOption::VALUE_NONE),
+ )));
+ $this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
+ }
+
+ public function testParseNegativeNumberAfterDoubleDash()
+ {
+ $input = new ArgvInput(array('cli.php', '--', '-1'));
+ $input->bind(new InputDefinition(array(new InputArgument('number'))));
+ $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
+
+ $input = new ArgvInput(array('cli.php', '-f', 'bar', '--', '-1'));
+ $input->bind(new InputDefinition(array(new InputArgument('number'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
+ $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses arguments with leading dashes as options before having encountered a double-dash sequence');
+ $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
+ }
+
+ public function testParseEmptyStringArgument()
+ {
+ $input = new ArgvInput(array('cli.php', '-f', 'bar', ''));
+ $input->bind(new InputDefinition(array(new InputArgument('empty'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
+
+ $this->assertEquals(array('empty' => ''), $input->getArguments(), '->parse() parses empty string arguments');
+ }
+
+ public function testGetFirstArgument()
+ {
+ $input = new ArgvInput(array('cli.php', '-fbbar'));
+ $this->assertEquals('', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
+
+ $input = new ArgvInput(array('cli.php', '-fbbar', 'foo'));
+ $this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
+ }
+
+ public function testHasParameterOption()
+ {
+ $input = new ArgvInput(array('cli.php', '-f', 'foo'));
+ $this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');
+
+ $input = new ArgvInput(array('cli.php', '--foo', 'foo'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input');
+
+ $input = new ArgvInput(array('cli.php', 'foo'));
+ $this->assertFalse($input->hasParameterOption('--foo'), '->hasParameterOption() returns false if the given short option is not in the raw input');
+
+ $input = new ArgvInput(array('cli.php', '--foo=bar'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input');
+ }
+
+ public function testToString()
+ {
+ $input = new ArgvInput(array('cli.php', '-f', 'foo'));
+ $this->assertEquals('-f foo', (string) $input);
+
+ $input = new ArgvInput(array('cli.php', '-f', '--bar=foo', 'a b c d', "A\nB'C"));
+ $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
+ }
+
+ /**
+ * @dataProvider provideGetParameterOptionValues
+ */
+ public function testGetParameterOptionEqualSign($argv, $key, $expected)
+ {
+ $input = new ArgvInput($argv);
+ $this->assertEquals($expected, $input->getParameterOption($key), '->getParameterOption() returns the expected value');
+ }
+
+ public function provideGetParameterOptionValues()
+ {
+ return array(
+ array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'),
+ array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
+ );
+ }
+
+ public function testParseSingleDashAsArgument()
+ {
+ $input = new ArgvInput(array('cli.php', '-'));
+ $input->bind(new InputDefinition(array(new InputArgument('file'))));
+ $this->assertEquals(array('file' => '-'), $input->getArguments(), '->parse() parses single dash as an argument');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
new file mode 100644
index 0000000..73f2e33
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
@@ -0,0 +1,129 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class ArrayInputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetFirstArgument()
+ {
+ $input = new ArrayInput(array());
+ $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null if no argument were passed');
+ $input = new ArrayInput(array('name' => 'Fabien'));
+ $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
+ $input = new ArrayInput(array('--foo' => 'bar', 'name' => 'Fabien'));
+ $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
+ }
+
+ public function testHasParameterOption()
+ {
+ $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
+ $this->assertFalse($input->hasParameterOption('--bar'), '->hasParameterOption() returns false if an option is not present in the passed parameters');
+
+ $input = new ArrayInput(array('--foo'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
+ }
+
+ public function testParseArguments()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
+
+ $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');
+ }
+
+ /**
+ * @dataProvider provideOptions
+ */
+ public function testParseOptions($input, $options, $expectedOptions, $message)
+ {
+ $input = new ArrayInput($input, new InputDefinition($options));
+
+ $this->assertEquals($expectedOptions, $input->getOptions(), $message);
+ }
+
+ public function provideOptions()
+ {
+ return array(
+ array(
+ array('--foo' => 'bar'),
+ array(new InputOption('foo')),
+ array('foo' => 'bar'),
+ '->parse() parses long options'
+ ),
+ array(
+ array('--foo' => 'bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
+ array('foo' => 'bar'),
+ '->parse() parses long options with a default value'
+ ),
+ array(
+ array('--foo' => null),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
+ array('foo' => 'default'),
+ '->parse() parses long options with a default value'
+ ),
+ array(
+ array('-f' => 'bar'),
+ array(new InputOption('foo', 'f')),
+ array('foo' => 'bar'),
+ '->parse() parses short options'
+ )
+ );
+ }
+
+ /**
+ * @dataProvider provideInvalidInput
+ */
+ public function testParseInvalidInput($parameters, $definition, $expectedExceptionMessage)
+ {
+ $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);
+
+ new ArrayInput($parameters, $definition);
+ }
+
+ public function provideInvalidInput()
+ {
+ return array(
+ array(
+ array('foo' => 'foo'),
+ new InputDefinition(array(new InputArgument('name'))),
+ 'The "foo" argument does not exist.'
+ ),
+ array(
+ array('--foo' => null),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
+ 'The "--foo" option requires a value.'
+ ),
+ array(
+ array('--foo' => 'foo'),
+ new InputDefinition(),
+ 'The "--foo" option does not exist.'
+ ),
+ array(
+ array('-o' => 'foo'),
+ new InputDefinition(),
+ 'The "-o" option does not exist.'
+ )
+ );
+ }
+
+ public function testToString()
+ {
+ $input = new ArrayInput(array('-f' => null, '-b' => 'bar', '--foo' => 'b a z', '--lala' => null, 'test' => 'Foo', 'test2' => "A\nB'C"));
+ $this->assertEquals('-f -b=bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input);
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php
new file mode 100644
index 0000000..3bfc796
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php
@@ -0,0 +1,111 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputArgument;
+
+class InputArgumentTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $argument = new InputArgument('foo');
+ $this->assertEquals('foo', $argument->getName(), '__construct() takes a name as its first argument');
+ }
+
+ public function testModes()
+ {
+ $argument = new InputArgument('foo');
+ $this->assertFalse($argument->isRequired(), '__construct() gives a "InputArgument::OPTIONAL" mode by default');
+
+ $argument = new InputArgument('foo', null);
+ $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');
+
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL);
+ $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');
+
+ $argument = new InputArgument('foo', InputArgument::REQUIRED);
+ $this->assertTrue($argument->isRequired(), '__construct() can take "InputArgument::REQUIRED" as its mode');
+ }
+
+ /**
+ * @dataProvider provideInvalidModes
+ */
+ public function testInvalidModes($mode)
+ {
+ $this->setExpectedException('InvalidArgumentException', sprintf('Argument mode "%s" is not valid.', $mode));
+
+ new InputArgument('foo', $mode);
+ }
+
+ public function provideInvalidModes()
+ {
+ return array(
+ array('ANOTHER_ONE'),
+ array(-1)
+ );
+ }
+
+ public function testIsArray()
+ {
+ $argument = new InputArgument('foo', InputArgument::IS_ARRAY);
+ $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
+ $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL);
+ $this->assertFalse($argument->isArray(), '->isArray() returns false if the argument can not be an array');
+ }
+
+ public function testGetDescription()
+ {
+ $argument = new InputArgument('foo', null, 'Some description');
+ $this->assertEquals('Some description', $argument->getDescription(), '->getDescription() return the message description');
+ }
+
+ public function testGetDefault()
+ {
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
+ $this->assertEquals('default', $argument->getDefault(), '->getDefault() return the default value');
+ }
+
+ public function testSetDefault()
+ {
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
+ $argument->setDefault(null);
+ $this->assertNull($argument->getDefault(), '->setDefault() can reset the default value by passing null');
+ $argument->setDefault('another');
+ $this->assertEquals('another', $argument->getDefault(), '->setDefault() changes the default value');
+
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
+ $argument->setDefault(array(1, 2));
+ $this->assertEquals(array(1, 2), $argument->getDefault(), '->setDefault() changes the default value');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot set a default value except for InputArgument::OPTIONAL mode.
+ */
+ public function testSetDefaultWithRequiredArgument()
+ {
+ $argument = new InputArgument('foo', InputArgument::REQUIRED);
+ $argument->setDefault('default');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage A default value for an array argument must be an array.
+ */
+ public function testSetDefaultWithArrayArgument()
+ {
+ $argument = new InputArgument('foo', InputArgument::IS_ARRAY);
+ $argument->setDefault('default');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php
new file mode 100644
index 0000000..5cf5011
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php
@@ -0,0 +1,420 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class InputDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixtures;
+
+ protected $foo, $bar, $foo1, $foo2;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixtures = __DIR__.'/../Fixtures/';
+ }
+
+ public function testConstructorArguments()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $this->assertEquals(array(), $definition->getArguments(), '__construct() creates a new InputDefinition object');
+
+ $definition = new InputDefinition(array($this->foo, $this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '__construct() takes an array of InputArgument objects as its first argument');
+ }
+
+ public function testConstructorOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $this->assertEquals(array(), $definition->getOptions(), '__construct() creates a new InputDefinition object');
+
+ $definition = new InputDefinition(array($this->foo, $this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '__construct() takes an array of InputOption objects as its first argument');
+ }
+
+ public function testSetArguments()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->setArguments(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->setArguments() sets the array of InputArgument objects');
+ $definition->setArguments(array($this->bar));
+
+ $this->assertEquals(array('bar' => $this->bar), $definition->getArguments(), '->setArguments() clears all InputArgument objects');
+ }
+
+ public function testAddArguments()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArguments() adds an array of InputArgument objects');
+ $definition->addArguments(array($this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArguments() does not clear existing InputArgument objects');
+ }
+
+ public function testAddArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo);
+ $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArgument() adds a InputArgument object');
+ $definition->addArgument($this->bar);
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArgument() adds a InputArgument object');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An argument with name "foo" already exists.
+ */
+ public function testArgumentsMustHaveDifferentNames()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo);
+ $definition->addArgument($this->foo1);
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot add an argument after an array argument.
+ */
+ public function testArrayArgumentHasToBeLast()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument(new InputArgument('fooarray', InputArgument::IS_ARRAY));
+ $definition->addArgument(new InputArgument('anotherbar'));
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot add a required argument after an optional one.
+ */
+ public function testRequiredArgumentCannotFollowAnOptionalOne()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo);
+ $definition->addArgument($this->foo2);
+ }
+
+ public function testGetArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+ $this->assertEquals($this->foo, $definition->getArgument('foo'), '->getArgument() returns a InputArgument by its name');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "bar" argument does not exist.
+ */
+ public function testGetInvalidArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+ $definition->getArgument('bar');
+ }
+
+ public function testHasArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+
+ $this->assertTrue($definition->hasArgument('foo'), '->hasArgument() returns true if a InputArgument exists for the given name');
+ $this->assertFalse($definition->hasArgument('bar'), '->hasArgument() returns false if a InputArgument exists for the given name');
+ }
+
+ public function testGetArgumentRequiredCount()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo2);
+ $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
+ $definition->addArgument($this->foo);
+ $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
+ }
+
+ public function testGetArgumentCount()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo2);
+ $this->assertEquals(1, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
+ $definition->addArgument($this->foo);
+ $this->assertEquals(2, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
+ }
+
+ public function testGetArgumentDefaults()
+ {
+ $definition = new InputDefinition(array(
+ new InputArgument('foo1', InputArgument::OPTIONAL),
+ new InputArgument('foo2', InputArgument::OPTIONAL, '', 'default'),
+ new InputArgument('foo3', InputArgument::OPTIONAL | InputArgument::IS_ARRAY),
+ // new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)),
+ ));
+ $this->assertEquals(array('foo1' => null, 'foo2' => 'default', 'foo3' => array()), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');
+
+ $definition = new InputDefinition(array(
+ new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)),
+ ));
+ $this->assertEquals(array('foo4' => array(1, 2)), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');
+ }
+
+ public function testSetOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->setOptions() sets the array of InputOption objects');
+ $definition->setOptions(array($this->bar));
+ $this->assertEquals(array('bar' => $this->bar), $definition->getOptions(), '->setOptions() clears all InputOption objects');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "-f" option does not exist.
+ */
+ public function testSetOptionsClearsOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $definition->setOptions(array($this->bar));
+ $definition->getOptionForShortcut('f');
+ }
+
+ public function testAddOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOptions() adds an array of InputOption objects');
+ $definition->addOptions(array($this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOptions() does not clear existing InputOption objects');
+ }
+
+ public function testAddOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $definition->addOption($this->foo);
+ $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOption() adds a InputOption object');
+ $definition->addOption($this->bar);
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOption() adds a InputOption object');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An option named "foo" already exists.
+ */
+ public function testAddDuplicateOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $definition->addOption($this->foo);
+ $definition->addOption($this->foo2);
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An option with shortcut "f" already exists.
+ */
+ public function testAddDuplicateShortcutOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $definition->addOption($this->foo);
+ $definition->addOption($this->foo1);
+ }
+
+ public function testGetOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals($this->foo, $definition->getOption('foo'), '->getOption() returns a InputOption by its name');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "--bar" option does not exist.
+ */
+ public function testGetInvalidOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $definition->getOption('bar');
+ }
+
+ public function testHasOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertTrue($definition->hasOption('foo'), '->hasOption() returns true if a InputOption exists for the given name');
+ $this->assertFalse($definition->hasOption('bar'), '->hasOption() returns false if a InputOption exists for the given name');
+ }
+
+ public function testHasShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertTrue($definition->hasShortcut('f'), '->hasShortcut() returns true if a InputOption exists for the given shortcut');
+ $this->assertFalse($definition->hasShortcut('b'), '->hasShortcut() returns false if a InputOption exists for the given shortcut');
+ }
+
+ public function testGetOptionForShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals($this->foo, $definition->getOptionForShortcut('f'), '->getOptionForShortcut() returns a InputOption by its shortcut');
+ }
+
+ public function testGetOptionForMultiShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->multi));
+ $this->assertEquals($this->multi, $definition->getOptionForShortcut('m'), '->getOptionForShortcut() returns a InputOption by its shortcut');
+ $this->assertEquals($this->multi, $definition->getOptionForShortcut('mmm'), '->getOptionForShortcut() returns a InputOption by its shortcut');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "-l" option does not exist.
+ */
+ public function testGetOptionForInvalidShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $definition->getOptionForShortcut('l');
+ }
+
+ public function testGetOptionDefaults()
+ {
+ $definition = new InputDefinition(array(
+ new InputOption('foo1', null, InputOption::VALUE_NONE),
+ new InputOption('foo2', null, InputOption::VALUE_REQUIRED),
+ new InputOption('foo3', null, InputOption::VALUE_REQUIRED, '', 'default'),
+ new InputOption('foo4', null, InputOption::VALUE_OPTIONAL),
+ new InputOption('foo5', null, InputOption::VALUE_OPTIONAL, '', 'default'),
+ new InputOption('foo6', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
+ new InputOption('foo7', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', array(1, 2)),
+ ));
+ $defaults = array(
+ 'foo1' => null,
+ 'foo2' => null,
+ 'foo3' => 'default',
+ 'foo4' => null,
+ 'foo5' => 'default',
+ 'foo6' => array(),
+ 'foo7' => array(1, 2),
+ );
+ $this->assertEquals($defaults, $definition->getOptionDefaults(), '->getOptionDefaults() returns the default values for all options');
+ }
+
+ public function testGetSynopsis()
+ {
+ $definition = new InputDefinition(array(new InputOption('foo')));
+ $this->assertEquals('[--foo]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputOption('foo', 'f')));
+ $this->assertEquals('[-f|--foo]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)));
+ $this->assertEquals('[-f|--foo="..."]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)));
+ $this->assertEquals('[-f|--foo[="..."]]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+
+ $definition = new InputDefinition(array(new InputArgument('foo')));
+ $this->assertEquals('[foo]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED)));
+ $this->assertEquals('foo', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputArgument('foo', InputArgument::IS_ARRAY)));
+ $this->assertEquals('[foo1] ... [fooN]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED | InputArgument::IS_ARRAY)));
+ $this->assertEquals('foo1 ... [fooN]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ }
+
+ public function testAsText()
+ {
+ $definition = new InputDefinition(array(
+ new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
+ new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
+ new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('http://foo.com/')),
+ new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
+ new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
+ new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
+ new InputOption('qux', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux option', array('http://foo.com/', 'bar')),
+ new InputOption('qux2', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux2 option', array('foo' => 'bar')),
+ ));
+ $this->assertStringEqualsFile(self::$fixtures.'/definition_astext.txt', $definition->asText(), '->asText() returns a textual representation of the InputDefinition');
+ }
+
+ public function testAsXml()
+ {
+ $definition = new InputDefinition(array(
+ new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
+ new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
+ new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('bar')),
+ new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
+ new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
+ new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
+ ));
+ $this->assertXmlStringEqualsXmlFile(self::$fixtures.'/definition_asxml.txt', $definition->asXml(), '->asText() returns a textual representation of the InputDefinition');
+ }
+
+ protected function initializeArguments()
+ {
+ $this->foo = new InputArgument('foo');
+ $this->bar = new InputArgument('bar');
+ $this->foo1 = new InputArgument('foo');
+ $this->foo2 = new InputArgument('foo2', InputArgument::REQUIRED);
+ }
+
+ protected function initializeOptions()
+ {
+ $this->foo = new InputOption('foo', 'f');
+ $this->bar = new InputOption('bar', 'b');
+ $this->foo1 = new InputOption('fooBis', 'f');
+ $this->foo2 = new InputOption('foo', 'p');
+ $this->multi = new InputOption('multi', 'm|mm|mmm');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php
new file mode 100644
index 0000000..5817e8f
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php
@@ -0,0 +1,204 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputOption;
+
+class InputOptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $option = new InputOption('foo');
+ $this->assertEquals('foo', $option->getName(), '__construct() takes a name as its first argument');
+ $option = new InputOption('--foo');
+ $this->assertEquals('foo', $option->getName(), '__construct() removes the leading -- of the option name');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.
+ */
+ public function testArrayModeWithoutValue()
+ {
+ new InputOption('foo', 'f', InputOption::VALUE_IS_ARRAY);
+ }
+
+ public function testShortcut()
+ {
+ $option = new InputOption('foo', 'f');
+ $this->assertEquals('f', $option->getShortcut(), '__construct() can take a shortcut as its second argument');
+ $option = new InputOption('foo', '-f|-ff|fff');
+ $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
+ $option = new InputOption('foo', array('f', 'ff', '-fff'));
+ $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
+ $option = new InputOption('foo');
+ $this->assertNull($option->getShortcut(), '__construct() makes the shortcut null by default');
+ }
+
+ public function testModes()
+ {
+ $option = new InputOption('foo', 'f');
+ $this->assertFalse($option->acceptValue(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
+ $this->assertFalse($option->isValueRequired(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
+ $this->assertFalse($option->isValueOptional(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
+
+ $option = new InputOption('foo', 'f', null);
+ $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
+ $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_REQUIRED);
+ $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
+ $this->assertTrue($option->isValueRequired(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
+ $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL);
+ $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
+ $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
+ $this->assertTrue($option->isValueOptional(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
+ }
+
+ /**
+ * @dataProvider provideInvalidModes
+ */
+ public function testInvalidModes($mode)
+ {
+ $this->setExpectedException('InvalidArgumentException', sprintf('Option mode "%s" is not valid.', $mode));
+
+ new InputOption('foo', 'f', $mode);
+ }
+
+ public function provideInvalidModes()
+ {
+ return array(
+ array('ANOTHER_ONE'),
+ array(-1)
+ );
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testEmptyNameIsInvalid()
+ {
+ new InputOption('');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testDoubleDashNameIsInvalid()
+ {
+ new InputOption('--');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSingleDashOptionIsInvalid()
+ {
+ new InputOption('foo', '-');
+ }
+
+ public function testIsArray()
+ {
+ $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
+ $this->assertTrue($option->isArray(), '->isArray() returns true if the option can be an array');
+ $option = new InputOption('foo', null, InputOption::VALUE_NONE);
+ $this->assertFalse($option->isArray(), '->isArray() returns false if the option can not be an array');
+ }
+
+ public function testGetDescription()
+ {
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $this->assertEquals('Some description', $option->getDescription(), '->getDescription() returns the description message');
+ }
+
+ public function testGetDefault()
+ {
+ $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL, '', 'default');
+ $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
+ $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED);
+ $this->assertNull($option->getDefault(), '->getDefault() returns null if no default value is configured');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
+ $this->assertEquals(array(), $option->getDefault(), '->getDefault() returns an empty array if option is an array');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_NONE);
+ $this->assertFalse($option->getDefault(), '->getDefault() returns false if the option does not take a value');
+ }
+
+ public function testSetDefault()
+ {
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
+ $option->setDefault(null);
+ $this->assertNull($option->getDefault(), '->setDefault() can reset the default value by passing null');
+ $option->setDefault('another');
+ $this->assertEquals('another', $option->getDefault(), '->setDefault() changes the default value');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY);
+ $option->setDefault(array(1, 2));
+ $this->assertEquals(array(1, 2), $option->getDefault(), '->setDefault() changes the default value');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot set a default value when using InputOption::VALUE_NONE mode.
+ */
+ public function testDefaultValueWithValueNoneMode()
+ {
+ $option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
+ $option->setDefault('default');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage A default value for an array option must be an array.
+ */
+ public function testDefaultValueWithIsArrayMode()
+ {
+ $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
+ $option->setDefault('default');
+ }
+
+ public function testEquals()
+ {
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('foo', 'f', null, 'Alternative description');
+ $this->assertTrue($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
+ $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description', true);
+ $this->assertFalse($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('bar', 'f', null, 'Some description');
+ $this->assertFalse($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('foo', '', null, 'Some description');
+ $this->assertFalse($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
+ $this->assertFalse($option->equals($option2));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php
new file mode 100644
index 0000000..0b3e38f
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php
@@ -0,0 +1,121 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class InputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals('foo', $input->getArgument('name'), '->__construct() takes a InputDefinition as an argument');
+ }
+
+ public function testOptions()
+ {
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'))));
+ $this->assertEquals('foo', $input->getOption('name'), '->getOption() returns the value for the given option');
+
+ $input->setOption('name', 'bar');
+ $this->assertEquals('bar', $input->getOption('name'), '->setOption() sets the value for a given option');
+ $this->assertEquals(array('name' => 'bar'), $input->getOptions(), '->getOptions() returns all option values');
+
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
+ $this->assertEquals('default', $input->getOption('bar'), '->getOption() returns the default value for optional options');
+ $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getOptions(), '->getOptions() returns all option values, even optional ones');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" option does not exist.
+ */
+ public function testSetInvalidOption()
+ {
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
+ $input->setOption('foo', 'bar');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" option does not exist.
+ */
+ public function testGetInvalidOption()
+ {
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
+ $input->getOption('foo');
+ }
+
+ public function testArguments()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals('foo', $input->getArgument('name'), '->getArgument() returns the value for the given argument');
+
+ $input->setArgument('name', 'bar');
+ $this->assertEquals('bar', $input->getArgument('name'), '->setArgument() sets the value for a given argument');
+ $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->getArguments() returns all argument values');
+
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
+ $this->assertEquals('default', $input->getArgument('bar'), '->getArgument() returns the default value for optional arguments');
+ $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getArguments(), '->getArguments() returns all argument values, even optional ones');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" argument does not exist.
+ */
+ public function testSetInvalidArgument()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
+ $input->setArgument('foo', 'bar');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" argument does not exist.
+ */
+ public function testGetInvalidArgument()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
+ $input->getArgument('foo');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Not enough arguments.
+ */
+ public function testValidateWithMissingArguments()
+ {
+ $input = new ArrayInput(array());
+ $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));
+ $input->validate();
+ }
+
+ public function testValidate()
+ {
+ $input = new ArrayInput(array('name' => 'foo'));
+ $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));
+
+ $this->assertNull($input->validate());
+ }
+
+ public function testSetGetInteractive()
+ {
+ $input = new ArrayInput(array());
+ $this->assertTrue($input->isInteractive(), '->isInteractive() returns whether the input should be interactive or not');
+ $input->setInteractive(false);
+ $this->assertFalse($input->isInteractive(), '->setInteractive() changes the interactive flag');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php
new file mode 100644
index 0000000..b284320
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php
@@ -0,0 +1,90 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\StringInput;
+
+class StringInputTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTokenizeData
+ */
+ public function testTokenize($input, $tokens, $message)
+ {
+ $input = new StringInput($input);
+ $r = new \ReflectionClass('Symfony\Component\Console\Input\ArgvInput');
+ $p = $r->getProperty('tokens');
+ $p->setAccessible(true);
+ $this->assertEquals($tokens, $p->getValue($input), $message);
+ }
+
+ public function testInputOptionWithGivenString()
+ {
+ $definition = new InputDefinition(
+ array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
+ );
+
+ // call to bind
+ $input = new StringInput('--foo=bar');
+ $input->bind($definition);
+ $this->assertEquals('bar', $input->getOption('foo'));
+
+ // definition in constructor
+ $input = new StringInput('--foo=bar', $definition);
+ $this->assertEquals('bar', $input->getOption('foo'));
+ }
+
+ public function getTokenizeData()
+ {
+ return array(
+ array('', array(), '->tokenize() parses an empty string'),
+ array('foo', array('foo'), '->tokenize() parses arguments'),
+ array(' foo bar ', array('foo', 'bar'), '->tokenize() ignores whitespaces between arguments'),
+ array('"quoted"', array('quoted'), '->tokenize() parses quoted arguments'),
+ array("'quoted'", array('quoted'), '->tokenize() parses quoted arguments'),
+ array("'a\rb\nc\td'", array("a\rb\nc\td"), '->tokenize() parses whitespace chars in strings'),
+ array("'a'\r'b'\n'c'\t'd'", array('a','b','c','d'), '->tokenize() parses whitespace chars between args as spaces'),
+ array('\"quoted\"', array('"quoted"'), '->tokenize() parses escaped-quoted arguments'),
+ array("\'quoted\'", array('\'quoted\''), '->tokenize() parses escaped-quoted arguments'),
+ array('-a', array('-a'), '->tokenize() parses short options'),
+ array('-azc', array('-azc'), '->tokenize() parses aggregated short options'),
+ array('-awithavalue', array('-awithavalue'), '->tokenize() parses short options with a value'),
+ array('-a"foo bar"', array('-afoo bar'), '->tokenize() parses short options with a value'),
+ array('-a"foo bar""foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
+ array('-a\'foo bar\'', array('-afoo bar'), '->tokenize() parses short options with a value'),
+ array('-a\'foo bar\'\'foo bar\'', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
+ array('-a\'foo bar\'"foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
+ array('--long-option', array('--long-option'), '->tokenize() parses long options'),
+ array('--long-option=foo', array('--long-option=foo'), '->tokenize() parses long options with a value'),
+ array('--long-option="foo bar"', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
+ array('--long-option="foo bar""another"', array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
+ array('--long-option=\'foo bar\'', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
+ array("--long-option='foo bar''another'", array("--long-option=foo baranother"), '->tokenize() parses long options with a value'),
+ array("--long-option='foo bar'\"another\"", array("--long-option=foo baranother"), '->tokenize() parses long options with a value'),
+ array('foo -a -ffoo --long bar', array('foo', '-a', '-ffoo', '--long', 'bar'), '->tokenize() parses when several arguments and options'),
+ );
+ }
+
+ public function testToString()
+ {
+ $input = new StringInput('-f foo');
+ $this->assertEquals('-f foo', (string) $input);
+
+ $input = new StringInput('-f --bar=foo "a b c d"');
+ $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d'), (string) $input);
+
+ $input = new StringInput('-f --bar=foo \'a b c d\' '."'A\nB\\'C'");
+ $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php
new file mode 100644
index 0000000..7a3ede3
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Output\Output;
+
+class ConsoleOutputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $output = new ConsoleOutput(Output::VERBOSITY_QUIET, true);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php
new file mode 100644
index 0000000..b20ae4e
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php
@@ -0,0 +1,39 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class NullOutputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $output = new NullOutput();
+
+ ob_start();
+ $output->write('foo');
+ $buffer = ob_get_clean();
+
+ $this->assertSame('', $buffer, '->write() does nothing (at least nothing is printed)');
+ $this->assertFalse($output->isDecorated(), '->isDecorated() returns false');
+ }
+
+ public function testVerbosity()
+ {
+ $output = new NullOutput();
+ $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() returns VERBOSITY_QUIET for NullOutput by default');
+
+ $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
+ $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() always returns VERBOSITY_QUIET for NullOutput');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php
new file mode 100644
index 0000000..95bbbe6
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php
@@ -0,0 +1,156 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $output = new TestOutput(Output::VERBOSITY_QUIET, true);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
+ $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
+ }
+
+ public function testSetIsDecorated()
+ {
+ $output = new TestOutput();
+ $output->setDecorated(true);
+ $this->assertTrue($output->isDecorated(), 'setDecorated() sets the decorated flag');
+ }
+
+ public function testSetGetVerbosity()
+ {
+ $output = new TestOutput();
+ $output->setVerbosity(Output::VERBOSITY_QUIET);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '->setVerbosity() sets the verbosity');
+
+ $this->assertTrue($output->isQuiet());
+ $this->assertFalse($output->isVerbose());
+ $this->assertFalse($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_NORMAL);
+ $this->assertFalse($output->isQuiet());
+ $this->assertFalse($output->isVerbose());
+ $this->assertFalse($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_VERBOSE);
+ $this->assertFalse($output->isQuiet());
+ $this->assertTrue($output->isVerbose());
+ $this->assertFalse($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE);
+ $this->assertFalse($output->isQuiet());
+ $this->assertTrue($output->isVerbose());
+ $this->assertTrue($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_DEBUG);
+ $this->assertFalse($output->isQuiet());
+ $this->assertTrue($output->isVerbose());
+ $this->assertTrue($output->isVeryVerbose());
+ $this->assertTrue($output->isDebug());
+ }
+
+ public function testWriteWithVerbosityQuiet()
+ {
+ $output = new TestOutput(Output::VERBOSITY_QUIET);
+ $output->writeln('foo');
+ $this->assertEquals('', $output->output, '->writeln() outputs nothing if verbosity is set to VERBOSITY_QUIET');
+ }
+
+ public function testWriteAnArrayOfMessages()
+ {
+ $output = new TestOutput();
+ $output->writeln(array('foo', 'bar'));
+ $this->assertEquals("foo\nbar\n", $output->output, '->writeln() can take an array of messages to output');
+ }
+
+ /**
+ * @dataProvider provideWriteArguments
+ */
+ public function testWriteRawMessage($message, $type, $expectedOutput)
+ {
+ $output = new TestOutput();
+ $output->writeln($message, $type);
+ $this->assertEquals($expectedOutput, $output->output);
+ }
+
+ public function provideWriteArguments()
+ {
+ return array(
+ array('foo', Output::OUTPUT_RAW, "foo\n"),
+ array('foo', Output::OUTPUT_PLAIN, "foo\n"),
+ );
+ }
+
+ public function testWriteWithDecorationTurnedOff()
+ {
+ $output = new TestOutput();
+ $output->setDecorated(false);
+ $output->writeln('foo');
+ $this->assertEquals("foo\n", $output->output, '->writeln() strips decoration tags if decoration is set to false');
+ }
+
+ public function testWriteDecoratedMessage()
+ {
+ $fooStyle = new OutputFormatterStyle('yellow', 'red', array('blink'));
+ $output = new TestOutput();
+ $output->getFormatter()->setStyle('FOO', $fooStyle);
+ $output->setDecorated(true);
+ $output->writeln('foo');
+ $this->assertEquals("\033[33;41;5mfoo\033[0m\n", $output->output, '->writeln() decorates the output');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Unknown output type given (24)
+ */
+ public function testWriteWithInvalidOutputType()
+ {
+ $output = new TestOutput();
+ $output->writeln('foo', 24);
+ }
+
+ public function testWriteWithInvalidStyle()
+ {
+ $output = new TestOutput();
+
+ $output->clear();
+ $output->write('foo');
+ $this->assertEquals('foo', $output->output, '->write() do nothing when a style does not exist');
+
+ $output->clear();
+ $output->writeln('foo');
+ $this->assertEquals("foo\n", $output->output, '->writeln() do nothing when a style does not exist');
+ }
+}
+
+class TestOutput extends Output
+{
+ public $output = '';
+
+ public function clear()
+ {
+ $this->output = '';
+ }
+
+ protected function doWrite($message, $newline)
+ {
+ $this->output .= $message.($newline ? "\n" : '');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php
new file mode 100644
index 0000000..2fd4f61
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class StreamOutputTest extends \PHPUnit_Framework_TestCase
+{
+ protected $stream;
+
+ protected function setUp()
+ {
+ $this->stream = fopen('php://memory', 'a', false);
+ }
+
+ protected function tearDown()
+ {
+ $this->stream = null;
+ }
+
+ public function testConstructor()
+ {
+ $output = new StreamOutput($this->stream, Output::VERBOSITY_QUIET, true);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
+ $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The StreamOutput class needs a stream as its first argument.
+ */
+ public function testStreamIsRequired()
+ {
+ new StreamOutput('foo');
+ }
+
+ public function testGetStream()
+ {
+ $output = new StreamOutput($this->stream);
+ $this->assertEquals($this->stream, $output->getStream(), '->getStream() returns the current stream');
+ }
+
+ public function testDoWrite()
+ {
+ $output = new StreamOutput($this->stream);
+ $output->writeln('foo');
+ rewind($output->getStream());
+ $this->assertEquals('foo'.PHP_EOL, stream_get_contents($output->getStream()), '->doWrite() writes to the stream');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php
new file mode 100644
index 0000000..a8389dd
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php
@@ -0,0 +1,69 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Tester\ApplicationTester;
+
+class ApplicationTesterTest extends \PHPUnit_Framework_TestCase
+{
+ protected $application;
+ protected $tester;
+
+ protected function setUp()
+ {
+ $this->application = new Application();
+ $this->application->setAutoExit(false);
+ $this->application->register('foo')
+ ->addArgument('foo')
+ ->setCode(function ($input, $output) { $output->writeln('foo'); })
+ ;
+
+ $this->tester = new ApplicationTester($this->application);
+ $this->tester->run(array('command' => 'foo', 'foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
+ }
+
+ protected function tearDown()
+ {
+ $this->application = null;
+ $this->tester = null;
+ }
+
+ public function testRun()
+ {
+ $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
+ $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
+ $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
+ }
+
+ public function testGetInput()
+ {
+ $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
+ }
+
+ public function testGetOutput()
+ {
+ rewind($this->tester->getOutput()->getStream());
+ $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
+ }
+
+ public function testGetDisplay()
+ {
+ $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
+ }
+
+ public function testGetStatusCode()
+ {
+ $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php
new file mode 100644
index 0000000..b54c00e
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php
@@ -0,0 +1,84 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class CommandTesterTest extends \PHPUnit_Framework_TestCase
+{
+ protected $command;
+ protected $tester;
+
+ protected function setUp()
+ {
+ $this->command = new Command('foo');
+ $this->command->addArgument('command');
+ $this->command->addArgument('foo');
+ $this->command->setCode(function ($input, $output) { $output->writeln('foo'); });
+
+ $this->tester = new CommandTester($this->command);
+ $this->tester->execute(array('foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
+ }
+
+ protected function tearDown()
+ {
+ $this->command = null;
+ $this->tester = null;
+ }
+
+ public function testExecute()
+ {
+ $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
+ $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
+ $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
+ }
+
+ public function testGetInput()
+ {
+ $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
+ }
+
+ public function testGetOutput()
+ {
+ rewind($this->tester->getOutput()->getStream());
+ $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
+ }
+
+ public function testGetDisplay()
+ {
+ $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
+ }
+
+ public function testGetStatusCode()
+ {
+ $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
+ }
+
+ public function testCommandFromApplication()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+
+ $command = new Command('foo');
+ $command->setCode(function ($input, $output) { $output->writeln('foo'); });
+
+ $application->add($command);
+
+ $tester = new CommandTester($application->find('foo'));
+
+ // check that there is no need to pass the command name here
+ $this->assertEquals(0, $tester->execute(array()));
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/composer.json b/core/vendor/symfony/console/Symfony/Component/Console/composer.json
new file mode 100644
index 0000000..77777aa
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/composer.json
@@ -0,0 +1,37 @@
+{
+ "name": "symfony/console",
+ "type": "library",
+ "description": "Symfony Console Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/event-dispatcher": "~2.1"
+ },
+ "suggest": {
+ "symfony/event-dispatcher": ""
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Console\\": "" }
+ },
+ "target-dir": "Symfony/Component/Console",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ }
+}
diff --git a/core/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist b/core/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist
new file mode 100644
index 0000000..8a7edd4
--- /dev/null
+++ b/core/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist
@@ -0,0 +1,30 @@
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
+
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php
new file mode 100644
index 0000000..bdb04f5
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php
@@ -0,0 +1,236 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+/**
+ * Interface for finder engine implementations.
+ *
+ * @author Jean-François Simon
+ */
+abstract class AbstractAdapter implements AdapterInterface
+{
+ protected $followLinks = false;
+ protected $mode = 0;
+ protected $minDepth = 0;
+ protected $maxDepth = PHP_INT_MAX;
+ protected $exclude = array();
+ protected $names = array();
+ protected $notNames = array();
+ protected $contains = array();
+ protected $notContains = array();
+ protected $sizes = array();
+ protected $dates = array();
+ protected $filters = array();
+ protected $sort = false;
+ protected $paths = array();
+ protected $notPaths = array();
+ protected $ignoreUnreadableDirs = false;
+
+ private static $areSupported = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSupported()
+ {
+ $name = $this->getName();
+
+ if (!array_key_exists($name, self::$areSupported)) {
+ self::$areSupported[$name] = $this->canBeUsed();
+ }
+
+ return self::$areSupported[$name];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFollowLinks($followLinks)
+ {
+ $this->followLinks = $followLinks;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMode($mode)
+ {
+ $this->mode = $mode;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDepths(array $depths)
+ {
+ $this->minDepth = 0;
+ $this->maxDepth = PHP_INT_MAX;
+
+ foreach ($depths as $comparator) {
+ switch ($comparator->getOperator()) {
+ case '>':
+ $this->minDepth = $comparator->getTarget() + 1;
+ break;
+ case '>=':
+ $this->minDepth = $comparator->getTarget();
+ break;
+ case '<':
+ $this->maxDepth = $comparator->getTarget() - 1;
+ break;
+ case '<=':
+ $this->maxDepth = $comparator->getTarget();
+ break;
+ default:
+ $this->minDepth = $this->maxDepth = $comparator->getTarget();
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setExclude(array $exclude)
+ {
+ $this->exclude = $exclude;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNames(array $names)
+ {
+ $this->names = $names;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotNames(array $notNames)
+ {
+ $this->notNames = $notNames;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContains(array $contains)
+ {
+ $this->contains = $contains;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotContains(array $notContains)
+ {
+ $this->notContains = $notContains;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSizes(array $sizes)
+ {
+ $this->sizes = $sizes;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDates(array $dates)
+ {
+ $this->dates = $dates;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFilters(array $filters)
+ {
+ $this->filters = $filters;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSort($sort)
+ {
+ $this->sort = $sort;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setPath(array $paths)
+ {
+ $this->paths = $paths;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotPath(array $notPaths)
+ {
+ $this->notPaths = $notPaths;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function ignoreUnreadableDirs($ignore = true)
+ {
+ $this->ignoreUnreadableDirs = (bool) $ignore;
+
+ return $this;
+ }
+
+ /**
+ * Returns whether the adapter is supported in the current environment.
+ *
+ * This method should be implemented in all adapters. Do not implement
+ * isSupported in the adapters as the generic implementation provides a cache
+ * layer.
+ *
+ * @see isSupported
+ *
+ * @return bool Whether the adapter is supported
+ */
+ abstract protected function canBeUsed();
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php
new file mode 100644
index 0000000..0194038
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php
@@ -0,0 +1,327 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Exception\AccessDeniedException;
+use Symfony\Component\Finder\Iterator;
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Expression\Expression;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+use Symfony\Component\Finder\Comparator\NumberComparator;
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+/**
+ * Shell engine implementation using GNU find command.
+ *
+ * @author Jean-François Simon
+ */
+abstract class AbstractFindAdapter extends AbstractAdapter
+{
+ /**
+ * @var Shell
+ */
+ protected $shell;
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->shell = new Shell();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ // having "/../" in path make find fail
+ $dir = realpath($dir);
+
+ // searching directories containing or not containing strings leads to no result
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
+ return new Iterator\FilePathsIterator(array(), $dir);
+ }
+
+ $command = Command::create();
+ $find = $this->buildFindCommand($command, $dir);
+
+ if ($this->followLinks) {
+ $find->add('-follow');
+ }
+
+ $find->add('-mindepth')->add($this->minDepth + 1);
+
+ if (PHP_INT_MAX !== $this->maxDepth) {
+ $find->add('-maxdepth')->add($this->maxDepth + 1);
+ }
+
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
+ $find->add('-type d');
+ } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
+ $find->add('-type f');
+ }
+
+ $this->buildNamesFiltering($find, $this->names);
+ $this->buildNamesFiltering($find, $this->notNames, true);
+ $this->buildPathsFiltering($find, $dir, $this->paths);
+ $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
+ $this->buildSizesFiltering($find, $this->sizes);
+ $this->buildDatesFiltering($find, $this->dates);
+
+ $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
+ $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
+
+ if ($useGrep && ($this->contains || $this->notContains)) {
+ $grep = $command->ins('grep');
+ $this->buildContentFiltering($grep, $this->contains);
+ $this->buildContentFiltering($grep, $this->notContains, true);
+ }
+
+ if ($useSort) {
+ $this->buildSorting($command, $this->sort);
+ }
+
+ $command->setErrorHandler(
+ $this->ignoreUnreadableDirs
+ // If directory is unreadable and finder is set to ignore it, `stderr` is ignored.
+ ? function ($stderr) { return; }
+ : function ($stderr) { throw new AccessDeniedException($stderr); }
+ );
+
+ $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
+ $iterator = new Iterator\FilePathsIterator($paths, $dir);
+
+ if ($this->exclude) {
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
+ }
+
+ if (!$useGrep && ($this->contains || $this->notContains)) {
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
+ }
+
+ if ($this->filters) {
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
+ }
+
+ if (!$useSort && $this->sort) {
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
+ $iterator = $iteratorAggregate->getIterator();
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return $this->shell->testCommand('find');
+ }
+
+ /**
+ * @param Command $command
+ * @param string $dir
+ *
+ * @return Command
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ return $command
+ ->ins('find')
+ ->add('find ')
+ ->arg($dir)
+ ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions
+ }
+
+ /**
+ * @param Command $command
+ * @param string[] $names
+ * @param bool $not
+ */
+ private function buildNamesFiltering(Command $command, array $names, $not = false)
+ {
+ if (0 === count($names)) {
+ return;
+ }
+
+ $command->add($not ? '-not' : null)->cmd('(');
+
+ foreach ($names as $i => $name) {
+ $expr = Expression::create($name);
+
+ // Find does not support expandable globs ("*.{a,b}" syntax).
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
+ }
+
+ // Fixes 'not search' and 'full path matching' regex problems.
+ // - Jokers '.' are replaced by [^/].
+ // - We add '[^/]*' before and after regex (if no ^|$ flags are present).
+ if ($expr->isRegex()) {
+ $regex = $expr->getRegex();
+ $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
+ ->setStartFlag(false)
+ ->setStartJoker(true)
+ ->replaceJokers('[^/]');
+ if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
+ $regex->setEndJoker(false)->append('[^/]*');
+ }
+ }
+
+ $command
+ ->add($i > 0 ? '-or' : null)
+ ->add($expr->isRegex()
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
+ : ($expr->isCaseSensitive() ? '-name' : '-iname')
+ )
+ ->arg($expr->renderPattern());
+ }
+
+ $command->cmd(')');
+ }
+
+ /**
+ * @param Command $command
+ * @param string $dir
+ * @param string[] $paths
+ * @param bool $not
+ */
+ private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
+ {
+ if (0 === count($paths)) {
+ return;
+ }
+
+ $command->add($not ? '-not' : null)->cmd('(');
+
+ foreach ($paths as $i => $path) {
+ $expr = Expression::create($path);
+
+ // Find does not support expandable globs ("*.{a,b}" syntax).
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
+ }
+
+ // Fixes 'not search' regex problems.
+ if ($expr->isRegex()) {
+ $regex = $expr->getRegex();
+ $regex->prepend($regex->hasStartFlag() ? $dir.DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
+ } else {
+ $expr->prepend('*')->append('*');
+ }
+
+ $command
+ ->add($i > 0 ? '-or' : null)
+ ->add($expr->isRegex()
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
+ : ($expr->isCaseSensitive() ? '-path' : '-ipath')
+ )
+ ->arg($expr->renderPattern());
+ }
+
+ $command->cmd(')');
+ }
+
+ /**
+ * @param Command $command
+ * @param NumberComparator[] $sizes
+ */
+ private function buildSizesFiltering(Command $command, array $sizes)
+ {
+ foreach ($sizes as $i => $size) {
+ $command->add($i > 0 ? '-and' : null);
+
+ switch ($size->getOperator()) {
+ case '<=':
+ $command->add('-size -'.($size->getTarget() + 1).'c');
+ break;
+ case '>=':
+ $command->add('-size +'. ($size->getTarget() - 1).'c');
+ break;
+ case '>':
+ $command->add('-size +'.$size->getTarget().'c');
+ break;
+ case '!=':
+ $command->add('-size -'.$size->getTarget().'c');
+ $command->add('-size +'.$size->getTarget().'c');
+ case '<':
+ default:
+ $command->add('-size -'.$size->getTarget().'c');
+ }
+ }
+ }
+
+ /**
+ * @param Command $command
+ * @param DateComparator[] $dates
+ */
+ private function buildDatesFiltering(Command $command, array $dates)
+ {
+ foreach ($dates as $i => $date) {
+ $command->add($i > 0 ? '-and' : null);
+
+ $mins = (int) round((time()-$date->getTarget()) / 60);
+
+ if (0 > $mins) {
+ // mtime is in the future
+ $command->add(' -mmin -0');
+ // we will have no result so we don't need to continue
+ return;
+ }
+
+ switch ($date->getOperator()) {
+ case '<=':
+ $command->add('-mmin +'.($mins - 1));
+ break;
+ case '>=':
+ $command->add('-mmin -'.($mins + 1));
+ break;
+ case '>':
+ $command->add('-mmin -'.$mins);
+ break;
+ case '!=':
+ $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
+ break;
+ case '<':
+ default:
+ $command->add('-mmin +'.$mins);
+ }
+ }
+ }
+
+ /**
+ * @param Command $command
+ * @param string $sort
+ *
+ * @throws \InvalidArgumentException
+ */
+ private function buildSorting(Command $command, $sort)
+ {
+ $this->buildFormatSorting($command, $sort);
+ }
+
+ /**
+ * @param Command $command
+ * @param string $sort
+ */
+ abstract protected function buildFormatSorting(Command $command, $sort);
+
+ /**
+ * @param Command $command
+ * @param array $contains
+ * @param bool $not
+ */
+ abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php
new file mode 100644
index 0000000..e25fc3e
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php
@@ -0,0 +1,144 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+/**
+ * @author Jean-François Simon
+ */
+interface AdapterInterface
+{
+ /**
+ * @param bool $followLinks
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setFollowLinks($followLinks);
+
+ /**
+ * @param int $mode
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setMode($mode);
+
+ /**
+ * @param array $exclude
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setExclude(array $exclude);
+
+ /**
+ * @param array $depths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setDepths(array $depths);
+
+ /**
+ * @param array $names
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNames(array $names);
+
+ /**
+ * @param array $notNames
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotNames(array $notNames);
+
+ /**
+ * @param array $contains
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setContains(array $contains);
+
+ /**
+ * @param array $notContains
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotContains(array $notContains);
+
+ /**
+ * @param array $sizes
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setSizes(array $sizes);
+
+ /**
+ * @param array $dates
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setDates(array $dates);
+
+ /**
+ * @param array $filters
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setFilters(array $filters);
+
+ /**
+ * @param \Closure|int $sort
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setSort($sort);
+
+ /**
+ * @param array $paths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setPath(array $paths);
+
+ /**
+ * @param array $notPaths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotPath(array $notPaths);
+
+ /**
+ * @param bool $ignore
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function ignoreUnreadableDirs($ignore = true);
+
+ /**
+ * @param string $dir
+ *
+ * @return \Iterator Result iterator
+ */
+ public function searchInDirectory($dir);
+
+ /**
+ * Tests adapter support for current platform.
+ *
+ * @return bool
+ */
+ public function isSupported();
+
+ /**
+ * Returns adapter name.
+ *
+ * @return string
+ */
+ public function getName();
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php
new file mode 100644
index 0000000..4a25bae
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php
@@ -0,0 +1,103 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * Shell engine implementation using BSD find command.
+ *
+ * @author Jean-François Simon
+ */
+class BsdFindAdapter extends AbstractFindAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'bsd_find';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFormatSorting(Command $command, $sort)
+ {
+ switch ($sort) {
+ case SortableIterator::SORT_BY_NAME:
+ $command->ins('sort')->add('| sort');
+
+ return;
+ case SortableIterator::SORT_BY_TYPE:
+ $format = '%HT';
+ break;
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
+ $format = '%a';
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME:
+ $format = '%c';
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
+ $format = '%m';
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
+ }
+
+ $command
+ ->add('-print0 | xargs -0 stat -f')
+ ->arg($format.'%t%N')
+ ->add('| sort | cut -f 2');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);
+
+ return $command;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
+ {
+ foreach ($contains as $contain) {
+ $expr = Expression::create($contain);
+
+ // todo: avoid forking process for each $pattern by using multiple -e options
+ $command
+ ->add('| grep -v \'^$\'')
+ ->add('| xargs -I{} grep -I')
+ ->add($expr->isCaseSensitive() ? null : '-i')
+ ->add($not ? '-L' : '-l')
+ ->add('-Ee')->arg($expr->renderPattern())
+ ->add('{}')
+ ;
+ }
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php
new file mode 100644
index 0000000..b72451e
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php
@@ -0,0 +1,104 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * Shell engine implementation using GNU find command.
+ *
+ * @author Jean-François Simon
+ */
+class GnuFindAdapter extends AbstractFindAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'gnu_find';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFormatSorting(Command $command, $sort)
+ {
+ switch ($sort) {
+ case SortableIterator::SORT_BY_NAME:
+ $command->ins('sort')->add('| sort');
+
+ return;
+ case SortableIterator::SORT_BY_TYPE:
+ $format = '%y';
+ break;
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
+ $format = '%A@';
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME:
+ $format = '%C@';
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
+ $format = '%T@';
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
+ }
+
+ $command
+ ->get('find')
+ ->add('-printf')
+ ->arg($format.' %h/%f\\n')
+ ->add('| sort | cut')
+ ->arg('-d ')
+ ->arg('-f2-')
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
+ {
+ foreach ($contains as $contain) {
+ $expr = Expression::create($contain);
+
+ // todo: avoid forking process for each $pattern by using multiple -e options
+ $command
+ ->add('| xargs -I{} -r grep -I')
+ ->add($expr->isCaseSensitive() ? null : '-i')
+ ->add($not ? '-L' : '-l')
+ ->add('-Ee')->arg($expr->renderPattern())
+ ->add('{}')
+ ;
+ }
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php
new file mode 100644
index 0000000..378a26a
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php
@@ -0,0 +1,98 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Iterator;
+
+/**
+ * PHP finder engine implementation.
+ *
+ * @author Jean-François Simon
+ */
+class PhpAdapter extends AbstractAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
+
+ if ($this->followLinks) {
+ $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
+ }
+
+ $iterator = new \RecursiveIteratorIterator(
+ new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+
+ if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
+ $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
+ }
+
+ if ($this->mode) {
+ $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
+ }
+
+ if ($this->exclude) {
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
+ }
+
+ if ($this->names || $this->notNames) {
+ $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
+ }
+
+ if ($this->contains || $this->notContains) {
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
+ }
+
+ if ($this->sizes) {
+ $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
+ }
+
+ if ($this->dates) {
+ $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
+ }
+
+ if ($this->filters) {
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
+ }
+
+ if ($this->sort) {
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
+ $iterator = $iteratorAggregate->getIterator();
+ }
+
+ if ($this->paths || $this->notPaths) {
+ $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'php';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md b/core/vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md
new file mode 100644
index 0000000..7ad2308
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md
@@ -0,0 +1,30 @@
+CHANGELOG
+=========
+
+2.3.0
+-----
+
+ * added a way to ignore unreadable directories (via Finder::ignoreUnreadableDirs())
+ * unified the way subfolders that are not executable are handled by always throwing an AccessDeniedException exception
+
+2.2.0
+-----
+
+ * added Finder::path() and Finder::notPath() methods
+ * added finder adapters to improve performance on specific platforms
+ * added support for wildcard characters (glob patterns) in the paths passed
+ to Finder::in()
+
+2.1.0
+-----
+
+ * added Finder::sortByAccessedTime(), Finder::sortByChangedTime(), and
+ Finder::sortByModifiedTime()
+ * added Countable to Finder
+ * added support for an array of directories as an argument to
+ Finder::exclude()
+ * added searching based on the file content via Finder::contains() and
+ Finder::notContains()
+ * added support for the != operator in the Comparator
+ * [BC BREAK] filter expressions (used for file name and content) are no more
+ considered as regexps but glob patterns when they are enclosed in '*' or '?'
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php
new file mode 100644
index 0000000..4f5e1ff
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php
@@ -0,0 +1,98 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Comparator;
+
+/**
+ * Comparator.
+ *
+ * @author Fabien Potencier
+ */
+class Comparator
+{
+ private $target;
+ private $operator = '==';
+
+ /**
+ * Gets the target value.
+ *
+ * @return string The target value
+ */
+ public function getTarget()
+ {
+ return $this->target;
+ }
+
+ /**
+ * Sets the target value.
+ *
+ * @param string $target The target value
+ */
+ public function setTarget($target)
+ {
+ $this->target = $target;
+ }
+
+ /**
+ * Gets the comparison operator.
+ *
+ * @return string The operator
+ */
+ public function getOperator()
+ {
+ return $this->operator;
+ }
+
+ /**
+ * Sets the comparison operator.
+ *
+ * @param string $operator A valid operator
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setOperator($operator)
+ {
+ if (!$operator) {
+ $operator = '==';
+ }
+
+ if (!in_array($operator, array('>', '<', '>=', '<=', '==', '!='))) {
+ throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
+ }
+
+ $this->operator = $operator;
+ }
+
+ /**
+ * Tests against the target.
+ *
+ * @param mixed $test A test value
+ *
+ * @return bool
+ */
+ public function test($test)
+ {
+ switch ($this->operator) {
+ case '>':
+ return $test > $this->target;
+ case '>=':
+ return $test >= $this->target;
+ case '<':
+ return $test < $this->target;
+ case '<=':
+ return $test <= $this->target;
+ case '!=':
+ return $test != $this->target;
+ }
+
+ return $test == $this->target;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php
new file mode 100644
index 0000000..9de444f
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php
@@ -0,0 +1,54 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Comparator;
+
+/**
+ * DateCompare compiles date comparisons.
+ *
+ * @author Fabien Potencier
+ */
+class DateComparator extends Comparator
+{
+
+ /**
+ * Constructor.
+ *
+ * @param string $test A comparison string
+ *
+ * @throws \InvalidArgumentException If the test is not understood
+ */
+ public function __construct($test)
+ {
+ if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) {
+ throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test));
+ }
+
+ try {
+ $date = new \DateTime($matches[2]);
+ $target = $date->format('U');
+ } catch (\Exception $e) {
+ throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
+ }
+
+ $operator = isset($matches[1]) ? $matches[1] : '==';
+ if ('since' === $operator || 'after' === $operator) {
+ $operator = '>';
+ }
+
+ if ('until' === $operator || 'before' === $operator) {
+ $operator = '<';
+ }
+
+ $this->setOperator($operator);
+ $this->setTarget($target);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php
new file mode 100644
index 0000000..955cc67
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php
@@ -0,0 +1,82 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Comparator;
+
+/**
+ * NumberComparator compiles a simple comparison to an anonymous
+ * subroutine, which you can call with a value to be tested again.
+ *
+ * Now this would be very pointless, if NumberCompare didn't understand
+ * magnitudes.
+ *
+ * The target value may use magnitudes of kilobytes (k, ki),
+ * megabytes (m, mi), or gigabytes (g, gi). Those suffixed
+ * with an i use the appropriate 2**n version in accordance with the
+ * IEC standard: http://physics.nist.gov/cuu/Units/binary.html
+ *
+ * Based on the Perl Number::Compare module.
+ *
+ * @author Fabien Potencier PHP port
+ * @author Richard Clamp Perl version
+ *
+ * @copyright 2004-2005 Fabien Potencier
+ * @copyright 2002 Richard Clamp
+ *
+ * @see http://physics.nist.gov/cuu/Units/binary.html
+ */
+class NumberComparator extends Comparator
+{
+ /**
+ * Constructor.
+ *
+ * @param string $test A comparison string
+ *
+ * @throws \InvalidArgumentException If the test is not understood
+ */
+ public function __construct($test)
+ {
+ if (!preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) {
+ throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test));
+ }
+
+ $target = $matches[2];
+ if (!is_numeric($target)) {
+ throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target));
+ }
+ if (isset($matches[3])) {
+ // magnitude
+ switch (strtolower($matches[3])) {
+ case 'k':
+ $target *= 1000;
+ break;
+ case 'ki':
+ $target *= 1024;
+ break;
+ case 'm':
+ $target *= 1000000;
+ break;
+ case 'mi':
+ $target *= 1024*1024;
+ break;
+ case 'g':
+ $target *= 1000000000;
+ break;
+ case 'gi':
+ $target *= 1024*1024*1024;
+ break;
+ }
+ }
+
+ $this->setTarget($target);
+ $this->setOperator(isset($matches[1]) ? $matches[1] : '==');
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php
new file mode 100644
index 0000000..ee195ea
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+/**
+ * @author Jean-François Simon
+ */
+class AccessDeniedException extends \UnexpectedValueException
+{
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php
new file mode 100644
index 0000000..15fa221
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+use Symfony\Component\Finder\Adapter\AdapterInterface;
+
+/**
+ * Base exception for all adapter failures.
+ *
+ * @author Jean-François Simon
+ */
+class AdapterFailureException extends \RuntimeException implements ExceptionInterface
+{
+ /**
+ * @var \Symfony\Component\Finder\Adapter\AdapterInterface
+ */
+ private $adapter;
+
+ /**
+ * @param AdapterInterface $adapter
+ * @param string|null $message
+ * @param \Exception|null $previous
+ */
+ public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null)
+ {
+ $this->adapter = $adapter;
+ parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAdapter()
+ {
+ return $this->adapter;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..bff0214
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+/**
+ * @author Jean-François Simon
+ */
+interface ExceptionInterface
+{
+ /**
+ * @return \Symfony\Component\Finder\Adapter\AdapterInterface
+ */
+ public function getAdapter();
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php
new file mode 100644
index 0000000..3663112
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+/**
+ * @author Jean-François Simon
+ */
+class OperationNotPermitedException extends AdapterFailureException
+{
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php
new file mode 100644
index 0000000..2658f6a
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php
@@ -0,0 +1,45 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+use Symfony\Component\Finder\Adapter\AdapterInterface;
+use Symfony\Component\Finder\Shell\Command;
+
+/**
+ * @author Jean-François Simon
+ */
+class ShellCommandFailureException extends AdapterFailureException
+{
+ /**
+ * @var Command
+ */
+ private $command;
+
+ /**
+ * @param AdapterInterface $adapter
+ * @param Command $command
+ * @param \Exception|null $previous
+ */
+ public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null)
+ {
+ $this->command = $command;
+ parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous);
+ }
+
+ /**
+ * @return Command
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php
new file mode 100644
index 0000000..8559b33
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php
@@ -0,0 +1,146 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon
+ */
+class Expression implements ValueInterface
+{
+ const TYPE_REGEX = 1;
+ const TYPE_GLOB = 2;
+
+ /**
+ * @var ValueInterface
+ */
+ private $value;
+
+ /**
+ * @param string $expr
+ *
+ * @return Expression
+ */
+ public static function create($expr)
+ {
+ return new self($expr);
+ }
+
+ /**
+ * @param string $expr
+ */
+ public function __construct($expr)
+ {
+ try {
+ $this->value = Regex::create($expr);
+ } catch (\InvalidArgumentException $e) {
+ $this->value = new Glob($expr);
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render()
+ {
+ return $this->value->render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function renderPattern()
+ {
+ return $this->value->renderPattern();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isCaseSensitive()
+ {
+ return $this->value->isCaseSensitive();
+ }
+
+ /**
+ * @return int
+ */
+ public function getType()
+ {
+ return $this->value->getType();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepend($expr)
+ {
+ $this->value->prepend($expr);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function append($expr)
+ {
+ $this->value->append($expr);
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRegex()
+ {
+ return self::TYPE_REGEX === $this->value->getType();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isGlob()
+ {
+ return self::TYPE_GLOB === $this->value->getType();
+ }
+
+ /**
+ * @throws \LogicException
+ *
+ * @return Glob
+ */
+ public function getGlob()
+ {
+ if (self::TYPE_GLOB !== $this->value->getType()) {
+ throw new \LogicException('Regex can\'t be transformed to glob.');
+ }
+
+ return $this->value;
+ }
+
+ /**
+ * @return Regex
+ */
+ public function getRegex()
+ {
+ return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex();
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php
new file mode 100644
index 0000000..3023cee
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php
@@ -0,0 +1,157 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon
+ */
+class Glob implements ValueInterface
+{
+ /**
+ * @var string
+ */
+ private $pattern;
+
+ /**
+ * @param string $pattern
+ */
+ public function __construct($pattern)
+ {
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render()
+ {
+ return $this->pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function renderPattern()
+ {
+ return $this->pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getType()
+ {
+ return Expression::TYPE_GLOB;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isCaseSensitive()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepend($expr)
+ {
+ $this->pattern = $expr.$this->pattern;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function append($expr)
+ {
+ $this->pattern .= $expr;
+
+ return $this;
+ }
+
+ /**
+ * Tests if glob is expandable ("*.{a,b}" syntax).
+ *
+ * @return bool
+ */
+ public function isExpandable()
+ {
+ return false !== strpos($this->pattern, '{')
+ && false !== strpos($this->pattern, '}');
+ }
+
+ /**
+ * @param bool $strictLeadingDot
+ * @param bool $strictWildcardSlash
+ *
+ * @return Regex
+ */
+ public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true)
+ {
+ $firstByte = true;
+ $escaping = false;
+ $inCurlies = 0;
+ $regex = '';
+ $sizeGlob = strlen($this->pattern);
+ for ($i = 0; $i < $sizeGlob; $i++) {
+ $car = $this->pattern[$i];
+ if ($firstByte) {
+ if ($strictLeadingDot && '.' !== $car) {
+ $regex .= '(?=[^\.])';
+ }
+
+ $firstByte = false;
+ }
+
+ if ('/' === $car) {
+ $firstByte = true;
+ }
+
+ if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
+ $regex .= "\\$car";
+ } elseif ('*' === $car) {
+ $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
+ } elseif ('?' === $car) {
+ $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
+ } elseif ('{' === $car) {
+ $regex .= $escaping ? '\\{' : '(';
+ if (!$escaping) {
+ ++$inCurlies;
+ }
+ } elseif ('}' === $car && $inCurlies) {
+ $regex .= $escaping ? '}' : ')';
+ if (!$escaping) {
+ --$inCurlies;
+ }
+ } elseif (',' === $car && $inCurlies) {
+ $regex .= $escaping ? ',' : '|';
+ } elseif ('\\' === $car) {
+ if ($escaping) {
+ $regex .= '\\\\';
+ $escaping = false;
+ } else {
+ $escaping = true;
+ }
+
+ continue;
+ } else {
+ $regex .= $car;
+ }
+ $escaping = false;
+ }
+
+ return new Regex('^'.$regex.'$');
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php
new file mode 100644
index 0000000..2e8f507
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php
@@ -0,0 +1,321 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon
+ */
+class Regex implements ValueInterface
+{
+ const START_FLAG = '^';
+ const END_FLAG = '$';
+ const BOUNDARY = '~';
+ const JOKER = '.*';
+ const ESCAPING = '\\';
+
+ /**
+ * @var string
+ */
+ private $pattern;
+
+ /**
+ * @var array
+ */
+ private $options;
+
+ /**
+ * @var bool
+ */
+ private $startFlag;
+
+ /**
+ * @var bool
+ */
+ private $endFlag;
+
+ /**
+ * @var bool
+ */
+ private $startJoker;
+
+ /**
+ * @var bool
+ */
+ private $endJoker;
+
+ /**
+ * @param string $expr
+ *
+ * @return Regex
+ *
+ * @throws \InvalidArgumentException
+ */
+ public static function create($expr)
+ {
+ if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
+ $start = substr($m[1], 0, 1);
+ $end = substr($m[1], -1);
+
+ if (
+ ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
+ || ($start === '{' && $end === '}')
+ || ($start === '(' && $end === ')')
+ ) {
+ return new self(substr($m[1], 1, -1), $m[2], $end);
+ }
+ }
+
+ throw new \InvalidArgumentException('Given expression is not a regex.');
+ }
+
+ /**
+ * @param string $pattern
+ * @param string $options
+ * @param string $delimiter
+ */
+ public function __construct($pattern, $options = '', $delimiter = null)
+ {
+ if (null !== $delimiter) {
+ // removes delimiter escaping
+ $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
+ }
+
+ $this->parsePattern($pattern);
+ $this->options = $options;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render()
+ {
+ return self::BOUNDARY
+ .$this->renderPattern()
+ .self::BOUNDARY
+ .$this->options;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function renderPattern()
+ {
+ return ($this->startFlag ? self::START_FLAG : '')
+ .($this->startJoker ? self::JOKER : '')
+ .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
+ .($this->endJoker ? self::JOKER : '')
+ .($this->endFlag ? self::END_FLAG : '');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isCaseSensitive()
+ {
+ return !$this->hasOption('i');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getType()
+ {
+ return Expression::TYPE_REGEX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepend($expr)
+ {
+ $this->pattern = $expr.$this->pattern;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function append($expr)
+ {
+ $this->pattern .= $expr;
+
+ return $this;
+ }
+
+ /**
+ * @param string $option
+ *
+ * @return bool
+ */
+ public function hasOption($option)
+ {
+ return false !== strpos($this->options, $option);
+ }
+
+ /**
+ * @param string $option
+ *
+ * @return Regex
+ */
+ public function addOption($option)
+ {
+ if (!$this->hasOption($option)) {
+ $this->options.= $option;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param string $option
+ *
+ * @return Regex
+ */
+ public function removeOption($option)
+ {
+ $this->options = str_replace($option, '', $this->options);
+
+ return $this;
+ }
+
+ /**
+ * @param bool $startFlag
+ *
+ * @return Regex
+ */
+ public function setStartFlag($startFlag)
+ {
+ $this->startFlag = $startFlag;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasStartFlag()
+ {
+ return $this->startFlag;
+ }
+
+ /**
+ * @param bool $endFlag
+ *
+ * @return Regex
+ */
+ public function setEndFlag($endFlag)
+ {
+ $this->endFlag = (bool) $endFlag;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasEndFlag()
+ {
+ return $this->endFlag;
+ }
+
+ /**
+ * @param bool $startJoker
+ *
+ * @return Regex
+ */
+ public function setStartJoker($startJoker)
+ {
+ $this->startJoker = $startJoker;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasStartJoker()
+ {
+ return $this->startJoker;
+ }
+
+ /**
+ * @param bool $endJoker
+ *
+ * @return Regex
+ */
+ public function setEndJoker($endJoker)
+ {
+ $this->endJoker = (bool) $endJoker;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasEndJoker()
+ {
+ return $this->endJoker;
+ }
+
+ /**
+ * @param array $replacement
+ *
+ * @return Regex
+ */
+ public function replaceJokers($replacement)
+ {
+ $replace = function ($subject) use ($replacement) {
+ $subject = $subject[0];
+ $replace = 0 === substr_count($subject, '\\') % 2;
+
+ return $replace ? str_replace('.', $replacement, $subject) : $subject;
+ };
+
+ $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
+
+ return $this;
+ }
+
+ /**
+ * @param string $pattern
+ */
+ private function parsePattern($pattern)
+ {
+ if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
+ $pattern = substr($pattern, 1);
+ }
+
+ if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
+ $pattern = substr($pattern, 2);
+ }
+
+ if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
+ $pattern = substr($pattern, 0, -1);
+ }
+
+ if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
+ $pattern = substr($pattern, 0, -2);
+ }
+
+ $this->pattern = $pattern;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php
new file mode 100644
index 0000000..34ce0e7
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon
+ */
+interface ValueInterface
+{
+ /**
+ * Renders string representation of expression.
+ *
+ * @return string
+ */
+ public function render();
+
+ /**
+ * Renders string representation of pattern.
+ *
+ * @return string
+ */
+ public function renderPattern();
+
+ /**
+ * Returns value case sensitivity.
+ *
+ * @return bool
+ */
+ public function isCaseSensitive();
+
+ /**
+ * Returns expression type.
+ *
+ * @return int
+ */
+ public function getType();
+
+ /**
+ * @param string $expr
+ *
+ * @return ValueInterface
+ */
+ public function prepend($expr);
+
+ /**
+ * @param string $expr
+ *
+ * @return ValueInterface
+ */
+ public function append($expr);
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Finder.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Finder.php
new file mode 100644
index 0000000..db4d851
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Finder.php
@@ -0,0 +1,829 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder;
+
+use Symfony\Component\Finder\Adapter\AdapterInterface;
+use Symfony\Component\Finder\Adapter\GnuFindAdapter;
+use Symfony\Component\Finder\Adapter\BsdFindAdapter;
+use Symfony\Component\Finder\Adapter\PhpAdapter;
+use Symfony\Component\Finder\Exception\ExceptionInterface;
+
+/**
+ * Finder allows to build rules to find files and directories.
+ *
+ * It is a thin wrapper around several specialized iterator classes.
+ *
+ * All rules may be invoked several times.
+ *
+ * All methods return the current Finder object to allow easy chaining:
+ *
+ * $finder = Finder::create()->files()->name('*.php')->in(__DIR__);
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class Finder implements \IteratorAggregate, \Countable
+{
+ const IGNORE_VCS_FILES = 1;
+ const IGNORE_DOT_FILES = 2;
+
+ private $mode = 0;
+ private $names = array();
+ private $notNames = array();
+ private $exclude = array();
+ private $filters = array();
+ private $depths = array();
+ private $sizes = array();
+ private $followLinks = false;
+ private $sort = false;
+ private $ignore = 0;
+ private $dirs = array();
+ private $dates = array();
+ private $iterators = array();
+ private $contains = array();
+ private $notContains = array();
+ private $adapters = array();
+ private $paths = array();
+ private $notPaths = array();
+ private $ignoreUnreadableDirs = false;
+
+ private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
+
+ $this
+ ->addAdapter(new GnuFindAdapter())
+ ->addAdapter(new BsdFindAdapter())
+ ->addAdapter(new PhpAdapter(), -50)
+ ->setAdapter('php')
+ ;
+ }
+
+ /**
+ * Creates a new Finder.
+ *
+ * @return Finder A new Finder instance
+ *
+ * @api
+ */
+ public static function create()
+ {
+ return new static();
+ }
+
+ /**
+ * Registers a finder engine implementation.
+ *
+ * @param AdapterInterface $adapter An adapter instance
+ * @param int $priority Highest is selected first
+ *
+ * @return Finder The current Finder instance
+ */
+ public function addAdapter(AdapterInterface $adapter, $priority = 0)
+ {
+ $this->adapters[$adapter->getName()] = array(
+ 'adapter' => $adapter,
+ 'priority' => $priority,
+ 'selected' => false,
+ );
+
+ return $this->sortAdapters();
+ }
+
+ /**
+ * Sets the selected adapter to the best one according to the current platform the code is run on.
+ *
+ * @return Finder The current Finder instance
+ */
+ public function useBestAdapter()
+ {
+ $this->resetAdapterSelection();
+
+ return $this->sortAdapters();
+ }
+
+ /**
+ * Selects the adapter to use.
+ *
+ * @param string $name
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return Finder The current Finder instance
+ */
+ public function setAdapter($name)
+ {
+ if (!isset($this->adapters[$name])) {
+ throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
+ }
+
+ $this->resetAdapterSelection();
+ $this->adapters[$name]['selected'] = true;
+
+ return $this->sortAdapters();
+ }
+
+ /**
+ * Removes all adapters registered in the finder.
+ *
+ * @return Finder The current Finder instance
+ */
+ public function removeAdapters()
+ {
+ $this->adapters = array();
+
+ return $this;
+ }
+
+ /**
+ * Returns registered adapters ordered by priority without extra information.
+ *
+ * @return AdapterInterface[]
+ */
+ public function getAdapters()
+ {
+ return array_values(array_map(function (array $adapter) {
+ return $adapter['adapter'];
+ }, $this->adapters));
+ }
+
+ /**
+ * Restricts the matching to directories only.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @api
+ */
+ public function directories()
+ {
+ $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
+
+ return $this;
+ }
+
+ /**
+ * Restricts the matching to files only.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @api
+ */
+ public function files()
+ {
+ $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests for the directory depth.
+ *
+ * Usage:
+ *
+ * $finder->depth('> 1') // the Finder will start matching at level 1.
+ * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
+ *
+ * @param int $level The depth level expression
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\DepthRangeFilterIterator
+ * @see Symfony\Component\Finder\Comparator\NumberComparator
+ *
+ * @api
+ */
+ public function depth($level)
+ {
+ $this->depths[] = new Comparator\NumberComparator($level);
+
+ return $this;
+ }
+
+ /**
+ * Adds tests for file dates (last modified).
+ *
+ * The date must be something that strtotime() is able to parse:
+ *
+ * $finder->date('since yesterday');
+ * $finder->date('until 2 days ago');
+ * $finder->date('> now - 2 hours');
+ * $finder->date('>= 2005-10-15');
+ *
+ * @param string $date A date rage string
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see strtotime
+ * @see Symfony\Component\Finder\Iterator\DateRangeFilterIterator
+ * @see Symfony\Component\Finder\Comparator\DateComparator
+ *
+ * @api
+ */
+ public function date($date)
+ {
+ $this->dates[] = new Comparator\DateComparator($date);
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that files must match.
+ *
+ * You can use patterns (delimited with / sign), globs or simple strings.
+ *
+ * $finder->name('*.php')
+ * $finder->name('/\.php$/') // same as above
+ * $finder->name('test.php')
+ *
+ * @param string $pattern A pattern (a regexp, a glob, or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
+ *
+ * @api
+ */
+ public function name($pattern)
+ {
+ $this->names[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that files must not match.
+ *
+ * @param string $pattern A pattern (a regexp, a glob, or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
+ *
+ * @api
+ */
+ public function notName($pattern)
+ {
+ $this->notNames[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests that file contents must match.
+ *
+ * Strings or PCRE patterns can be used:
+ *
+ * $finder->contains('Lorem ipsum')
+ * $finder->contains('/Lorem ipsum/i')
+ *
+ * @param string $pattern A pattern (string or regexp)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\FilecontentFilterIterator
+ */
+ public function contains($pattern)
+ {
+ $this->contains[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests that file contents must not match.
+ *
+ * Strings or PCRE patterns can be used:
+ *
+ * $finder->notContains('Lorem ipsum')
+ * $finder->notContains('/Lorem ipsum/i')
+ *
+ * @param string $pattern A pattern (string or regexp)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\FilecontentFilterIterator
+ */
+ public function notContains($pattern)
+ {
+ $this->notContains[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that filenames must match.
+ *
+ * You can use patterns (delimited with / sign) or simple strings.
+ *
+ * $finder->path('some/special/dir')
+ * $finder->path('/some\/special\/dir/') // same as above
+ *
+ * Use only / as dirname separator.
+ *
+ * @param string $pattern A pattern (a regexp or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
+ */
+ public function path($pattern)
+ {
+ $this->paths[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that filenames must not match.
+ *
+ * You can use patterns (delimited with / sign) or simple strings.
+ *
+ * $finder->notPath('some/special/dir')
+ * $finder->notPath('/some\/special\/dir/') // same as above
+ *
+ * Use only / as dirname separator.
+ *
+ * @param string $pattern A pattern (a regexp or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
+ */
+ public function notPath($pattern)
+ {
+ $this->notPaths[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests for file sizes.
+ *
+ * $finder->size('> 10K');
+ * $finder->size('<= 1Ki');
+ * $finder->size(4);
+ *
+ * @param string $size A size range string
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\SizeRangeFilterIterator
+ * @see Symfony\Component\Finder\Comparator\NumberComparator
+ *
+ * @api
+ */
+ public function size($size)
+ {
+ $this->sizes[] = new Comparator\NumberComparator($size);
+
+ return $this;
+ }
+
+ /**
+ * Excludes directories.
+ *
+ * @param string|array $dirs A directory path or an array of directories
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator
+ *
+ * @api
+ */
+ public function exclude($dirs)
+ {
+ $this->exclude = array_merge($this->exclude, (array) $dirs);
+
+ return $this;
+ }
+
+ /**
+ * Excludes "hidden" directories and files (starting with a dot).
+ *
+ * @param bool $ignoreDotFiles Whether to exclude "hidden" files or not
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator
+ *
+ * @api
+ */
+ public function ignoreDotFiles($ignoreDotFiles)
+ {
+ if ($ignoreDotFiles) {
+ $this->ignore = $this->ignore | static::IGNORE_DOT_FILES;
+ } else {
+ $this->ignore = $this->ignore & ~static::IGNORE_DOT_FILES;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Forces the finder to ignore version control directories.
+ *
+ * @param bool $ignoreVCS Whether to exclude VCS files or not
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator
+ *
+ * @api
+ */
+ public function ignoreVCS($ignoreVCS)
+ {
+ if ($ignoreVCS) {
+ $this->ignore = $this->ignore | static::IGNORE_VCS_FILES;
+ } else {
+ $this->ignore = $this->ignore & ~static::IGNORE_VCS_FILES;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds VCS patterns.
+ *
+ * @see ignoreVCS
+ *
+ * @param string|string[] $pattern VCS patterns to ignore
+ */
+ public static function addVCSPattern($pattern)
+ {
+ foreach ((array) $pattern as $p) {
+ self::$vcsPatterns[] = $p;
+ }
+
+ self::$vcsPatterns = array_unique(self::$vcsPatterns);
+ }
+
+ /**
+ * Sorts files and directories by an anonymous function.
+ *
+ * The anonymous function receives two \SplFileInfo instances to compare.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @param \Closure $closure An anonymous function
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\SortableIterator
+ *
+ * @api
+ */
+ public function sort(\Closure $closure)
+ {
+ $this->sort = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by name.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\SortableIterator
+ *
+ * @api
+ */
+ public function sortByName()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by type (directories before files), then by name.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\SortableIterator
+ *
+ * @api
+ */
+ public function sortByType()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by the last accessed time.
+ *
+ * This is the time that the file was last accessed, read or written to.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\SortableIterator
+ *
+ * @api
+ */
+ public function sortByAccessedTime()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by the last inode changed time.
+ *
+ * This is the time that the inode information was last modified (permissions, owner, group or other metadata).
+ *
+ * On Windows, since inode is not available, changed time is actually the file creation time.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\SortableIterator
+ *
+ * @api
+ */
+ public function sortByChangedTime()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by the last modified time.
+ *
+ * This is the last time the actual contents of the file were last modified.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\SortableIterator
+ *
+ * @api
+ */
+ public function sortByModifiedTime()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
+
+ return $this;
+ }
+
+ /**
+ * Filters the iterator with an anonymous function.
+ *
+ * The anonymous function receives a \SplFileInfo and must return false
+ * to remove files.
+ *
+ * @param \Closure $closure An anonymous function
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see Symfony\Component\Finder\Iterator\CustomFilterIterator
+ *
+ * @api
+ */
+ public function filter(\Closure $closure)
+ {
+ $this->filters[] = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Forces the following of symlinks.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @api
+ */
+ public function followLinks()
+ {
+ $this->followLinks = true;
+
+ return $this;
+ }
+
+ /**
+ * Tells finder to ignore unreadable directories.
+ *
+ * By default, scanning unreadable directories content throws an AccessDeniedException.
+ *
+ * @param bool $ignore
+ *
+ * @return Finder The current Finder instance
+ */
+ public function ignoreUnreadableDirs($ignore = true)
+ {
+ $this->ignoreUnreadableDirs = (bool) $ignore;
+
+ return $this;
+ }
+
+ /**
+ * Searches files and directories which match defined rules.
+ *
+ * @param string|array $dirs A directory path or an array of directories
+ *
+ * @return Finder The current Finder instance
+ *
+ * @throws \InvalidArgumentException if one of the directories does not exist
+ *
+ * @api
+ */
+ public function in($dirs)
+ {
+ $resolvedDirs = array();
+
+ foreach ((array) $dirs as $dir) {
+ if (is_dir($dir)) {
+ $resolvedDirs[] = $dir;
+ } elseif ($glob = glob($dir, GLOB_ONLYDIR)) {
+ $resolvedDirs = array_merge($resolvedDirs, $glob);
+ } else {
+ throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
+ }
+ }
+
+ $this->dirs = array_merge($this->dirs, $resolvedDirs);
+
+ return $this;
+ }
+
+ /**
+ * Returns an Iterator for the current Finder configuration.
+ *
+ * This method implements the IteratorAggregate interface.
+ *
+ * @return \Iterator An iterator
+ *
+ * @throws \LogicException if the in() method has not been called
+ */
+ public function getIterator()
+ {
+ if (0 === count($this->dirs) && 0 === count($this->iterators)) {
+ throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
+ }
+
+ if (1 === count($this->dirs) && 0 === count($this->iterators)) {
+ return $this->searchInDirectory($this->dirs[0]);
+ }
+
+ $iterator = new \AppendIterator();
+ foreach ($this->dirs as $dir) {
+ $iterator->append($this->searchInDirectory($dir));
+ }
+
+ foreach ($this->iterators as $it) {
+ $iterator->append($it);
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * Appends an existing set of files/directories to the finder.
+ *
+ * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array.
+ *
+ * @param mixed $iterator
+ *
+ * @return Finder The finder
+ *
+ * @throws \InvalidArgumentException When the given argument is not iterable.
+ */
+ public function append($iterator)
+ {
+ if ($iterator instanceof \IteratorAggregate) {
+ $this->iterators[] = $iterator->getIterator();
+ } elseif ($iterator instanceof \Iterator) {
+ $this->iterators[] = $iterator;
+ } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
+ $it = new \ArrayIterator();
+ foreach ($iterator as $file) {
+ $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
+ }
+ $this->iterators[] = $it;
+ } else {
+ throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Counts all the results collected by the iterators.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return iterator_count($this->getIterator());
+ }
+
+ /**
+ * @return Finder The current Finder instance
+ */
+ private function sortAdapters()
+ {
+ uasort($this->adapters, function (array $a, array $b) {
+ if ($a['selected'] || $b['selected']) {
+ return $a['selected'] ? -1 : 1;
+ }
+
+ return $a['priority'] > $b['priority'] ? -1 : 1;
+ });
+
+ return $this;
+ }
+
+ /**
+ * @param $dir
+ *
+ * @return \Iterator
+ *
+ * @throws \RuntimeException When none of the adapters are supported
+ */
+ private function searchInDirectory($dir)
+ {
+ if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
+ $this->exclude = array_merge($this->exclude, self::$vcsPatterns);
+ }
+
+ if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
+ $this->notPaths[] = '#(^|/)\..+(/|$)#';
+ }
+
+ foreach ($this->adapters as $adapter) {
+ if ($adapter['adapter']->isSupported()) {
+ try {
+ return $this
+ ->buildAdapter($adapter['adapter'])
+ ->searchInDirectory($dir);
+ } catch (ExceptionInterface $e) {}
+ }
+ }
+
+ throw new \RuntimeException('No supported adapter found.');
+ }
+
+ /**
+ * @param AdapterInterface $adapter
+ *
+ * @return AdapterInterface
+ */
+ private function buildAdapter(AdapterInterface $adapter)
+ {
+ return $adapter
+ ->setFollowLinks($this->followLinks)
+ ->setDepths($this->depths)
+ ->setMode($this->mode)
+ ->setExclude($this->exclude)
+ ->setNames($this->names)
+ ->setNotNames($this->notNames)
+ ->setContains($this->contains)
+ ->setNotContains($this->notContains)
+ ->setSizes($this->sizes)
+ ->setDates($this->dates)
+ ->setFilters($this->filters)
+ ->setSort($this->sort)
+ ->setPath($this->paths)
+ ->setNotPath($this->notPaths)
+ ->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
+ }
+
+ /**
+ * Unselects all adapters.
+ */
+ private function resetAdapterSelection()
+ {
+ $this->adapters = array_map(function (array $properties) {
+ $properties['selected'] = false;
+
+ return $properties;
+ }, $this->adapters);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Glob.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Glob.php
new file mode 100644
index 0000000..df65ac7
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Glob.php
@@ -0,0 +1,103 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder;
+
+/**
+ * Glob matches globbing patterns against text.
+ *
+ * if match_glob("foo.*", "foo.bar") echo "matched\n";
+ *
+ * // prints foo.bar and foo.baz
+ * $regex = glob_to_regex("foo.*");
+ * for (array('foo.bar', 'foo.baz', 'foo', 'bar') as $t)
+ * {
+ * if (/$regex/) echo "matched: $car\n";
+ * }
+ *
+ * Glob implements glob(3) style matching that can be used to match
+ * against text, rather than fetching names from a filesystem.
+ *
+ * Based on the Perl Text::Glob module.
+ *
+ * @author Fabien Potencier PHP port
+ * @author Richard Clamp Perl version
+ * @copyright 2004-2005 Fabien Potencier
+ * @copyright 2002 Richard Clamp
+ */
+class Glob
+{
+ /**
+ * Returns a regexp which is the equivalent of the glob pattern.
+ *
+ * @param string $glob The glob pattern
+ * @param bool $strictLeadingDot
+ * @param bool $strictWildcardSlash
+ *
+ * @return string regex The regexp
+ */
+ public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardSlash = true)
+ {
+ $firstByte = true;
+ $escaping = false;
+ $inCurlies = 0;
+ $regex = '';
+ $sizeGlob = strlen($glob);
+ for ($i = 0; $i < $sizeGlob; $i++) {
+ $car = $glob[$i];
+ if ($firstByte) {
+ if ($strictLeadingDot && '.' !== $car) {
+ $regex .= '(?=[^\.])';
+ }
+
+ $firstByte = false;
+ }
+
+ if ('/' === $car) {
+ $firstByte = true;
+ }
+
+ if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
+ $regex .= "\\$car";
+ } elseif ('*' === $car) {
+ $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
+ } elseif ('?' === $car) {
+ $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
+ } elseif ('{' === $car) {
+ $regex .= $escaping ? '\\{' : '(';
+ if (!$escaping) {
+ ++$inCurlies;
+ }
+ } elseif ('}' === $car && $inCurlies) {
+ $regex .= $escaping ? '}' : ')';
+ if (!$escaping) {
+ --$inCurlies;
+ }
+ } elseif (',' === $car && $inCurlies) {
+ $regex .= $escaping ? ',' : '|';
+ } elseif ('\\' === $car) {
+ if ($escaping) {
+ $regex .= '\\\\';
+ $escaping = false;
+ } else {
+ $escaping = true;
+ }
+
+ continue;
+ } else {
+ $regex .= $car;
+ }
+ $escaping = false;
+ }
+
+ return '#^'.$regex.'$#';
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php
new file mode 100644
index 0000000..36d79db
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php
@@ -0,0 +1,63 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * CustomFilterIterator filters files by applying anonymous functions.
+ *
+ * The anonymous function receives a \SplFileInfo and must return false
+ * to remove files.
+ *
+ * @author Fabien Potencier
+ */
+class CustomFilterIterator extends FilterIterator
+{
+ private $filters = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param array $filters An array of PHP callbacks
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __construct(\Iterator $iterator, array $filters)
+ {
+ foreach ($filters as $filter) {
+ if (!is_callable($filter)) {
+ throw new \InvalidArgumentException('Invalid PHP callback.');
+ }
+ }
+ $this->filters = $filters;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+
+ foreach ($this->filters as $filter) {
+ if (false === call_user_func($filter, $fileinfo)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php
new file mode 100644
index 0000000..bad682e
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+/**
+ * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates).
+ *
+ * @author Fabien Potencier
+ */
+class DateRangeFilterIterator extends FilterIterator
+{
+ private $comparators = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param DateComparator[] $comparators An array of DateComparator instances
+ */
+ public function __construct(\Iterator $iterator, array $comparators)
+ {
+ $this->comparators = $comparators;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+
+ if (!$fileinfo->isFile()) {
+ return true;
+ }
+
+ $filedate = $fileinfo->getMTime();
+ foreach ($this->comparators as $compare) {
+ if (!$compare->test($filedate)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php
new file mode 100644
index 0000000..c1c5ce8
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * DepthRangeFilterIterator limits the directory depth.
+ *
+ * @author Fabien Potencier
+ */
+class DepthRangeFilterIterator extends FilterIterator
+{
+ private $minDepth = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param \RecursiveIteratorIterator $iterator The Iterator to filter
+ * @param int $minDepth The min depth
+ * @param int $maxDepth The max depth
+ */
+ public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX)
+ {
+ $this->minDepth = $minDepth;
+ $iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth);
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ return $this->getInnerIterator()->getDepth() >= $this->minDepth;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
new file mode 100644
index 0000000..b2be58e
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
@@ -0,0 +1,55 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * ExcludeDirectoryFilterIterator filters out directories.
+ *
+ * @author Fabien Potencier
+ */
+class ExcludeDirectoryFilterIterator extends FilterIterator
+{
+ private $patterns = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param array $directories An array of directories to exclude
+ */
+ public function __construct(\Iterator $iterator, array $directories)
+ {
+ foreach ($directories as $directory) {
+ $this->patterns[] = '#(^|/)'.preg_quote($directory, '#').'(/|$)#';
+ }
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
+ $path = strtr($path, '\\', '/');
+ foreach ($this->patterns as $pattern) {
+ if (preg_match($pattern, $path)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php
new file mode 100644
index 0000000..48634f2
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php
@@ -0,0 +1,131 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\SplFileInfo;
+
+/**
+ * Iterate over shell command result.
+ *
+ * @author Jean-François Simon
+ */
+class FilePathsIterator extends \ArrayIterator
+{
+ /**
+ * @var string
+ */
+ private $baseDir;
+
+ /**
+ * @var int
+ */
+ private $baseDirLength;
+
+ /**
+ * @var string
+ */
+ private $subPath;
+
+ /**
+ * @var string
+ */
+ private $subPathname;
+
+ /**
+ * @var SplFileInfo
+ */
+ private $current;
+
+ /**
+ * @param array $paths List of paths returned by shell command
+ * @param string $baseDir Base dir for relative path building
+ */
+ public function __construct(array $paths, $baseDir)
+ {
+ $this->baseDir = $baseDir;
+ $this->baseDirLength = strlen($baseDir);
+
+ parent::__construct($paths);
+ }
+
+ /**
+ * @param string $name
+ * @param array $arguments
+ *
+ * @return mixed
+ */
+ public function __call($name, array $arguments)
+ {
+ return call_user_func_array(array($this->current(), $name), $arguments);
+ }
+
+ /**
+ * Return an instance of SplFileInfo with support for relative paths.
+ *
+ * @return SplFileInfo File information
+ */
+ public function current()
+ {
+ return $this->current;
+ }
+
+ /**
+ * @return string
+ */
+ public function key()
+ {
+ return $this->current->getPathname();
+ }
+
+ public function next()
+ {
+ parent::next();
+ $this->buildProperties();
+ }
+
+ public function rewind()
+ {
+ parent::rewind();
+ $this->buildProperties();
+ }
+
+ /**
+ * @return string
+ */
+ public function getSubPath()
+ {
+ return $this->subPath;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSubPathname()
+ {
+ return $this->subPathname;
+ }
+
+ private function buildProperties()
+ {
+ $absolutePath = parent::current();
+
+ if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) {
+ $this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\');
+ $dir = dirname($this->subPathname);
+ $this->subPath = '.' === $dir ? '' : $dir;
+ } else {
+ $this->subPath = $this->subPathname = '';
+ }
+
+ $this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php
new file mode 100644
index 0000000..985475e
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php
@@ -0,0 +1,55 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * FileTypeFilterIterator only keeps files, directories, or both.
+ *
+ * @author Fabien Potencier
+ */
+class FileTypeFilterIterator extends FilterIterator
+{
+ const ONLY_FILES = 1;
+ const ONLY_DIRECTORIES = 2;
+
+ private $mode;
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
+ */
+ public function __construct(\Iterator $iterator, $mode)
+ {
+ $this->mode = $mode;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+ if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
+ return false;
+ } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php
new file mode 100644
index 0000000..9ea3330
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php
@@ -0,0 +1,76 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings).
+ *
+ * @author Fabien Potencier
+ * @author Włodzimierz Gajda
+ */
+class FilecontentFilterIterator extends MultiplePcreFilterIterator
+{
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ if (!$this->matchRegexps && !$this->noMatchRegexps) {
+ return true;
+ }
+
+ $fileinfo = $this->current();
+
+ if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
+ return false;
+ }
+
+ $content = $fileinfo->getContents();
+ if (!$content) {
+ return false;
+ }
+
+ // should at least not match one rule to exclude
+ foreach ($this->noMatchRegexps as $regex) {
+ if (preg_match($regex, $content)) {
+ return false;
+ }
+ }
+
+ // should at least match one rule
+ $match = true;
+ if ($this->matchRegexps) {
+ $match = false;
+ foreach ($this->matchRegexps as $regex) {
+ if (preg_match($regex, $content)) {
+ return true;
+ }
+ }
+ }
+
+ return $match;
+ }
+
+ /**
+ * Converts string to regexp if necessary.
+ *
+ * @param string $str Pattern: string or regexp
+ *
+ * @return string regexp corresponding to a given string or regexp
+ */
+ protected function toRegex($str)
+ {
+ return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php
new file mode 100644
index 0000000..c4e0ccd
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php
@@ -0,0 +1,68 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string).
+ *
+ * @author Fabien Potencier
+ */
+class FilenameFilterIterator extends MultiplePcreFilterIterator
+{
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $filename = $this->current()->getFilename();
+
+ // should at least not match one rule to exclude
+ foreach ($this->noMatchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return false;
+ }
+ }
+
+ // should at least match one rule
+ $match = true;
+ if ($this->matchRegexps) {
+ $match = false;
+ foreach ($this->matchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return true;
+ }
+ }
+ }
+
+ return $match;
+ }
+
+ /**
+ * Converts glob to regexp.
+ *
+ * PCRE patterns are left unchanged.
+ * Glob strings are transformed with Glob::toRegex().
+ *
+ * @param string $str Pattern: glob or regexp
+ *
+ * @return string regexp corresponding to a given glob or regexp
+ */
+ protected function toRegex($str)
+ {
+ return Expression::create($str)->getRegex()->render();
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php
new file mode 100644
index 0000000..f4da44c
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * This iterator just overrides the rewind method in order to correct a PHP bug.
+ *
+ * @see https://bugs.php.net/bug.php?id=49104
+ *
+ * @author Alex Bogomazov
+ */
+abstract class FilterIterator extends \FilterIterator
+{
+ /**
+ * This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after
+ * rewind in some cases.
+ *
+ * @see FilterIterator::rewind()
+ */
+ public function rewind()
+ {
+ $iterator = $this;
+ while ($iterator instanceof \OuterIterator) {
+ $innerIterator = $iterator->getInnerIterator();
+
+ if ($innerIterator instanceof RecursiveDirectoryIterator) {
+ if ($innerIterator->isRewindable()) {
+ $innerIterator->next();
+ $innerIterator->rewind();
+ }
+ } elseif ($iterator->getInnerIterator() instanceof \FilesystemIterator) {
+ $iterator->getInnerIterator()->next();
+ $iterator->getInnerIterator()->rewind();
+ }
+ $iterator = $iterator->getInnerIterator();
+ }
+
+ parent::rewind();
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php
new file mode 100644
index 0000000..d7efc90
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php
@@ -0,0 +1,66 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings).
+ *
+ * @author Fabien Potencier
+ */
+abstract class MultiplePcreFilterIterator extends FilterIterator
+{
+ protected $matchRegexps = array();
+ protected $noMatchRegexps = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param array $matchPatterns An array of patterns that need to match
+ * @param array $noMatchPatterns An array of patterns that need to not match
+ */
+ public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
+ {
+ foreach ($matchPatterns as $pattern) {
+ $this->matchRegexps[] = $this->toRegex($pattern);
+ }
+
+ foreach ($noMatchPatterns as $pattern) {
+ $this->noMatchRegexps[] = $this->toRegex($pattern);
+ }
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Checks whether the string is a regex.
+ *
+ * @param string $str
+ *
+ * @return bool Whether the given string is a regex
+ */
+ protected function isRegex($str)
+ {
+ return Expression::create($str)->isRegex();
+ }
+
+ /**
+ * Converts string into regexp.
+ *
+ * @param string $str Pattern
+ *
+ * @return string regexp corresponding to a given string
+ */
+ abstract protected function toRegex($str);
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php
new file mode 100644
index 0000000..828fa41
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php
@@ -0,0 +1,75 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * PathFilterIterator filters files by path patterns (e.g. some/special/dir).
+ *
+ * @author Fabien Potencier
+ * @author Włodzimierz Gajda
+ */
+class PathFilterIterator extends MultiplePcreFilterIterator
+{
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $filename = $this->current()->getRelativePathname();
+
+ if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+ $filename = strtr($filename, '\\', '/');
+ }
+
+ // should at least not match one rule to exclude
+ foreach ($this->noMatchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return false;
+ }
+ }
+
+ // should at least match one rule
+ $match = true;
+ if ($this->matchRegexps) {
+ $match = false;
+ foreach ($this->matchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return true;
+ }
+ }
+ }
+
+ return $match;
+ }
+
+ /**
+ * Converts strings to regexp.
+ *
+ * PCRE patterns are left unchanged.
+ *
+ * Default conversion:
+ * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/'
+ *
+ * Use only / as directory separator (on Windows also).
+ *
+ * @param string $str Pattern: regexp or dirname.
+ *
+ * @return string regexp corresponding to a given string or regexp
+ */
+ protected function toRegex($str)
+ {
+ return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php
new file mode 100644
index 0000000..9543a3f
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php
@@ -0,0 +1,126 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Exception\AccessDeniedException;
+use Symfony\Component\Finder\SplFileInfo;
+
+/**
+ * Extends the \RecursiveDirectoryIterator to support relative paths
+ *
+ * @author Victor Berchet
+ */
+class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
+{
+ /**
+ * @var bool
+ */
+ private $ignoreUnreadableDirs;
+
+ /**
+ * @var bool
+ */
+ private $rewindable;
+
+ /**
+ * Constructor.
+ *
+ * @param string $path
+ * @param int $flags
+ * @param bool $ignoreUnreadableDirs
+ *
+ * @throws \RuntimeException
+ */
+ public function __construct($path, $flags, $ignoreUnreadableDirs = false)
+ {
+ if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
+ throw new \RuntimeException('This iterator only support returning current as fileinfo.');
+ }
+
+ parent::__construct($path, $flags);
+ $this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
+ }
+
+ /**
+ * Return an instance of SplFileInfo with support for relative paths
+ *
+ * @return SplFileInfo File information
+ */
+ public function current()
+ {
+ return new SplFileInfo(parent::current()->getPathname(), $this->getSubPath(), $this->getSubPathname());
+ }
+
+ /**
+ * @return \RecursiveIterator
+ *
+ * @throws AccessDeniedException
+ */
+ public function getChildren()
+ {
+ try {
+ $children = parent::getChildren();
+
+ if ($children instanceof self) {
+ // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore
+ $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
+ }
+
+ return $children;
+ } catch (\UnexpectedValueException $e) {
+ if ($this->ignoreUnreadableDirs) {
+ // If directory is unreadable and finder is set to ignore it, a fake empty content is returned.
+ return new \RecursiveArrayIterator(array());
+ } else {
+ throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+ }
+
+ /**
+ * Do nothing for non rewindable stream
+ */
+ public function rewind()
+ {
+ if (false === $this->isRewindable()) {
+ return;
+ }
+
+ // @see https://bugs.php.net/bug.php?id=49104
+ parent::next();
+
+ parent::rewind();
+ }
+
+ /**
+ * Checks if the stream is rewindable.
+ *
+ * @return bool true when the stream is rewindable, false otherwise
+ */
+ public function isRewindable()
+ {
+ if (null !== $this->rewindable) {
+ return $this->rewindable;
+ }
+
+ if (false !== $stream = @opendir($this->getPath())) {
+ $infos = stream_get_meta_data($stream);
+ closedir($stream);
+
+ if ($infos['seekable']) {
+ return $this->rewindable = true;
+ }
+ }
+
+ return $this->rewindable = false;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php
new file mode 100644
index 0000000..b345a16
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php
@@ -0,0 +1,59 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Comparator\NumberComparator;
+
+/**
+ * SizeRangeFilterIterator filters out files that are not in the given size range.
+ *
+ * @author Fabien Potencier
+ */
+class SizeRangeFilterIterator extends FilterIterator
+{
+ private $comparators = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param NumberComparator[] $comparators An array of NumberComparator instances
+ */
+ public function __construct(\Iterator $iterator, array $comparators)
+ {
+ $this->comparators = $comparators;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+ if (!$fileinfo->isFile()) {
+ return true;
+ }
+
+ $filesize = $fileinfo->getSize();
+ foreach ($this->comparators as $compare) {
+ if (!$compare->test($filesize)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php
new file mode 100644
index 0000000..b32ac8d
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php
@@ -0,0 +1,82 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * SortableIterator applies a sort on a given Iterator.
+ *
+ * @author Fabien Potencier
+ */
+class SortableIterator implements \IteratorAggregate
+{
+ const SORT_BY_NAME = 1;
+ const SORT_BY_TYPE = 2;
+ const SORT_BY_ACCESSED_TIME = 3;
+ const SORT_BY_CHANGED_TIME = 4;
+ const SORT_BY_MODIFIED_TIME = 5;
+
+ private $iterator;
+ private $sort;
+
+ /**
+ * Constructor.
+ *
+ * @param \Traversable $iterator The Iterator to filter
+ * @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback)
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __construct(\Traversable $iterator, $sort)
+ {
+ $this->iterator = $iterator;
+
+ if (self::SORT_BY_NAME === $sort) {
+ $this->sort = function ($a, $b) {
+ return strcmp($a->getRealpath(), $b->getRealpath());
+ };
+ } elseif (self::SORT_BY_TYPE === $sort) {
+ $this->sort = function ($a, $b) {
+ if ($a->isDir() && $b->isFile()) {
+ return -1;
+ } elseif ($a->isFile() && $b->isDir()) {
+ return 1;
+ }
+
+ return strcmp($a->getRealpath(), $b->getRealpath());
+ };
+ } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
+ $this->sort = function ($a, $b) {
+ return ($a->getATime() - $b->getATime());
+ };
+ } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
+ $this->sort = function ($a, $b) {
+ return ($a->getCTime() - $b->getCTime());
+ };
+ } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
+ $this->sort = function ($a, $b) {
+ return ($a->getMTime() - $b->getMTime());
+ };
+ } elseif (is_callable($sort)) {
+ $this->sort = $sort;
+ } else {
+ throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
+ }
+ }
+
+ public function getIterator()
+ {
+ $array = iterator_to_array($this->iterator, true);
+ uasort($array, $this->sort);
+
+ return new \ArrayIterator($array);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/LICENSE b/core/vendor/symfony/finder/Symfony/Component/Finder/LICENSE
new file mode 100644
index 0000000..0b3292c
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2014 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/README.md b/core/vendor/symfony/finder/Symfony/Component/Finder/README.md
new file mode 100644
index 0000000..8494531
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/README.md
@@ -0,0 +1,41 @@
+Finder Component
+================
+
+Finder finds files and directories via an intuitive fluent interface.
+
+ use Symfony\Component\Finder\Finder;
+
+ $finder = new Finder();
+
+ $iterator = $finder
+ ->files()
+ ->name('*.php')
+ ->depth(0)
+ ->size('>= 1K')
+ ->in(__DIR__);
+
+ foreach ($iterator as $file) {
+ print $file->getRealpath()."\n";
+ }
+
+But you can also use it to find files stored remotely like in this example where
+we are looking for files on Amazon S3:
+
+ $s3 = new \Zend_Service_Amazon_S3($key, $secret);
+ $s3->registerStreamWrapper("s3");
+
+ $finder = new Finder();
+ $finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
+ foreach ($finder->in('s3://bucket-name') as $file) {
+ print $file->getFilename()."\n";
+ }
+
+Resources
+---------
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Finder/
+ $ composer.phar install
+ $ phpunit
+
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php
new file mode 100644
index 0000000..78824d0
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php
@@ -0,0 +1,294 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Shell;
+
+/**
+ * @author Jean-François Simon
+ */
+class Command
+{
+ /**
+ * @var Command|null
+ */
+ private $parent;
+
+ /**
+ * @var array
+ */
+ private $bits = array();
+
+ /**
+ * @var array
+ */
+ private $labels = array();
+
+ /**
+ * @var \Closure|null
+ */
+ private $errorHandler;
+
+ /**
+ * Constructor.
+ *
+ * @param Command|null $parent Parent command
+ */
+ public function __construct(Command $parent = null)
+ {
+ $this->parent = $parent;
+ }
+
+ /**
+ * Returns command as string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->join();
+ }
+
+ /**
+ * Creates a new Command instance.
+ *
+ * @param Command|null $parent Parent command
+ *
+ * @return Command New Command instance
+ */
+ public static function create(Command $parent = null)
+ {
+ return new self($parent);
+ }
+
+ /**
+ * Escapes special chars from input.
+ *
+ * @param string $input A string to escape
+ *
+ * @return string The escaped string
+ */
+ public static function escape($input)
+ {
+ return escapeshellcmd($input);
+ }
+
+ /**
+ * Quotes input.
+ *
+ * @param string $input An argument string
+ *
+ * @return string The quoted string
+ */
+ public static function quote($input)
+ {
+ return escapeshellarg($input);
+ }
+
+ /**
+ * Appends a string or a Command instance.
+ *
+ * @param string|Command $bit
+ *
+ * @return Command The current Command instance
+ */
+ public function add($bit)
+ {
+ $this->bits[] = $bit;
+
+ return $this;
+ }
+
+ /**
+ * Prepends a string or a command instance.
+ *
+ * @param string|Command $bit
+ *
+ * @return Command The current Command instance
+ */
+ public function top($bit)
+ {
+ array_unshift($this->bits, $bit);
+
+ foreach ($this->labels as $label => $index) {
+ $this->labels[$label] += 1;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Appends an argument, will be quoted.
+ *
+ * @param string $arg
+ *
+ * @return Command The current Command instance
+ */
+ public function arg($arg)
+ {
+ $this->bits[] = self::quote($arg);
+
+ return $this;
+ }
+
+ /**
+ * Appends escaped special command chars.
+ *
+ * @param string $esc
+ *
+ * @return Command The current Command instance
+ */
+ public function cmd($esc)
+ {
+ $this->bits[] = self::escape($esc);
+
+ return $this;
+ }
+
+ /**
+ * Inserts a labeled command to feed later.
+ *
+ * @param string $label The unique label
+ *
+ * @return Command The current Command instance
+ *
+ * @throws \RuntimeException If label already exists
+ */
+ public function ins($label)
+ {
+ if (isset($this->labels[$label])) {
+ throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
+ }
+
+ $this->bits[] = self::create($this);
+ $this->labels[$label] = count($this->bits)-1;
+
+ return $this->bits[$this->labels[$label]];
+ }
+
+ /**
+ * Retrieves a previously labeled command.
+ *
+ * @param string $label
+ *
+ * @return Command The labeled command
+ *
+ * @throws \RuntimeException
+ */
+ public function get($label)
+ {
+ if (!isset($this->labels[$label])) {
+ throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
+ }
+
+ return $this->bits[$this->labels[$label]];
+ }
+
+ /**
+ * Returns parent command (if any).
+ *
+ * @return Command Parent command
+ *
+ * @throws \RuntimeException If command has no parent
+ */
+ public function end()
+ {
+ if (null === $this->parent) {
+ throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
+ }
+
+ return $this->parent;
+ }
+
+ /**
+ * Counts bits stored in command.
+ *
+ * @return int The bits count
+ */
+ public function length()
+ {
+ return count($this->bits);
+ }
+
+ /**
+ * @param \Closure $errorHandler
+ *
+ * @return Command
+ */
+ public function setErrorHandler(\Closure $errorHandler)
+ {
+ $this->errorHandler = $errorHandler;
+
+ return $this;
+ }
+
+ /**
+ * @return \Closure|null
+ */
+ public function getErrorHandler()
+ {
+ return $this->errorHandler;
+ }
+
+ /**
+ * Executes current command.
+ *
+ * @return array The command result
+ *
+ * @throws \RuntimeException
+ */
+ public function execute()
+ {
+ if (null === $this->errorHandler) {
+ exec($this->join(), $output);
+ } else {
+ $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
+ $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);
+
+ if ($error = stream_get_contents($pipes[2])) {
+ call_user_func($this->errorHandler, $error);
+ }
+
+ proc_close($process);
+ }
+
+ return $output ?: array();
+ }
+
+ /**
+ * Joins bits.
+ *
+ * @return string
+ */
+ public function join()
+ {
+ return implode(' ', array_filter(
+ array_map(function ($bit) {
+ return $bit instanceof Command ? $bit->join() : ($bit ?: null);
+ }, $this->bits),
+ function ($bit) { return null !== $bit; }
+ ));
+ }
+
+ /**
+ * Insert a string or a Command instance before the bit at given position $index (index starts from 0).
+ *
+ * @param string|Command $bit
+ * @param int $index
+ *
+ * @return Command The current Command instance
+ */
+ public function addAtIndex($bit, $index)
+ {
+ array_splice($this->bits, $index, 0, $bit);
+
+ return $this;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php
new file mode 100644
index 0000000..8586cbc
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php
@@ -0,0 +1,95 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Shell;
+
+/**
+ * @author Jean-François Simon
+ */
+class Shell
+{
+ const TYPE_UNIX = 1;
+ const TYPE_DARWIN = 2;
+ const TYPE_CYGWIN = 3;
+ const TYPE_WINDOWS = 4;
+ const TYPE_BSD = 5;
+
+ /**
+ * @var string|null
+ */
+ private $type;
+
+ /**
+ * Returns guessed OS type.
+ *
+ * @return int
+ */
+ public function getType()
+ {
+ if (null === $this->type) {
+ $this->type = $this->guessType();
+ }
+
+ return $this->type;
+ }
+
+ /**
+ * Tests if a command is available.
+ *
+ * @param string $command
+ *
+ * @return bool
+ */
+ public function testCommand($command)
+ {
+ if (self::TYPE_WINDOWS === $this->type) {
+ // todo: find a way to test if Windows command exists
+ return false;
+ }
+
+ if (!function_exists('exec')) {
+ return false;
+ }
+
+ // todo: find a better way (command could not be available)
+ exec('command -v '.$command, $output, $code);
+
+ return 0 === $code && count($output) > 0;
+ }
+
+ /**
+ * Guesses OS type.
+ *
+ * @return int
+ */
+ private function guessType()
+ {
+ $os = strtolower(PHP_OS);
+
+ if (false !== strpos($os, 'cygwin')) {
+ return self::TYPE_CYGWIN;
+ }
+
+ if (false !== strpos($os, 'darwin')) {
+ return self::TYPE_DARWIN;
+ }
+
+ if (false !== strpos($os, 'bsd')) {
+ return self::TYPE_BSD;
+ }
+
+ if (0 === strpos($os, 'win')) {
+ return self::TYPE_WINDOWS;
+ }
+
+ return self::TYPE_UNIX;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php b/core/vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php
new file mode 100644
index 0000000..d911fe0
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php
@@ -0,0 +1,77 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder;
+
+/**
+ * Extends \SplFileInfo to support relative paths
+ *
+ * @author Fabien Potencier
+ */
+class SplFileInfo extends \SplFileInfo
+{
+ private $relativePath;
+ private $relativePathname;
+
+ /**
+ * Constructor
+ *
+ * @param string $file The file name
+ * @param string $relativePath The relative path
+ * @param string $relativePathname The relative path name
+ */
+ public function __construct($file, $relativePath, $relativePathname)
+ {
+ parent::__construct($file);
+ $this->relativePath = $relativePath;
+ $this->relativePathname = $relativePathname;
+ }
+
+ /**
+ * Returns the relative path
+ *
+ * @return string the relative path
+ */
+ public function getRelativePath()
+ {
+ return $this->relativePath;
+ }
+
+ /**
+ * Returns the relative path name
+ *
+ * @return string the relative path name
+ */
+ public function getRelativePathname()
+ {
+ return $this->relativePathname;
+ }
+
+ /**
+ * Returns the contents of the file
+ *
+ * @return string the contents of the file
+ *
+ * @throws \RuntimeException
+ */
+ public function getContents()
+ {
+ $level = error_reporting(0);
+ $content = file_get_contents($this->getPathname());
+ error_reporting($level);
+ if (false === $content) {
+ $error = error_get_last();
+ throw new \RuntimeException($error['message']);
+ }
+
+ return $content;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php
new file mode 100644
index 0000000..bf59844
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Comparator;
+
+use Symfony\Component\Finder\Comparator\Comparator;
+
+class ComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetSetOperator()
+ {
+ $comparator = new Comparator();
+ try {
+ $comparator->setOperator('foo');
+ $this->fail('->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
+ }
+
+ $comparator = new Comparator();
+ $comparator->setOperator('>');
+ $this->assertEquals('>', $comparator->getOperator(), '->getOperator() returns the current operator');
+ }
+
+ public function testGetSetTarget()
+ {
+ $comparator = new Comparator();
+ $comparator->setTarget(8);
+ $this->assertEquals(8, $comparator->getTarget(), '->getTarget() returns the target');
+ }
+
+ /**
+ * @dataProvider getTestData
+ */
+ public function testTest($operator, $target, $match, $noMatch)
+ {
+ $c = new Comparator();
+ $c->setOperator($operator);
+ $c->setTarget($target);
+
+ foreach ($match as $m) {
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
+ }
+ }
+
+ public function getTestData()
+ {
+ return array(
+ array('<', '1000', array('500', '999'), array('1000', '1500')),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php
new file mode 100644
index 0000000..ac8256a
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Comparator;
+
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+class DateComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ try {
+ new DateComparator('foobar');
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ }
+
+ try {
+ new DateComparator('');
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ }
+ }
+
+ /**
+ * @dataProvider getTestData
+ */
+ public function testTest($test, $match, $noMatch)
+ {
+ $c = new DateComparator($test);
+
+ foreach ($match as $m) {
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
+ }
+ }
+
+ public function getTestData()
+ {
+ return array(
+ array('< 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
+ array('until 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
+ array('before 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
+ array('> 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
+ array('after 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
+ array('since 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
+ array('!= 2005-10-10', array(strtotime('2005-10-11')), array(strtotime('2005-10-10'))),
+ );
+
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php
new file mode 100644
index 0000000..b07870b
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php
@@ -0,0 +1,109 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Comparator;
+
+use Symfony\Component\Finder\Comparator\NumberComparator;
+
+class NumberComparatorTest extends \PHPUnit_Framework_TestCase
+{
+
+ /**
+ * @dataProvider getConstructorTestData
+ */
+ public function testConstructor($successes, $failures)
+ {
+ foreach ($successes as $s) {
+ new NumberComparator($s);
+ }
+
+ foreach ($failures as $f) {
+ try {
+ new NumberComparator($f);
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ }
+ }
+ }
+
+ /**
+ * @dataProvider getTestData
+ */
+ public function testTest($test, $match, $noMatch)
+ {
+ $c = new NumberComparator($test);
+
+ foreach ($match as $m) {
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
+ }
+ }
+
+ public function getTestData()
+ {
+ return array(
+ array('< 1000', array('500', '999'), array('1000', '1500')),
+
+ array('< 1K', array('500', '999'), array('1000', '1500')),
+ array('<1k', array('500', '999'), array('1000', '1500')),
+ array(' < 1 K ', array('500', '999'), array('1000', '1500')),
+ array('<= 1K', array('1000'), array('1001')),
+ array('> 1K', array('1001'), array('1000')),
+ array('>= 1K', array('1000'), array('999')),
+
+ array('< 1KI', array('500', '1023'), array('1024', '1500')),
+ array('<= 1KI', array('1024'), array('1025')),
+ array('> 1KI', array('1025'), array('1024')),
+ array('>= 1KI', array('1024'), array('1023')),
+
+ array('1KI', array('1024'), array('1023', '1025')),
+ array('==1KI', array('1024'), array('1023', '1025')),
+
+ array('==1m', array('1000000'), array('999999', '1000001')),
+ array('==1mi', array(1024*1024), array(1024*1024-1, 1024*1024+1)),
+
+ array('==1g', array('1000000000'), array('999999999', '1000000001')),
+ array('==1gi', array(1024*1024*1024), array(1024*1024*1024-1, 1024*1024*1024+1)),
+
+ array('!= 1000', array('500', '999'), array('1000')),
+ );
+ }
+
+ public function getConstructorTestData()
+ {
+ return array(
+ array(
+ array(
+ '1', '0',
+ '3.5', '33.55', '123.456', '123456.78',
+ '.1', '.123',
+ '.0', '0.0',
+ '1.', '0.', '123.',
+ '==1', '!=1', '<1', '>1', '<=1', '>=1',
+ '==1k', '==1ki', '==1m', '==1mi', '==1g', '==1gi',
+ '1k', '1ki', '1m', '1mi', '1g', '1gi',
+ ),
+ array(
+ false, null, '',
+ ' ', 'foobar',
+ '=1', '===1',
+ '0 . 1', '123 .45', '234. 567',
+ '..', '.0.', '0.1.2',
+ )
+ ),
+ );
+ }
+
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php
new file mode 100644
index 0000000..4254a45
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php
@@ -0,0 +1,68 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Expression;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+class ExpressionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTypeGuesserData
+ */
+ public function testTypeGuesser($expr, $type)
+ {
+ $this->assertEquals($type, Expression::create($expr)->getType());
+ }
+
+ /**
+ * @dataProvider getCaseSensitiveData
+ */
+ public function testCaseSensitive($expr, $isCaseSensitive)
+ {
+ $this->assertEquals($isCaseSensitive, Expression::create($expr)->isCaseSensitive());
+ }
+
+ /**
+ * @dataProvider getRegexRenderingData
+ */
+ public function testRegexRendering($expr, $body)
+ {
+ $this->assertEquals($body, Expression::create($expr)->renderPattern());
+ }
+
+ public function getTypeGuesserData()
+ {
+ return array(
+ array('{foo}', Expression::TYPE_REGEX),
+ array('/foo/', Expression::TYPE_REGEX),
+ array('foo', Expression::TYPE_GLOB),
+ array('foo*', Expression::TYPE_GLOB),
+ );
+ }
+
+ public function getCaseSensitiveData()
+ {
+ return array(
+ array('{foo}m', true),
+ array('/foo/i', false),
+ array('foo*', true),
+ );
+ }
+
+ public function getRegexRenderingData()
+ {
+ return array(
+ array('{foo}m', 'foo'),
+ array('/foo/i', 'foo'),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php
new file mode 100644
index 0000000..9d4c3e5
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Expression;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+class GlobTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getToRegexData
+ */
+ public function testGlobToRegex($glob, $match, $noMatch)
+ {
+ foreach ($match as $m) {
+ $this->assertRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertNotRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
+ }
+ }
+
+ public function getToRegexData()
+ {
+ return array(
+ array('', array(''), array('f', '/')),
+ array('*', array('foo'), array('foo/', '/foo')),
+ array('foo.*', array('foo.php', 'foo.a', 'foo.'), array('fooo.php', 'foo.php/foo')),
+ array('fo?', array('foo', 'fot'), array('fooo', 'ffoo', 'fo/')),
+ array('fo{o,t}', array('foo', 'fot'), array('fob', 'fo/')),
+ array('foo(bar|foo)', array('foo(bar|foo)'), array('foobar', 'foofoo')),
+ array('foo,bar', array('foo,bar'), array('foo', 'bar')),
+ array('fo{o,\\,}', array('foo', 'fo,'), array()),
+ array('fo{o,\\\\}', array('foo', 'fo\\'), array()),
+ array('/foo', array('/foo'), array('foo')),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php
new file mode 100644
index 0000000..35ba276
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php
@@ -0,0 +1,143 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Expression;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+class RegexTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getHasFlagsData
+ */
+ public function testHasFlags($regex, $start, $end)
+ {
+ $expr = new Expression($regex);
+
+ $this->assertEquals($start, $expr->getRegex()->hasStartFlag());
+ $this->assertEquals($end, $expr->getRegex()->hasEndFlag());
+ }
+
+ /**
+ * @dataProvider getHasJokersData
+ */
+ public function testHasJokers($regex, $start, $end)
+ {
+ $expr = new Expression($regex);
+
+ $this->assertEquals($start, $expr->getRegex()->hasStartJoker());
+ $this->assertEquals($end, $expr->getRegex()->hasEndJoker());
+ }
+
+ /**
+ * @dataProvider getSetFlagsData
+ */
+ public function testSetFlags($regex, $start, $end, $expected)
+ {
+ $expr = new Expression($regex);
+ $expr->getRegex()->setStartFlag($start)->setEndFlag($end);
+
+ $this->assertEquals($expected, $expr->render());
+ }
+
+ /**
+ * @dataProvider getSetJokersData
+ */
+ public function testSetJokers($regex, $start, $end, $expected)
+ {
+ $expr = new Expression($regex);
+ $expr->getRegex()->setStartJoker($start)->setEndJoker($end);
+
+ $this->assertEquals($expected, $expr->render());
+ }
+
+ public function testOptions()
+ {
+ $expr = new Expression('~abc~is');
+ $expr->getRegex()->removeOption('i')->addOption('m');
+
+ $this->assertEquals('~abc~sm', $expr->render());
+ }
+
+ public function testMixFlagsAndJokers()
+ {
+ $expr = new Expression('~^.*abc.*$~is');
+
+ $expr->getRegex()->setStartFlag(false)->setEndFlag(false)->setStartJoker(false)->setEndJoker(false);
+ $this->assertEquals('~abc~is', $expr->render());
+
+ $expr->getRegex()->setStartFlag(true)->setEndFlag(true)->setStartJoker(true)->setEndJoker(true);
+ $this->assertEquals('~^.*abc.*$~is', $expr->render());
+ }
+
+ /**
+ * @dataProvider getReplaceJokersTestData
+ */
+ public function testReplaceJokers($regex, $expected)
+ {
+ $expr = new Expression($regex);
+ $expr = $expr->getRegex()->replaceJokers('@');
+
+ $this->assertEquals($expected, $expr->renderPattern());
+ }
+
+ public function getHasFlagsData()
+ {
+ return array(
+ array('~^abc~', true, false),
+ array('~abc$~', false, true),
+ array('~abc~', false, false),
+ array('~^abc$~', true, true),
+ array('~^abc\\$~', true, false),
+ );
+ }
+
+ public function getHasJokersData()
+ {
+ return array(
+ array('~.*abc~', true, false),
+ array('~abc.*~', false, true),
+ array('~abc~', false, false),
+ array('~.*abc.*~', true, true),
+ array('~.*abc\\.*~', true, false),
+ );
+ }
+
+ public function getSetFlagsData()
+ {
+ return array(
+ array('~abc~', true, false, '~^abc~'),
+ array('~abc~', false, true, '~abc$~'),
+ array('~abc~', false, false, '~abc~'),
+ array('~abc~', true, true, '~^abc$~'),
+ );
+ }
+
+ public function getSetJokersData()
+ {
+ return array(
+ array('~abc~', true, false, '~.*abc~'),
+ array('~abc~', false, true, '~abc.*~'),
+ array('~abc~', false, false, '~abc~'),
+ array('~abc~', true, true, '~.*abc.*~'),
+ );
+ }
+
+ public function getReplaceJokersTestData()
+ {
+ return array(
+ array('~.abc~', '@abc'),
+ array('~\\.abc~', '\\.abc'),
+ array('~\\\\.abc~', '\\\\@abc'),
+ array('~\\\\\\.abc~', '\\\\\\.abc'),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php
new file mode 100644
index 0000000..0cbae14
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php
@@ -0,0 +1,57 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+
+/**
+ * @author Jean-François Simon
+ */
+class DummyAdapter extends AbstractAdapter
+{
+ /**
+ * @var \Iterator
+ */
+ private $iterator;
+
+ /**
+ * @param \Iterator $iterator
+ */
+ public function __construct(\Iterator $iterator)
+ {
+ $this->iterator = $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ return $this->iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'yes';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php
new file mode 100644
index 0000000..6e6ed24
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php
@@ -0,0 +1,45 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+use Symfony\Component\Finder\Exception\AdapterFailureException;
+
+/**
+ * @author Jean-François Simon
+ */
+class FailingAdapter extends AbstractAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ throw new AdapterFailureException($this);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'failing';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php
new file mode 100644
index 0000000..5a260b0
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php
@@ -0,0 +1,57 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+
+/**
+ * @author Jean-François Simon
+ */
+class NamedAdapter extends AbstractAdapter
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @param string $name
+ */
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ return new \ArrayIterator(array());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php
new file mode 100644
index 0000000..1f91b98
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php
@@ -0,0 +1,44 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+
+/**
+ * @author Jean-François Simon
+ */
+class UnsupportedAdapter extends AbstractAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ return new \ArrayIterator(array());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'unsupported';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return false;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php
new file mode 100644
index 0000000..a42b0d7
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php
@@ -0,0 +1,845 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests;
+
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Finder\Adapter;
+
+class FinderTest extends Iterator\RealIteratorTestCase
+{
+
+ public function testCreate()
+ {
+ $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testDirectories($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->directories());
+ $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->directories();
+ $finder->files();
+ $finder->directories();
+ $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testFiles($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->files());
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->files();
+ $finder->directories();
+ $finder->files();
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testDepth($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->depth('< 1'));
+ $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->depth('<= 0'));
+ $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->depth('>= 1'));
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->depth('< 1')->depth('>= 1');
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testName($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->name('*.php'));
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.ph*');
+ $finder->name('test.py');
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('~^test~i');
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('~\\.php$~i');
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.p{hp,y}');
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testNotName($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->notName('*.php'));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->notName('*.php');
+ $finder->notName('*.py');
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.ph*');
+ $finder->name('test.py');
+ $finder->notName('*.php');
+ $finder->notName('*.py');
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.ph*');
+ $finder->name('test.py');
+ $finder->notName('*.p{hp,y}');
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getRegexNameTestData
+ *
+ * @group regexName
+ */
+ public function testRegexName($adapter, $regex)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->name($regex);
+ $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSize($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->files()->size('< 1K')->size('> 500'));
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testDate($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->files()->date('until last month'));
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testExclude($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->exclude('foo'));
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIgnoreVCS($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreVCS(false)->ignoreDotFiles(false));
+ $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->ignoreVCS(false)->ignoreVCS(false)->ignoreDotFiles(false);
+ $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreVCS(true)->ignoreDotFiles(false));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIgnoreDotFiles($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreDotFiles(false)->ignoreVCS(false));
+ $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->ignoreDotFiles(false)->ignoreDotFiles(false)->ignoreVCS(false);
+ $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreDotFiles(true)->ignoreVCS(false));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByName($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByName());
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByType($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByType());
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'toto', 'foo/bar.tmp', 'test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByAccessedTime($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByAccessedTime());
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByChangedTime($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByChangedTime());
+ $this->assertIterator($this->toAbsolute(array('toto', 'test.py', 'test.php', 'foo/bar.tmp', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByModifiedTime($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByModifiedTime());
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSort($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealpath(), $b->getRealpath()); }));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testFilter($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return preg_match('/test/', $f) > 0; }));
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testFollowLinks($adapter)
+ {
+ if ('\\' == DIRECTORY_SEPARATOR) {
+ return;
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->followLinks());
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIn($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ try {
+ $finder->in('foobar');
+ $this->fail('->in() throws a \InvalidArgumentException if the directory does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '->in() throws a \InvalidArgumentException if the directory does not exist');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator();
+
+ $this->assertIterator(array(self::$tmpDir.DIRECTORY_SEPARATOR.'test.php', __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php'), $iterator);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testInWithGlob($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();
+
+ $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInWithNonDirectoryGlob($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__.'/Fixtures/A/a*');
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testGetIterator($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ try {
+ $finder->getIterator();
+ $this->fail('->getIterator() throws a \LogicException if the in() method has not been called');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('LogicException', $e, '->getIterator() throws a \LogicException if the in() method has not been called');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $dirs = array();
+ foreach ($finder->directories()->in(self::$tmpDir) as $dir) {
+ $dirs[] = (string) $dir;
+ }
+
+ $expected = $this->toAbsolute(array('foo', 'toto'));
+
+ sort($dirs);
+ sort($expected);
+
+ $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface');
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface');
+
+ $finder = $this->buildFinder($adapter);
+ $a = iterator_to_array($finder->directories()->in(self::$tmpDir));
+ $a = array_values(array_map(function ($a) { return (string) $a; }, $a));
+ sort($a);
+ $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface');
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testRelativePath($adapter)
+ {
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir);
+
+ $paths = array();
+
+ foreach ($finder as $file) {
+ $paths[] = $file->getRelativePath();
+ }
+
+ $ref = array("", "", "", "", "foo", "");
+
+ sort($ref);
+ sort($paths);
+
+ $this->assertEquals($ref, $paths);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testRelativePathname($adapter)
+ {
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir)->sortByName();
+
+ $paths = array();
+
+ foreach ($finder as $file) {
+ $paths[] = $file->getRelativePathname();
+ }
+
+ $ref = array("test.php", "toto", "test.py", "foo", "foo".DIRECTORY_SEPARATOR."bar.tmp", "foo bar");
+
+ sort($paths);
+ sort($ref);
+
+ $this->assertEquals($ref, $paths);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendWithAFinder($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
+
+ $finder1 = $this->buildFinder($adapter);
+ $finder1->directories()->in(self::$tmpDir);
+
+ $finder = $finder->append($finder1);
+
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendWithAnArray($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
+
+ $finder->append($this->toAbsolute(array('foo', 'toto')));
+
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendReturnsAFinder($adapter)
+ {
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', $this->buildFinder($adapter)->append(array()));
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendDoesNotRequireIn($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
+
+ $finder1 = Finder::create()->append($finder);
+
+ $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator());
+ }
+
+ public function testCountDirectories()
+ {
+ $directory = Finder::create()->directories()->in(self::$tmpDir);
+ $i = 0;
+
+ foreach ($directory as $dir) {
+ $i++;
+ }
+
+ $this->assertCount($i, $directory);
+ }
+
+ public function testCountFiles()
+ {
+ $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
+ $i = 0;
+
+ foreach ($files as $file) {
+ $i++;
+ }
+
+ $this->assertCount($i, $files);
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testCountWithoutIn()
+ {
+ $finder = Finder::create()->files();
+ count($finder);
+ }
+
+ /**
+ * @dataProvider getContainsTestData
+ * @group grep
+ */
+ public function testContains($adapter, $matchPatterns, $noMatchPatterns, $expected)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
+ ->name('*.txt')->sortByName()
+ ->contains($matchPatterns)
+ ->notContains($noMatchPatterns);
+
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testContainsOnDirectory(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__)
+ ->directories()
+ ->name('Fixtures')
+ ->contains('abc');
+ $this->assertIterator(array(), $finder);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testNotContainsOnDirectory(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__)
+ ->directories()
+ ->name('Fixtures')
+ ->notContains('abc');
+ $this->assertIterator(array(), $finder);
+ }
+
+ /**
+ * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
+ * with inner FilesystemIterator in an invalid state.
+ *
+ * @see https://bugs.php.net/bug.php?id=49104
+ *
+ * @dataProvider getAdaptersTestData
+ */
+ public function testMultipleLocations(Adapter\AdapterInterface $adapter)
+ {
+ $locations = array(
+ self::$tmpDir.'/',
+ self::$tmpDir.'/toto/',
+ );
+
+ // it is expected that there are test.py test.php in the tmpDir
+ $finder = $this->buildFinder($adapter);
+ $finder->in($locations)->depth('< 1')->name('test.php');
+
+ $this->assertCount(1, $finder);
+ }
+
+ /**
+ * Iterator keys must be the file pathname.
+ *
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIteratorKeys(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir);
+ foreach ($finder as $key => $file) {
+ $this->assertEquals($file->getPathname(), $key);
+ }
+ }
+
+ public function testAdaptersOrdering()
+ {
+ $finder = Finder::create()
+ ->removeAdapters()
+ ->addAdapter(new FakeAdapter\NamedAdapter('a'), 0)
+ ->addAdapter(new FakeAdapter\NamedAdapter('b'), -50)
+ ->addAdapter(new FakeAdapter\NamedAdapter('c'), 50)
+ ->addAdapter(new FakeAdapter\NamedAdapter('d'), -25)
+ ->addAdapter(new FakeAdapter\NamedAdapter('e'), 25);
+
+ $this->assertEquals(
+ array('c', 'e', 'a', 'd', 'b'),
+ array_map(function (Adapter\AdapterInterface $adapter) {
+ return $adapter->getName();
+ }, $finder->getAdapters())
+ );
+ }
+
+ public function testAdaptersChaining()
+ {
+ $iterator = new \ArrayIterator(array());
+ $filenames = $this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto'));
+ foreach ($filenames as $file) {
+ $iterator->append(new \Symfony\Component\Finder\SplFileInfo($file, null, null));
+ }
+
+ $finder = Finder::create()
+ ->removeAdapters()
+ ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3)
+ ->addAdapter(new FakeAdapter\FailingAdapter(), 2)
+ ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1);
+
+ $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator());
+ }
+
+ public function getAdaptersTestData()
+ {
+ return array_map(
+ function ($adapter) { return array($adapter); },
+ $this->getValidAdapters()
+ );
+ }
+
+ public function getContainsTestData()
+ {
+ $tests = array(
+ array('', '', array()),
+ array('foo', 'bar', array()),
+ array('', 'foobar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
+ array('lorem ipsum dolor sit amet', 'foobar', array('lorem.txt')),
+ array('sit', 'bar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
+ array('dolor sit amet', '@^L@m', array('dolor.txt', 'ipsum.txt')),
+ array('/^lorem ipsum dolor sit amet$/m', 'foobar', array('lorem.txt')),
+ array('lorem', 'foobar', array('lorem.txt')),
+ array('', 'lorem', array('dolor.txt', 'ipsum.txt')),
+ array('ipsum dolor sit amet', '/^IPSUM/m', array('lorem.txt')),
+ );
+
+ return $this->buildTestData($tests);
+ }
+
+ public function getRegexNameTestData()
+ {
+ $tests = array(
+ array('~.+\\.p.+~i'),
+ array('~t.*s~i'),
+ );
+
+ return $this->buildTestData($tests);
+ }
+
+ /**
+ * @dataProvider getTestPathData
+ */
+ public function testPath(Adapter\AdapterInterface $adapter, $matchPatterns, $noMatchPatterns, array $expected)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
+ ->path($matchPatterns)
+ ->notPath($noMatchPatterns);
+
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
+ }
+
+ public function testAdapterSelection()
+ {
+ // test that by default, PhpAdapter is selected
+ $adapters = Finder::create()->getAdapters();
+ $this->assertTrue($adapters[0] instanceof Adapter\PhpAdapter);
+
+ // test another adapter selection
+ $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters();
+ $this->assertTrue($adapters[0] instanceof Adapter\GnuFindAdapter);
+
+ // test that useBestAdapter method removes selection
+ $adapters = Finder::create()->useBestAdapter()->getAdapters();
+ $this->assertFalse($adapters[0] instanceof Adapter\PhpAdapter);
+ }
+
+ public function getTestPathData()
+ {
+ $tests = array(
+ array('', '', array()),
+ array('/^A\/B\/C/', '/C$/',
+ array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat')
+ ),
+ array('/^A\/B/', 'foobar',
+ array(
+ 'A'.DIRECTORY_SEPARATOR.'B',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ )
+ ),
+ array('A/B/C', 'foobar',
+ array(
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
+ )
+ ),
+ array('A/B', 'foobar',
+ array(
+ //dirs
+ 'A'.DIRECTORY_SEPARATOR.'B',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ //files
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
+ )
+ ),
+ array('/^with space\//', 'foobar',
+ array(
+ 'with space'.DIRECTORY_SEPARATOR.'foo.txt',
+ )
+ ),
+ );
+
+ return $this->buildTestData($tests);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAccessDeniedException(Adapter\AdapterInterface $adapter)
+ {
+ if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+ $this->markTestSkipped('chmod is not supported on Windows');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->in(self::$tmpDir);
+
+ // make 'foo' directory non-readable
+ chmod(self::$tmpDir.DIRECTORY_SEPARATOR.'foo', 0333);
+
+ try {
+ $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
+ $this->fail('Finder should throw an exception when opening a non-readable directory.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\Exception\\AccessDeniedException', $e);
+ }
+
+ // restore original permissions
+ chmod(self::$tmpDir.DIRECTORY_SEPARATOR.'foo', 0777);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIgnoredAccessDeniedException(Adapter\AdapterInterface $adapter)
+ {
+ if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+ $this->markTestSkipped('chmod is not supported on Windows');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir);
+
+ // make 'foo' directory non-readable
+ chmod(self::$tmpDir.DIRECTORY_SEPARATOR.'foo', 0333);
+
+ $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
+
+ // restore original permissions
+ chmod(self::$tmpDir.DIRECTORY_SEPARATOR.'foo', 0777);
+ }
+
+ private function buildTestData(array $tests)
+ {
+ $data = array();
+ foreach ($this->getValidAdapters() as $adapter) {
+ foreach ($tests as $test) {
+ $data[] = array_merge(array($adapter), $test);
+ }
+ }
+
+ return $data;
+ }
+
+ private function buildFinder(Adapter\AdapterInterface $adapter)
+ {
+ return Finder::create()
+ ->removeAdapters()
+ ->addAdapter($adapter);
+ }
+
+ private function getValidAdapters()
+ {
+ return array_filter(
+ array(
+ new Adapter\BsdFindAdapter(),
+ new Adapter\GnuFindAdapter(),
+ new Adapter\PhpAdapter()
+ ),
+ function (Adapter\AdapterInterface $adapter) {
+ return $adapter->isSupported();
+ }
+ );
+ }
+
+ /**
+ * Searching in multiple locations with sub directories involves
+ * AppendIterator which does an unnecessary rewind which leaves
+ * FilterIterator with inner FilesystemIterator in an invalid state.
+ *
+ * @see https://bugs.php.net/bug.php?id=49104
+ */
+ public function testMultipleLocationsWithSubDirectories()
+ {
+ $locations = array(
+ __DIR__.'/Fixtures/one',
+ self::$tmpDir.DIRECTORY_SEPARATOR.'toto',
+ );
+
+ $finder = new Finder();
+ $finder->in($locations)->depth('< 10')->name('*.neon');
+
+ $expected = array(
+ __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon',
+ __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon',
+ );
+
+ $this->assertIterator($expected, $finder);
+ $this->assertIteratorInForeach($expected, $finder);
+ }
+
+ public function testNonSeekableStream()
+ {
+ if (!in_array('ftp', stream_get_wrappers())) {
+ $this->markTestSkipped(sprintf('Unavailable stream "%s".', 'ftp'));
+ }
+
+ try {
+ $i = Finder::create()->in('ftp://ftp.mozilla.org/')->depth(0)->getIterator();
+ } catch (\UnexpectedValueException $e) {
+ $this->markTestSkipped(sprintf('Unsupported stream "%s".', 'ftp'));
+ }
+
+ $contains = array(
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'index.html',
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
+ );
+
+ $this->assertIteratorInForeach($contains, $i);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt
new file mode 100644
index 0000000..658bec6
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt
@@ -0,0 +1,2 @@
+dolor sit amet
+DOLOR SIT AMET
\ No newline at end of file
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt
new file mode 100644
index 0000000..c7f392d
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt
@@ -0,0 +1,2 @@
+ipsum dolor sit amet
+IPSUM DOLOR SIT AMET
\ No newline at end of file
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt
new file mode 100644
index 0000000..2991a2c
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt
@@ -0,0 +1,2 @@
+lorem ipsum dolor sit amet
+LOREM IPSUM DOLOR SIT AMET
\ No newline at end of file
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php
new file mode 100644
index 0000000..62629b1
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\CustomFilterIterator;
+
+class CustomFilterIteratorTest extends IteratorTestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testWithInvalidFilter()
+ {
+ new CustomFilterIterator(new Iterator(), array('foo'));
+ }
+
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($filters, $expected)
+ {
+ $inner = new Iterator(array('test.php', 'test.py', 'foo.php'));
+
+ $iterator = new CustomFilterIterator($inner, $filters);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ return array(
+ array(array(function (\SplFileInfo $fileinfo) { return false; }), array()),
+ array(array(function (\SplFileInfo $fileinfo) { return preg_match('/^test/', $fileinfo) > 0; }), array('test.php', 'test.py')),
+ array(array('is_dir'), array()),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php
new file mode 100644
index 0000000..18896d5
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php
@@ -0,0 +1,74 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+class DateRangeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($size, $expected)
+ {
+ $inner = new Iterator(self::$files);
+
+ $iterator = new DateRangeFilterIterator($inner, $size);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $since20YearsAgo = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ 'foo bar',
+ '.foo/bar',
+ );
+
+ $since2MonthsAgo = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'toto',
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ 'foo bar',
+ '.foo/bar',
+ );
+
+ $untilLastMonth = array(
+ '.git',
+ 'foo',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ '.foo',
+ );
+
+ return array(
+ array(array(new DateComparator('since 20 years ago')), $this->toAbsolute($since20YearsAgo)),
+ array(array(new DateComparator('since 2 months ago')), $this->toAbsolute($since2MonthsAgo)),
+ array(array(new DateComparator('until last month')), $this->toAbsolute($untilLastMonth)),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php
new file mode 100644
index 0000000..be06f1c
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php
@@ -0,0 +1,81 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
+
+class DepthRangeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($minDepth, $maxDepth, $expected)
+ {
+ $inner = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
+
+ $iterator = new DepthRangeFilterIterator($inner, $minDepth, $maxDepth);
+
+ $actual = array_keys(iterator_to_array($iterator));
+ sort($expected);
+ sort($actual);
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function getAcceptData()
+ {
+ $lessThan1 = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'test.php',
+ 'toto',
+ '.foo',
+ '.bar',
+ 'foo bar',
+ );
+
+ $lessThanOrEqualTo1 = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ '.foo',
+ '.foo/.bar',
+ '.bar',
+ 'foo bar',
+ '.foo/bar',
+ );
+
+ $graterThanOrEqualTo1 = array(
+ 'foo/bar.tmp',
+ '.foo/.bar',
+ '.foo/bar',
+ );
+
+ $equalTo1 = array(
+ 'foo/bar.tmp',
+ '.foo/.bar',
+ '.foo/bar',
+ );
+
+ return array(
+ array(0, 0, $this->toAbsolute($lessThan1)),
+ array(0, 1, $this->toAbsolute($lessThanOrEqualTo1)),
+ array(2, PHP_INT_MAX, array()),
+ array(1, PHP_INT_MAX, $this->toAbsolute($graterThanOrEqualTo1)),
+ array(1, 1, $this->toAbsolute($equalTo1)),
+ );
+ }
+
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php
new file mode 100644
index 0000000..e299fe7
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php
@@ -0,0 +1,65 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
+use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
+
+class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($directories, $expected)
+ {
+ $inner = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
+
+ $iterator = new ExcludeDirectoryFilterIterator($inner, $directories);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $foo = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'test.py',
+ 'test.php',
+ 'toto',
+ 'foo bar'
+ );
+
+ $fo = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'test.py',
+ 'foo',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ 'foo bar'
+ );
+
+ return array(
+ array(array('foo'), $this->toAbsolute($foo)),
+ array(array('fo'), $this->toAbsolute($fo)),
+ );
+ }
+
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php
new file mode 100644
index 0000000..61f0e9b
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php
@@ -0,0 +1,66 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FilePathsIterator;
+
+class FilePathsIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getSubPathData
+ */
+ public function testSubPath($baseDir, array $paths, array $subPaths, array $subPathnames)
+ {
+ $iterator = new FilePathsIterator($paths, $baseDir);
+
+ foreach ($iterator as $index => $file) {
+ $this->assertEquals($paths[$index], $file->getPathname());
+ $this->assertEquals($subPaths[$index], $iterator->getSubPath());
+ $this->assertEquals($subPathnames[$index], $iterator->getSubPathname());
+ }
+ }
+
+ public function getSubPathData()
+ {
+ $tmpDir = sys_get_temp_dir().'/symfony2_finder';
+
+ return array(
+ array(
+ $tmpDir,
+ array( // paths
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => $tmpDir.DIRECTORY_SEPARATOR.'.git',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => $tmpDir.DIRECTORY_SEPARATOR.'test.py',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => $tmpDir.DIRECTORY_SEPARATOR.'foo',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => $tmpDir.DIRECTORY_SEPARATOR.'test.php',
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => $tmpDir.DIRECTORY_SEPARATOR.'toto'
+ ),
+ array( // subPaths
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => ''
+ ),
+ array( // subPathnames
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => '.git',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => 'test.py',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => 'foo',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => 'test.php',
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => 'toto'
+ ),
+ ),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php
new file mode 100644
index 0000000..b2432ca
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php
@@ -0,0 +1,72 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FileTypeFilterIterator;
+
+class FileTypeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($mode, $expected)
+ {
+ $inner = new InnerTypeIterator(self::$files);
+
+ $iterator = new FileTypeFilterIterator($inner, $mode);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $onlyFiles = array(
+ 'test.py',
+ 'foo/bar.tmp',
+ 'test.php',
+ '.bar',
+ '.foo/.bar',
+ '.foo/bar',
+ 'foo bar',
+ );
+
+ $onlyDirectories = array(
+ '.git',
+ 'foo',
+ 'toto',
+ '.foo',
+ );
+
+ return array(
+ array(FileTypeFilterIterator::ONLY_FILES, $this->toAbsolute($onlyFiles)),
+ array(FileTypeFilterIterator::ONLY_DIRECTORIES, $this->toAbsolute($onlyDirectories)),
+ );
+ }
+}
+
+class InnerTypeIterator extends \ArrayIterator
+{
+ public function current()
+ {
+ return new \SplFileInfo(parent::current());
+ }
+
+ public function isFile()
+ {
+ return $this->current()->isFile();
+ }
+
+ public function isDir()
+ {
+ return $this->current()->isDir();
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php
new file mode 100644
index 0000000..dbc05b5
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php
@@ -0,0 +1,87 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
+
+class FilecontentFilterIteratorTest extends IteratorTestCase
+{
+
+ public function testAccept()
+ {
+ $inner = new MockFileListIterator(array('test.txt'));
+ $iterator = new FilecontentFilterIterator($inner, array(), array());
+ $this->assertIterator(array('test.txt'), $iterator);
+ }
+
+ public function testDirectory()
+ {
+ $inner = new MockFileListIterator(array('directory'));
+ $iterator = new FilecontentFilterIterator($inner, array('directory'), array());
+ $this->assertIterator(array(), $iterator);
+ }
+
+ public function testUnreadableFile()
+ {
+ $inner = new MockFileListIterator(array('file r-'));
+ $iterator = new FilecontentFilterIterator($inner, array('file r-'), array());
+ $this->assertIterator(array(), $iterator);
+ }
+
+ /**
+ * @dataProvider getTestFilterData
+ */
+ public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
+ {
+ $iterator = new FilecontentFilterIterator($inner, $matchPatterns, $noMatchPatterns);
+ $this->assertIterator($resultArray, $iterator);
+ }
+
+ public function getTestFilterData()
+ {
+ $inner = new MockFileListIterator();
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'a.txt',
+ 'contents' => 'Lorem ipsum...',
+ 'type' => 'file',
+ 'mode' => 'r+')
+ );
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'b.yml',
+ 'contents' => 'dolor sit...',
+ 'type' => 'file',
+ 'mode' => 'r+')
+ );
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'some/other/dir/third.php',
+ 'contents' => 'amet...',
+ 'type' => 'file',
+ 'mode' => 'r+')
+ );
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'unreadable-file.txt',
+ 'contents' => false,
+ 'type' => 'file',
+ 'mode' => 'r+')
+ );
+
+ return array(
+ array($inner, array('.'), array(), array('a.txt', 'b.yml', 'some/other/dir/third.php')),
+ array($inner, array('ipsum'), array(), array('a.txt')),
+ array($inner, array('i', 'amet'), array('Lorem', 'amet'), array('b.yml')),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php
new file mode 100644
index 0000000..c4b9795
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php
@@ -0,0 +1,54 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
+
+class FilenameFilterIteratorTest extends IteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($matchPatterns, $noMatchPatterns, $expected)
+ {
+ $inner = new InnerNameIterator(array('test.php', 'test.py', 'foo.php'));
+
+ $iterator = new FilenameFilterIterator($inner, $matchPatterns, $noMatchPatterns);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ return array(
+ array(array('test.*'), array(), array('test.php', 'test.py')),
+ array(array(), array('test.*'), array('foo.php')),
+ array(array('*.php'), array('test.*'), array('foo.php')),
+ array(array('*.php', '*.py'), array('foo.*'), array('test.php', 'test.py')),
+ array(array('/\.php$/'), array(), array('test.php', 'foo.php')),
+ array(array(), array('/\.php$/'), array('test.py')),
+ );
+ }
+}
+
+class InnerNameIterator extends \ArrayIterator
+{
+ public function current()
+ {
+ return new \SplFileInfo(parent::current());
+ }
+
+ public function getFilename()
+ {
+ return parent::current();
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php
new file mode 100644
index 0000000..029a266
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+/**
+ * @author Alex Bogomazov
+ */
+class FilterIteratorTest extends RealIteratorTestCase
+{
+ public function testFilterFilesystemIterators()
+ {
+ $i = new \FilesystemIterator($this->toAbsolute());
+
+ // it is expected that there are test.py test.php in the tmpDir
+ $i = $this->getMockForAbstractClass('Symfony\Component\Finder\Iterator\FilterIterator', array($i));
+ $i->expects($this->any())
+ ->method('accept')
+ ->will($this->returnCallback(function () use ($i) {
+ return (bool) preg_match('/\.php/', (string) $i->current());
+ })
+ );
+
+ $c = 0;
+ foreach ($i as $item) {
+ $c++;
+ }
+
+ $this->assertEquals(1, $c);
+
+ $i->rewind();
+
+ $c = 0;
+ foreach ($i as $item) {
+ $c++;
+ }
+
+ // This would fail with \FilterIterator but works with Symfony\Component\Finder\Iterator\FilterIterator
+ // see https://bugs.php.net/bug.php?id=49104
+ $this->assertEquals(1, $c);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php
new file mode 100644
index 0000000..849bf08
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php
@@ -0,0 +1,55 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+class Iterator implements \Iterator
+{
+ protected $values = array();
+
+ public function __construct(array $values = array())
+ {
+ foreach ($values as $value) {
+ $this->attach(new \SplFileInfo($value));
+ }
+ $this->rewind();
+ }
+
+ public function attach(\SplFileInfo $fileinfo)
+ {
+ $this->values[] = $fileinfo;
+ }
+
+ public function rewind()
+ {
+ reset($this->values);
+ }
+
+ public function valid()
+ {
+ return false !== $this->current();
+ }
+
+ public function next()
+ {
+ next($this->values);
+ }
+
+ public function current()
+ {
+ return current($this->values);
+ }
+
+ public function key()
+ {
+ return key($this->values);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php
new file mode 100644
index 0000000..504cfb0
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php
@@ -0,0 +1,73 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+abstract class IteratorTestCase extends \PHPUnit_Framework_TestCase
+{
+ protected function assertIterator($expected, \Traversable $iterator)
+ {
+ // set iterator_to_array $use_key to false to avoid values merge
+ // this made FinderTest::testAppendWithAnArray() failed with GnuFinderAdapter
+ $values = array_map(function (\SplFileInfo $fileinfo) { return str_replace('/', DIRECTORY_SEPARATOR, $fileinfo->getPathname()); }, iterator_to_array($iterator, false));
+
+ $expected = array_map(function ($path) { return str_replace('/', DIRECTORY_SEPARATOR, $path); }, $expected);
+
+ sort($values);
+ sort($expected);
+
+ $this->assertEquals($expected, array_values($values));
+ }
+
+ protected function assertOrderedIterator($expected, \Traversable $iterator)
+ {
+ $values = array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator));
+
+ $this->assertEquals($expected, array_values($values));
+ }
+
+ /**
+ * Same as IteratorTestCase::assertIterator with foreach usage
+ *
+ * @param array $expected
+ * @param \Traversable $iterator
+ */
+ protected function assertIteratorInForeach($expected, \Traversable $iterator)
+ {
+ $values = array();
+ foreach ($iterator as $file) {
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
+ $values[] = $file->getPathname();
+ }
+
+ sort($values);
+ sort($expected);
+
+ $this->assertEquals($expected, array_values($values));
+ }
+
+ /**
+ * Same as IteratorTestCase::assertOrderedIterator with foreach usage
+ *
+ * @param array $expected
+ * @param \Traversable $iterator
+ */
+ protected function assertOrderedIteratorInForeach($expected, \Traversable $iterator)
+ {
+ $values = array();
+ foreach ($iterator as $file) {
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
+ $values[] = $file->getPathname();
+ }
+
+ $this->assertEquals($expected, array_values($values));
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php
new file mode 100644
index 0000000..eb0adfa
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+class MockFileListIterator extends \ArrayIterator
+{
+ public function __construct(array $filesArray = array())
+ {
+ $files = array_map(function ($file) { return new MockSplFileInfo($file); }, $filesArray);
+ parent::__construct($files);
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php
new file mode 100644
index 0000000..a50e4c9
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php
@@ -0,0 +1,134 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+class MockSplFileInfo extends \SplFileInfo
+{
+ const TYPE_DIRECTORY = 1;
+ const TYPE_FILE = 2;
+ const TYPE_UNKNOWN = 3;
+
+ private $contents = null;
+ private $mode = null;
+ private $type = null;
+ private $relativePath = null;
+ private $relativePathname = null;
+
+ public function __construct($param)
+ {
+ if (is_string($param)) {
+ parent::__construct($param);
+ } elseif (is_array($param)) {
+ $defaults = array(
+ 'name' => 'file.txt',
+ 'contents' => null,
+ 'mode' => null,
+ 'type' => null,
+ 'relativePath' => null,
+ 'relativePathname' => null,
+ );
+ $defaults = array_merge($defaults, $param);
+ parent::__construct($defaults['name']);
+ $this->setContents($defaults['contents']);
+ $this->setMode($defaults['mode']);
+ $this->setType($defaults['type']);
+ $this->setRelativePath($defaults['relativePath']);
+ $this->setRelativePathname($defaults['relativePathname']);
+ } else {
+ throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param));
+ }
+ }
+
+ public function isFile()
+ {
+ if ($this->type === null) {
+ return preg_match('/file/', $this->getFilename());
+ };
+
+ return self::TYPE_FILE === $this->type;
+ }
+
+ public function isDir()
+ {
+ if ($this->type === null) {
+ return preg_match('/directory/', $this->getFilename());
+ }
+
+ return self::TYPE_DIRECTORY === $this->type;
+ }
+
+ public function isReadable()
+ {
+ if ($this->mode === null) {
+ return preg_match('/r\+/', $this->getFilename());
+ }
+
+ return preg_match('/r\+/', $this->mode);
+ }
+
+ public function getContents()
+ {
+ return $this->contents;
+ }
+
+ public function setContents($contents)
+ {
+ $this->contents = $contents;
+ }
+
+ public function setMode($mode)
+ {
+ $this->mode = $mode;
+ }
+
+ public function setType($type)
+ {
+ if (is_string($type)) {
+ switch ($type) {
+ case 'directory':
+ $this->type = self::TYPE_DIRECTORY;
+ case 'd':
+ $this->type = self::TYPE_DIRECTORY;
+ break;
+ case 'file':
+ $this->type = self::TYPE_FILE;
+ case 'f':
+ $this->type = self::TYPE_FILE;
+ break;
+ default:
+ $this->type = self::TYPE_UNKNOWN;
+ }
+ } else {
+ $this->type = $type;
+ }
+ }
+
+ public function setRelativePath($relativePath)
+ {
+ $this->relativePath = $relativePath;
+ }
+
+ public function setRelativePathname($relativePathname)
+ {
+ $this->relativePathname = $relativePathname;
+ }
+
+ public function getRelativePath()
+ {
+ return $this->relativePath;
+ }
+
+ public function getRelativePathname()
+ {
+ return $this->relativePathname;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php
new file mode 100644
index 0000000..89d8edb
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\MultiplePcreFilterIterator;
+
+class MultiplePcreFilterIteratorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getIsRegexFixtures
+ */
+ public function testIsRegex($string, $isRegex, $message)
+ {
+ $testIterator = new TestMultiplePcreFilterIterator();
+ $this->assertEquals($isRegex, $testIterator->isRegex($string), $message);
+ }
+
+ public function getIsRegexFixtures()
+ {
+ return array(
+ array('foo', false, 'string'),
+ array(' foo ', false, '" " is not a valid delimiter'),
+ array('\\foo\\', false, '"\\" is not a valid delimiter'),
+ array('afooa', false, '"a" is not a valid delimiter'),
+ array('//', false, 'the pattern should contain at least 1 character'),
+ array('/a/', true, 'valid regex'),
+ array('/foo/', true, 'valid regex'),
+ array('/foo/i', true, 'valid regex with a single modifier'),
+ array('/foo/imsxu', true, 'valid regex with multiple modifiers'),
+ array('#foo#', true, '"#" is a valid delimiter'),
+ array('{foo}', true, '"{,}" is a valid delimiter pair'),
+ array('*foo.*', false, '"*" is not considered as a valid delimiter'),
+ array('?foo.?', false, '"?" is not considered as a valid delimiter'),
+ );
+ }
+}
+
+class TestMultiplePcreFilterIterator extends MultiplePcreFilterIterator
+{
+ public function __construct()
+ {
+ }
+
+ public function accept()
+ {
+ throw new \BadFunctionCallException('Not implemented');
+ }
+
+ public function isRegex($str)
+ {
+ return parent::isRegex($str);
+ }
+
+ public function toRegex($str)
+ {
+ throw new \BadFunctionCallException('Not implemented');
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php
new file mode 100644
index 0000000..6f83e44
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php
@@ -0,0 +1,85 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\PathFilterIterator;
+
+class PathFilterIteratorTest extends IteratorTestCase
+{
+
+ /**
+ * @dataProvider getTestFilterData
+ */
+ public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
+ {
+ $iterator = new PathFilterIterator($inner, $matchPatterns, $noMatchPatterns);
+ $this->assertIterator($resultArray, $iterator);
+ }
+
+ public function getTestFilterData()
+ {
+ $inner = new MockFileListIterator();
+
+ //PATH: A/B/C/abc.dat
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'abc.dat',
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ ));
+
+ //PATH: A/B/ab.dat
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'ab.dat',
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ ));
+
+ //PATH: A/a.dat
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'a.dat',
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'a.dat',
+ ));
+
+ //PATH: copy/A/B/C/abc.dat.copy
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'abc.dat.copy',
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ ));
+
+ //PATH: copy/A/B/ab.dat.copy
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'ab.dat.copy',
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ ));
+
+ //PATH: copy/A/a.dat.copy
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'a.dat.copy',
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'a.dat',
+ ));
+
+ return array(
+ array($inner, array('/^A/'), array(), array('abc.dat', 'ab.dat', 'a.dat')),
+ array($inner, array('/^A\/B/'), array(), array('abc.dat', 'ab.dat')),
+ array($inner, array('/^A\/B\/C/'), array(), array('abc.dat')),
+ array($inner, array('/A\/B\/C/'), array(), array('abc.dat', 'abc.dat.copy')),
+
+ array($inner, array('A'), array(), array('abc.dat', 'ab.dat', 'a.dat', 'abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
+ array($inner, array('A/B'), array(), array('abc.dat', 'ab.dat', 'abc.dat.copy', 'ab.dat.copy')),
+ array($inner, array('A/B/C'), array(), array('abc.dat', 'abc.dat.copy')),
+
+ array($inner, array('copy/A'), array(), array('abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
+ array($inner, array('copy/A/B'), array(), array('abc.dat.copy', 'ab.dat.copy')),
+ array($inner, array('copy/A/B/C'), array(), array('abc.dat.copy')),
+
+ );
+ }
+
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php
new file mode 100644
index 0000000..65edb1e
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php
@@ -0,0 +1,107 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+abstract class RealIteratorTestCase extends IteratorTestCase
+{
+
+ protected static $tmpDir;
+ protected static $files;
+
+ public static function setUpBeforeClass()
+ {
+ self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony2_finder';
+
+ self::$files = array(
+ '.git/',
+ '.foo/',
+ '.foo/.bar',
+ '.foo/bar',
+ '.bar',
+ 'test.py',
+ 'foo/',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto/',
+ 'foo bar'
+ );
+
+ self::$files = self::toAbsolute(self::$files);
+
+ if (is_dir(self::$tmpDir)) {
+ self::tearDownAfterClass();
+ } else {
+ mkdir(self::$tmpDir);
+ }
+
+ foreach (self::$files as $file) {
+ if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
+ mkdir($file);
+ } else {
+ touch($file);
+ }
+ }
+
+ file_put_contents(self::toAbsolute('test.php'), str_repeat(' ', 800));
+ file_put_contents(self::toAbsolute('test.py'), str_repeat(' ', 2000));
+
+ touch(self::toAbsolute('foo/bar.tmp'), strtotime('2005-10-15'));
+ touch(self::toAbsolute('test.php'), strtotime('2005-10-15'));
+ }
+
+ public static function tearDownAfterClass()
+ {
+ foreach (array_reverse(self::$files) as $file) {
+ if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
+ @rmdir($file);
+ } else {
+ @unlink($file);
+ }
+ }
+ }
+
+ protected static function toAbsolute($files = null)
+ {
+ /*
+ * Without the call to setUpBeforeClass() property can be null.
+ */
+ if (!self::$tmpDir) {
+ self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony2_finder';
+ }
+
+ if (is_array($files)) {
+ $f = array();
+ foreach ($files as $file) {
+ $f[] = self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $file);
+ }
+
+ return $f;
+ }
+
+ if (is_string($files)) {
+ return self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $files);
+ }
+
+ return self::$tmpDir;
+ }
+
+ protected static function toAbsoluteFixtures($files)
+ {
+ $f = array();
+ foreach ($files as $file) {
+ $f[] = realpath(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$file);
+ }
+
+ return $f;
+ }
+
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
new file mode 100644
index 0000000..b9ba38b
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
@@ -0,0 +1,83 @@
+
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
+
+class RecursiveDirectoryIteratorTest extends IteratorTestCase
+{
+ /**
+ * @dataProvider getPaths
+ *
+ * @param string $path
+ * @param bool $seekable
+ * @param array $contains
+ * @param string $message
+ */
+ public function testRewind($path, $seekable, $contains, $message = null)
+ {
+ try {
+ $i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
+ } catch (\UnexpectedValueException $e) {
+ $this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
+ }
+
+ $i->rewind();
+
+ $this->assertTrue(true, $message);
+ }
+
+ /**
+ * @dataProvider getPaths
+ *
+ * @param string $path
+ * @param bool $seekable
+ * @param array $contains
+ * @param string $message
+ */
+ public function testSeek($path, $seekable, $contains, $message = null)
+ {
+ try {
+ $i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
+ } catch (\UnexpectedValueException $e) {
+ $this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
+ }
+
+ $actual = array();
+
+ $i->seek(0);
+ $actual[] = $i->getPathname();
+
+ $i->seek(1);
+ $actual[] = $i->getPathname();
+
+ $i->seek(2);
+ $actual[] = $i->getPathname();
+
+ $this->assertEquals($contains, $actual);
+ }
+
+ public function getPaths()
+ {
+ $data = array();
+
+ // ftp
+ $contains = array(
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'index.html',
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
+ );
+ $data[] = array('ftp://ftp.mozilla.org/', false, $contains);
+
+ return $data;
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php
new file mode 100644
index 0000000..726df9e
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php
@@ -0,0 +1,68 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
+use Symfony\Component\Finder\Comparator\NumberComparator;
+
+class SizeRangeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($size, $expected)
+ {
+ $inner = new InnerSizeIterator(self::$files);
+
+ $iterator = new SizeRangeFilterIterator($inner, $size);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $lessThan1KGreaterThan05K = array(
+ '.foo',
+ '.git',
+ 'foo',
+ 'test.php',
+ 'toto',
+ );
+
+ return array(
+ array(array(new NumberComparator('< 1K'), new NumberComparator('> 0.5K')), $this->toAbsolute($lessThan1KGreaterThan05K)),
+ );
+ }
+}
+
+class InnerSizeIterator extends \ArrayIterator
+{
+ public function current()
+ {
+ return new \SplFileInfo(parent::current());
+ }
+
+ public function getFilename()
+ {
+ return parent::current();
+ }
+
+ public function isFile()
+ {
+ return $this->current()->isFile();
+ }
+
+ public function getSize()
+ {
+ return $this->current()->getSize();
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
new file mode 100644
index 0000000..a2ca6ef
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
@@ -0,0 +1,156 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\SortableIterator;
+
+class SortableIteratorTest extends RealIteratorTestCase
+{
+ public function testConstructor()
+ {
+ try {
+ new SortableIterator(new Iterator(array()), 'foobar');
+ $this->fail('__construct() throws an \InvalidArgumentException exception if the mode is not valid');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException exception if the mode is not valid');
+ }
+ }
+
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($mode, $expected)
+ {
+ if (!is_callable($mode)) {
+ switch ($mode) {
+ case SortableIterator::SORT_BY_ACCESSED_TIME :
+ file_get_contents(self::toAbsolute('.git'));
+ sleep(1);
+ file_get_contents(self::toAbsolute('.bar'));
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME :
+ file_put_contents(self::toAbsolute('test.php'), 'foo');
+ sleep(1);
+ file_put_contents(self::toAbsolute('test.py'), 'foo');
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME :
+ file_put_contents(self::toAbsolute('test.php'), 'foo');
+ sleep(1);
+ file_put_contents(self::toAbsolute('test.py'), 'foo');
+ break;
+ }
+ }
+
+ $inner = new Iterator(self::$files);
+
+ $iterator = new SortableIterator($inner, $mode);
+
+ $this->assertOrderedIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+
+ $sortByName = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'foo',
+ 'foo bar',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'test.py',
+ 'toto',
+ );
+
+ $sortByType = array(
+ '.foo',
+ '.git',
+ 'foo',
+ 'toto',
+ '.bar',
+ '.foo/.bar',
+ '.foo/bar',
+ 'foo bar',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'test.py',
+ );
+
+ $customComparison = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'foo',
+ 'foo bar',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'test.py',
+ 'toto',
+ );
+
+ $sortByAccessedTime = array(
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ 'foo bar',
+ 'foo',
+ 'test.py',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ '.bar'
+ );
+
+ $sortByChangedTime = array(
+ 'foo',
+ 'foo/bar.tmp',
+ 'toto',
+ '.git',
+ '.bar',
+ '.foo',
+ 'foo bar',
+ '.foo/.bar',
+ '.foo/bar',
+ 'test.php',
+ 'test.py'
+ );
+
+ $sortByModifiedTime = array(
+ 'foo/bar.tmp',
+ 'foo',
+ 'toto',
+ '.git',
+ '.bar',
+ '.foo',
+ 'foo bar',
+ '.foo/.bar',
+ '.foo/bar',
+ 'test.php',
+ 'test.py'
+ );
+
+ return array(
+ array(SortableIterator::SORT_BY_NAME, $this->toAbsolute($sortByName)),
+ array(SortableIterator::SORT_BY_TYPE, $this->toAbsolute($sortByType)),
+ array(SortableIterator::SORT_BY_ACCESSED_TIME, $this->toAbsolute($sortByAccessedTime)),
+ array(SortableIterator::SORT_BY_CHANGED_TIME, $this->toAbsolute($sortByChangedTime)),
+ array(SortableIterator::SORT_BY_MODIFIED_TIME, $this->toAbsolute($sortByModifiedTime)),
+ array(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealpath(), $b->getRealpath()); }, $this->toAbsolute($customComparison)),
+ );
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/composer.json b/core/vendor/symfony/finder/Symfony/Component/Finder/composer.json
new file mode 100644
index 0000000..7de4713
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/composer.json
@@ -0,0 +1,31 @@
+{
+ "name": "symfony/finder",
+ "type": "library",
+ "description": "Symfony Finder Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Finder\\": "" }
+ },
+ "target-dir": "Symfony/Component/Finder",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ }
+}
diff --git a/core/vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist b/core/vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist
new file mode 100644
index 0000000..2327223
--- /dev/null
+++ b/core/vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist
@@ -0,0 +1,29 @@
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+ ./Tests
+ ./vendor
+
+
+
+