4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Console\Tests\Input;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Console\Input\ArgvInput;
16 use Symfony\Component\Console\Input\InputDefinition;
17 use Symfony\Component\Console\Input\InputArgument;
18 use Symfony\Component\Console\Input\InputOption;
20 class ArgvInputTest extends TestCase
22 public function testConstructor()
24 $_SERVER['argv'] = array('cli.php', 'foo');
25 $input = new ArgvInput();
26 $r = new \ReflectionObject($input);
27 $p = $r->getProperty('tokens');
28 $p->setAccessible(true);
30 $this->assertEquals(array('foo'), $p->getValue($input), '__construct() automatically get its input from the argv server variable');
33 public function testParseArguments()
35 $input = new ArgvInput(array('cli.php', 'foo'));
36 $input->bind(new InputDefinition(array(new InputArgument('name'))));
37 $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');
39 $input->bind(new InputDefinition(array(new InputArgument('name'))));
40 $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() is stateless');
44 * @dataProvider provideOptions
46 public function testParseOptions($input, $options, $expectedOptions, $message)
48 $input = new ArgvInput($input);
49 $input->bind(new InputDefinition($options));
51 $this->assertEquals($expectedOptions, $input->getOptions(), $message);
54 public function provideOptions()
58 array('cli.php', '--foo'),
59 array(new InputOption('foo')),
61 '->parse() parses long options without a value',
64 array('cli.php', '--foo=bar'),
65 array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
66 array('foo' => 'bar'),
67 '->parse() parses long options with a required value (with a = separator)',
70 array('cli.php', '--foo', 'bar'),
71 array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
72 array('foo' => 'bar'),
73 '->parse() parses long options with a required value (with a space separator)',
76 array('cli.php', '--foo='),
77 array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
79 '->parse() parses long options with optional value which is empty (with a = separator) as null',
82 array('cli.php', '--foo=', 'bar'),
83 array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)),
85 '->parse() parses long options with optional value which is empty (with a = separator) followed by an argument',
88 array('cli.php', '-f'),
89 array(new InputOption('foo', 'f')),
91 '->parse() parses short options without a value',
94 array('cli.php', '-fbar'),
95 array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
96 array('foo' => 'bar'),
97 '->parse() parses short options with a required value (with no separator)',
100 array('cli.php', '-f', 'bar'),
101 array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
102 array('foo' => 'bar'),
103 '->parse() parses short options with a required value (with a space separator)',
106 array('cli.php', '-f', ''),
107 array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
109 '->parse() parses short options with an optional empty value',
112 array('cli.php', '-f', '', 'foo'),
113 array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
115 '->parse() parses short options with an optional empty value followed by an argument',
118 array('cli.php', '-f', '', '-b'),
119 array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
120 array('foo' => '', 'bar' => true),
121 '->parse() parses short options with an optional empty value followed by an option',
124 array('cli.php', '-f', '-b', 'foo'),
125 array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
126 array('foo' => null, 'bar' => true),
127 '->parse() parses short options with an optional value which is not present',
130 array('cli.php', '-fb'),
131 array(new InputOption('foo', 'f'), new InputOption('bar', 'b')),
132 array('foo' => true, 'bar' => true),
133 '->parse() parses short options when they are aggregated as a single one',
136 array('cli.php', '-fb', 'bar'),
137 array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_REQUIRED)),
138 array('foo' => true, 'bar' => 'bar'),
139 '->parse() parses short options when they are aggregated as a single one and the last one has a required value',
142 array('cli.php', '-fb', 'bar'),
143 array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
144 array('foo' => true, 'bar' => 'bar'),
145 '->parse() parses short options when they are aggregated as a single one and the last one has an optional value',
148 array('cli.php', '-fbbar'),
149 array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
150 array('foo' => true, 'bar' => 'bar'),
151 '->parse() parses short options when they are aggregated as a single one and the last one has an optional value with no separator',
154 array('cli.php', '-fbbar'),
155 array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
156 array('foo' => 'bbar', 'bar' => null),
157 '->parse() parses short options when they are aggregated as a single one and one of them takes a value',
163 * @dataProvider provideInvalidInput
165 public function testInvalidInput($argv, $definition, $expectedExceptionMessage)
167 if (method_exists($this, 'expectException')) {
168 $this->expectException('RuntimeException');
169 $this->expectExceptionMessage($expectedExceptionMessage);
171 $this->setExpectedException('RuntimeException', $expectedExceptionMessage);
174 $input = new ArgvInput($argv);
175 $input->bind($definition);
178 public function provideInvalidInput()
182 array('cli.php', '--foo'),
183 new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
184 'The "--foo" option requires a value.',
187 array('cli.php', '-f'),
188 new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
189 'The "--foo" option requires a value.',
192 array('cli.php', '-ffoo'),
193 new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
194 'The "-o" option does not exist.',
197 array('cli.php', '--foo=bar'),
198 new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
199 'The "--foo" option does not accept a value.',
202 array('cli.php', 'foo', 'bar'),
203 new InputDefinition(),
204 'No arguments expected, got "foo".',
207 array('cli.php', 'foo', 'bar'),
208 new InputDefinition(array(new InputArgument('number'))),
209 'Too many arguments, expected arguments "number".',
212 array('cli.php', 'foo', 'bar', 'zzz'),
213 new InputDefinition(array(new InputArgument('number'), new InputArgument('county'))),
214 'Too many arguments, expected arguments "number" "county".',
217 array('cli.php', '--foo'),
218 new InputDefinition(),
219 'The "--foo" option does not exist.',
222 array('cli.php', '-f'),
223 new InputDefinition(),
224 'The "-f" option does not exist.',
227 array('cli.php', '-1'),
228 new InputDefinition(array(new InputArgument('number'))),
229 'The "-1" option does not exist.',
234 public function testParseArrayArgument()
236 $input = new ArgvInput(array('cli.php', 'foo', 'bar', 'baz', 'bat'));
237 $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::IS_ARRAY))));
239 $this->assertEquals(array('name' => array('foo', 'bar', 'baz', 'bat')), $input->getArguments(), '->parse() parses array arguments');
242 public function testParseArrayOption()
244 $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
245 $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
247 $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)');
249 $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz'));
250 $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
251 $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)');
253 $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
254 $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
255 $this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');
257 $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
258 $input->bind(new InputDefinition(array(
259 new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
260 new InputOption('anotherOption', null, InputOption::VALUE_NONE),
262 $this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
265 public function testParseNegativeNumberAfterDoubleDash()
267 $input = new ArgvInput(array('cli.php', '--', '-1'));
268 $input->bind(new InputDefinition(array(new InputArgument('number'))));
269 $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
271 $input = new ArgvInput(array('cli.php', '-f', 'bar', '--', '-1'));
272 $input->bind(new InputDefinition(array(new InputArgument('number'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
273 $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses arguments with leading dashes as options before having encountered a double-dash sequence');
274 $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
277 public function testParseEmptyStringArgument()
279 $input = new ArgvInput(array('cli.php', '-f', 'bar', ''));
280 $input->bind(new InputDefinition(array(new InputArgument('empty'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
282 $this->assertEquals(array('empty' => ''), $input->getArguments(), '->parse() parses empty string arguments');
285 public function testGetFirstArgument()
287 $input = new ArgvInput(array('cli.php', '-fbbar'));
288 $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null when there is no arguments');
290 $input = new ArgvInput(array('cli.php', '-fbbar', 'foo'));
291 $this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
294 public function testHasParameterOption()
296 $input = new ArgvInput(array('cli.php', '-f', 'foo'));
297 $this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');
299 $input = new ArgvInput(array('cli.php', '--foo', 'foo'));
300 $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input');
302 $input = new ArgvInput(array('cli.php', 'foo'));
303 $this->assertFalse($input->hasParameterOption('--foo'), '->hasParameterOption() returns false if the given short option is not in the raw input');
305 $input = new ArgvInput(array('cli.php', '--foo=bar'));
306 $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input');
309 public function testToString()
311 $input = new ArgvInput(array('cli.php', '-f', 'foo'));
312 $this->assertEquals('-f foo', (string) $input);
314 $input = new ArgvInput(array('cli.php', '-f', '--bar=foo', 'a b c d', "A\nB'C"));
315 $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
319 * @dataProvider provideGetParameterOptionValues
321 public function testGetParameterOptionEqualSign($argv, $key, $expected)
323 $input = new ArgvInput($argv);
324 $this->assertEquals($expected, $input->getParameterOption($key), '->getParameterOption() returns the expected value');
327 public function provideGetParameterOptionValues()
330 array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'),
331 array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'),
332 array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
333 array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
334 array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
335 array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), '1'),
339 public function testParseSingleDashAsArgument()
341 $input = new ArgvInput(array('cli.php', '-'));
342 $input->bind(new InputDefinition(array(new InputArgument('file'))));
343 $this->assertEquals(array('file' => '-'), $input->getArguments(), '->parse() parses single dash as an argument');
346 public function testParseOptionWithValueOptionalGivenEmptyAndRequiredArgument()
348 $input = new ArgvInput(array('cli.php', '--foo=', 'bar'));
349 $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED))));
350 $this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null');
351 $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments');
353 $input = new ArgvInput(array('cli.php', '--foo=0', 'bar'));
354 $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED))));
355 $this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null');
356 $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments');
359 public function testParseOptionWithValueOptionalGivenEmptyAndOptionalArgument()
361 $input = new ArgvInput(array('cli.php', '--foo=', 'bar'));
362 $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL))));
363 $this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null');
364 $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments');
366 $input = new ArgvInput(array('cli.php', '--foo=0', 'bar'));
367 $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL))));
368 $this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null');
369 $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments');