Skip to content
This repository was archived by the owner on Jun 18, 2022. It is now read-only.

Commit bfe6d35

Browse files
Merge pull request wp-cli#78 from rantonmattei/2015-02-20--No-Arg-value-warning
Fixed the 'No arg value warning' when an option is paased with no value ...
2 parents b25244c + 86209b1 commit bfe6d35

3 files changed

Lines changed: 271 additions & 4 deletions

File tree

lib/cli/Arguments.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ public function parse() {
406406
if ($this->_strict && !empty($this->_invalid)) {
407407
throw new InvalidArguments($this->_invalid);
408408
}
409+
Lexer::$allowRewind = true;
409410
}
410411

411412
private function _warn($message) {
@@ -436,7 +437,7 @@ private function _parseOption($option) {
436437
}
437438

438439
// Peak ahead to make sure we get a value.
439-
if (!$this->_lexer->end() && !$this->_lexer->peek->isValue) {
440+
if ($this->_lexer->end() || !$this->_lexer->peek->isValue) {
440441
// Oops! Got no value, throw a warning and continue.
441442
$this->_warn('no value given for ' . $option->raw);
442443
$this[$option->key] = null;

lib/cli/arguments/Lexer.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class Lexer extends Memoize implements \Iterator {
1919
private $_index = 0;
2020
private $_length = 0;
2121

22+
public static $allowRewind = true;
23+
2224
/**
2325
* @param array $items A list of strings to process as tokens.
2426
*/
@@ -68,11 +70,10 @@ public function key() {
6870
* the cursor's position to 0.
6971
*/
7072
public function rewind() {
71-
static $first = true;
7273
$this->_shift();
73-
if ($first) {
74+
if (self::$allowRewind) {
7475
$this->_index = 0;
75-
$first = false;
76+
self::$allowRewind = false;
7677
}
7778
}
7879

tests/test-arguments.php

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
<?php
2+
3+
use cli\Arguments;
4+
5+
/**
6+
* Class TestArguments
7+
* @todo add more tests to increase coverage
8+
*
9+
* @backupGlobals enabled
10+
*/
11+
class TestArguments extends PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* Array of expected settings
15+
* @var array
16+
*/
17+
protected $settings = null;
18+
19+
/**
20+
* Array of flags
21+
* @var array
22+
*/
23+
protected $flags = null;
24+
25+
/**
26+
* Array of expected options
27+
* @var array
28+
*/
29+
protected $options = null;
30+
31+
/**
32+
* Clear the $_SERVER['argv'] array
33+
*/
34+
public static function clearArgv()
35+
{
36+
$_SERVER['argv'] = array();
37+
$_SERVER['argc'] = 0;
38+
}
39+
40+
/**
41+
* Add one or more element(s) at the end of the $_SERVER['argv'] array
42+
*
43+
* @param array $args: value(s) to add to the argv array
44+
*/
45+
public static function pushToArgv($args)
46+
{
47+
if (is_string($args)) {
48+
$args = explode(' ', $args);
49+
}
50+
51+
foreach ($args as $arg) {
52+
array_push($_SERVER['argv'], $arg);
53+
}
54+
55+
$_SERVER['argc'] += count($args);
56+
}
57+
58+
/**
59+
* Set up valid flags and options
60+
*/
61+
public function setUp()
62+
{
63+
self::clearArgv();
64+
self::pushToArgv('my_script.php');
65+
66+
$this->flags = array(
67+
'flag1' => array(
68+
'aliases' => 'f',
69+
'description' => 'Test flag 1'
70+
),
71+
'flag2' => array(
72+
'description' => 'Test flag 2'
73+
)
74+
);
75+
76+
$this->options = array(
77+
'option1' => array(
78+
'aliases' => 'o',
79+
'description' => 'Test option 1'
80+
),
81+
'option2' => array(
82+
'aliases' => array('x', 'y'),
83+
'description' => 'Test option 2 with default',
84+
'default' => 'some default value'
85+
)
86+
);
87+
88+
$this->settings = array(
89+
'strict' => true,
90+
'flags' => $this->flags,
91+
'options' => $this->options
92+
);
93+
}
94+
95+
/**
96+
* Tear down fixtures
97+
*/
98+
public function tearDown()
99+
{
100+
$this->flags = null;
101+
$this->options = null;
102+
$this->settings = null;
103+
self::clearArgv();
104+
}
105+
106+
/**
107+
* Test adding a flag, getting a flag and getting all flags
108+
*/
109+
public function testAddFlags()
110+
{
111+
$args = new cli\Arguments($this->settings);
112+
113+
$expectedFlags = $this->flags;
114+
$expectedFlags['flag1']['default'] = false;
115+
$expectedFlags['flag1']['stackable'] = false;
116+
$expectedFlags['flag2']['default'] = false;
117+
$expectedFlags['flag2']['stackable'] = false;
118+
$expectedFlags['flag2']['aliases'] = array();
119+
120+
$this->assertSame($expectedFlags, $args->getFlags());
121+
122+
$this->assertSame($expectedFlags['flag1'], $args->getFlag('flag1'));
123+
$this->assertSame($expectedFlags['flag1'], $args->getFlag('f'));
124+
125+
$expectedFlag1Argument = new cli\arguments\Argument('-f');
126+
$this->assertSame($expectedFlags['flag1'], $args->getFlag($expectedFlag1Argument));
127+
}
128+
129+
/**
130+
* Test adding a option, getting a option and getting all options
131+
*/
132+
public function testAddOptions()
133+
{
134+
$args = new cli\Arguments($this->settings);
135+
136+
$expectedOptions = $this->options;
137+
$expectedOptions['option1']['default'] = null;
138+
139+
$this->assertSame($expectedOptions, $args->getOptions());
140+
141+
$this->assertSame($expectedOptions['option1'], $args->getOption('option1'));
142+
$this->assertSame($expectedOptions['option1'], $args->getOption('o'));
143+
144+
$expectedOption1Argument = new cli\arguments\Argument('-o');
145+
$this->assertSame($expectedOptions['option1'], $args->getOption($expectedOption1Argument));
146+
}
147+
148+
/**
149+
* Data provider with valid fags and options
150+
*
151+
* @return array set of args and expected parsed values
152+
*/
153+
public function settingsWithValidOptions()
154+
{
155+
return array(
156+
array(
157+
array('-o', 'option_value', '-f'),
158+
array('option1' => 'option_value', 'flag1' => true)
159+
),
160+
array(
161+
array('--option1', 'option_value', '--flag1'),
162+
array('option1' => 'option_value', 'flag1' => true)
163+
),
164+
array(
165+
array('-f', '--option1', 'option_value'),
166+
array('flag1' => true, 'option1' => 'option_value')
167+
)
168+
);
169+
}
170+
171+
/**
172+
* Data provider with missing options
173+
*
174+
* @return array set of args and expected parsed values
175+
*/
176+
public function settingsWithMissingOptions()
177+
{
178+
return array(
179+
array(
180+
array('-f', '--option1'),
181+
array('flag1' => true, 'option1' => 'Error should be triggered')
182+
),
183+
array(
184+
array('--option1', '-f'),
185+
array('option1' => 'Error should be triggered', 'flag1' => true)
186+
)
187+
);
188+
}
189+
190+
/**
191+
* Data provider with missing options. The default value should be populated
192+
*
193+
* @return array set of args and expected parsed values
194+
*/
195+
public function settingsWithMissingOptionsWithDefault()
196+
{
197+
return array(
198+
array(
199+
array('-f', '--option2'),
200+
array('flag1' => true, 'option2' => 'some default value')
201+
),
202+
array(
203+
array('--option2', '-f'),
204+
array('option2' => 'some default value', 'flag1' => true)
205+
)
206+
);
207+
}
208+
209+
/**
210+
* Generic private testParse method.
211+
*
212+
* @param array $args arguments as they appear in the cli
213+
* @param array $expectedValues expected values after parsing
214+
*/
215+
private function _testParse($cliParams, $expectedValues)
216+
{
217+
self::pushToArgv($cliParams);
218+
219+
$args = new cli\Arguments($this->settings);
220+
$args->parse();
221+
222+
foreach ($expectedValues as $name => $value) {
223+
if ($args->isFlag($name)) {
224+
$this->assertTrue($args[$name]);
225+
}
226+
227+
if ($args->isOption($name)) {
228+
$this->assertEquals($value, $args[$name]);
229+
}
230+
}
231+
}
232+
233+
/**
234+
* @param array $args arguments as they appear in the cli
235+
* @param array $expectedValues expected values after parsing
236+
*
237+
* @dataProvider settingsWithValidOptions
238+
*/
239+
public function testParseWithValidOptions($cliParams, $expectedValues)
240+
{
241+
$this->_testParse($cliParams, $expectedValues);
242+
}
243+
244+
/**
245+
* @param array $args arguments as they appear in the cli
246+
* @param array $expectedValues expected values after parsing
247+
* @dataProvider settingsWithMissingOptions
248+
* @expectedException PHPUnit_Framework_Error_Warning
249+
* @expectedExceptionMessage no value given for --option1
250+
*/
251+
public function testParseWithMissingOptions($cliParams, $expectedValues)
252+
{
253+
$this->_testParse($cliParams, $expectedValues);
254+
}
255+
256+
/**
257+
* @todo implement once the "default" value issue has been fixed
258+
* @dataProvider settingsWithMissingOptionsWithDefault
259+
*/
260+
public function testParseWithMissingOptionsWithDefault($cliParams, $expectedValues)
261+
{
262+
$this->markTestSkipped('Will fail cause default value is not populated. Issue #30 is still open.');
263+
$this->_testParse($cliParams, $expectedValues);
264+
}
265+
}

0 commit comments

Comments
 (0)