diff --git a/src/Util/Getopt.php b/src/Util/Getopt.php index bce701bb474..946ba0a22e8 100644 --- a/src/Util/Getopt.php +++ b/src/Util/Getopt.php @@ -36,7 +36,9 @@ public static function getopt(array $args, $short_options, $long_options = null) reset($args); array_map('trim', $args); - while (list($i, $arg) = @each($args)) { + while (false !== $arg = current($args)) { + $i = key($args); + next($args); if ($arg == '') { continue; } @@ -88,21 +90,17 @@ protected static function parseShortOption($arg, $short_options, &$opts, &$args) } if (strlen($spec) > 1 && $spec[1] == ':') { - if (strlen($spec) > 2 && $spec[2] == ':') { - if ($i + 1 < $argLen) { - $opts[] = [$opt, substr($arg, $i + 1)]; - break; - } - } else { - if ($i + 1 < $argLen) { - $opts[] = [$opt, substr($arg, $i + 1)]; - break; - } elseif (list(, $opt_arg) = @each($args)) { - } else { + if ($i + 1 < $argLen) { + $opts[] = [$opt, substr($arg, $i + 1)]; + break; + } + if (!(strlen($spec) > 2 && $spec[2] == ':')) { + if (false === $opt_arg = current($args)) { throw new Exception( "option requires an argument -- $opt" ); } + next($args); } } @@ -143,12 +141,13 @@ protected static function parseLongOption($arg, $long_options, &$opts, &$args) if (substr($long_opt, -1) == '=') { if (substr($long_opt, -2) != '==') { - if (!strlen($opt_arg) && - !(list(, $opt_arg) = @each($args)) - ) { - throw new Exception( - "option --$opt requires an argument" - ); + if (!strlen($opt_arg)) { + if (false === $opt_arg = current($args)) { + throw new Exception( + "option --$opt requires an argument" + ); + } + next($args); } } } elseif ($opt_arg) { diff --git a/tests/Util/GetoptTest.php b/tests/Util/GetoptTest.php index d66833a7229..5cfb1826269 100644 --- a/tests/Util/GetoptTest.php +++ b/tests/Util/GetoptTest.php @@ -59,4 +59,154 @@ public function testItIncludeTheShortOptionsAfterTheArgument() $this->assertEquals($expected, $actual); } + + public function testShortOptionUnrecognizedException() + { + $args = [ + 'command', + 'myArgument', + '-v', + ]; + + $this->expectException(PHPUnit\Framework\Exception::class); + $this->expectExceptionMessage('unrecognized option -- v'); + + Getopt::getopt($args, ''); + } + + public function testShortOptionRequiresAnArgumentException() + { + $args = [ + 'command', + 'myArgument', + '-f', + ]; + + $this->expectException(PHPUnit\Framework\Exception::class); + $this->expectExceptionMessage('option requires an argument -- f'); + + Getopt::getopt($args, 'f:'); + } + + public function testShortOptionHandleAnOptionalValue() + { + $args = [ + 'command', + 'myArgument', + '-f', + ]; + $actual = Getopt::getopt($args, 'f::'); + $expected = [ + [ + [ + 'f', + null, + ], + ], + [ + 'myArgument', + ], + ]; + $this->assertEquals($expected, $actual); + } + + public function testLongOptionIsAmbiguousException() + { + $args = [ + 'command', + '--col', + ]; + + $this->expectException(PHPUnit\Framework\Exception::class); + $this->expectExceptionMessage('option --col is ambiguous'); + + Getopt::getopt($args, '', ['columns', 'colors']); + } + + public function testLongOptionUnrecognizedException() + { + // the exception 'unrecognized option --option' is not thrown + // if the there are not defined extended options + $args = [ + 'command', + '--foo', + ]; + + $this->expectException(PHPUnit\Framework\Exception::class); + $this->expectExceptionMessage('unrecognized option --foo'); + + Getopt::getopt($args, '', ['colors']); + } + + public function testLongOptionRequiresAnArgumentException() + { + $args = [ + 'command', + '--foo', + ]; + + $this->expectException(PHPUnit\Framework\Exception::class); + $this->expectExceptionMessage('option --foo requires an argument'); + + Getopt::getopt($args, '', ['foo=']); + } + + public function testLongOptionDoesNotAllowAnArgumentException() + { + $args = [ + 'command', + '--foo=bar', + ]; + + $this->expectException(PHPUnit\Framework\Exception::class); + $this->expectExceptionMessage("option --foo doesn't allow an argument"); + + Getopt::getopt($args, '', ['foo']); + } + + public function testItHandlesLongParametesWithValues() + { + $command = 'command parameter-0 --exec parameter-1 --conf config.xml --optn parameter-2 --optn=content-of-o parameter-n'; + $args = explode(' ', $command); + unset($args[0]); + $expected = [ + [ + ['--exec', null], + ['--conf', 'config.xml'], + ['--optn', null], + ['--optn', 'content-of-o'], + ], + [ + 'parameter-0', + 'parameter-1', + 'parameter-2', + 'parameter-n', + ], + ]; + $actual = Getopt::getopt($args, '', ['exec', 'conf=', 'optn==']); + $this->assertEquals($expected, $actual); + } + + public function testItHandlesShortParametesWithValues() + { + $command = 'command parameter-0 -x parameter-1 -c config.xml -o parameter-2 -ocontent-of-o parameter-n'; + $args = explode(' ', $command); + unset($args[0]); + $expected = [ + [ + ['x', null], + ['c', 'config.xml'], + ['o', null], + ['o', 'content-of-o'], + ], + [ + 'parameter-0', + 'parameter-1', + 'parameter-2', + 'parameter-n', + ], + ]; + $actual = Getopt::getopt($args, 'xc:o::'); + $this->assertEquals($expected, $actual); + } }