From 6965274de5f19e77108d5e474301fa1ab3855603 Mon Sep 17 00:00:00 2001 From: Maciej Holyszko <14310995+falkenhawk@users.noreply.github.com> Date: Wed, 8 May 2019 12:11:35 +0200 Subject: [PATCH] Backported https://github.com/sebastianbergmann/phpunit/pull/2536 - refactored Getopt + tests - each() is deprecated since php 7.2 --- PHPUnit/Util/Getopt.php | 70 ++++++------- Tests/Util/GetoptTest.php | 204 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 34 deletions(-) create mode 100644 Tests/Util/GetoptTest.php diff --git a/PHPUnit/Util/Getopt.php b/PHPUnit/Util/Getopt.php index 41ec26c02d3..45fb7d80410 100644 --- a/PHPUnit/Util/Getopt.php +++ b/PHPUnit/Util/Getopt.php @@ -77,7 +77,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,20 +90,23 @@ public static function getopt(array $args, $short_options, $long_options = NULL) } if ($arg[0] != '-' || - (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) { - $non_opts = array_merge($non_opts, array_slice($args, $i)); - break; - } - - elseif (strlen($arg) > 1 && $arg[1] == '-') { + (strlen($arg) > 1 && $arg[1] == '-' && !$long_options) + ) { + $non_opts[] = $args[$i]; + continue; + } elseif (strlen($arg) > 1 && $arg[1] == '-') { self::parseLongOption( - substr($arg, 2), $long_options, $opts, $args + substr($arg, 2), + $long_options, + $opts, + $args ); - } - - else { + } else { self::parseShortOption( - substr($arg, 1), $short_options, $opts, $args + substr($arg, 1), + $short_options, + $opts, + $args ); } } @@ -118,32 +123,25 @@ protected static function parseShortOption($arg, $short_options, &$opts, &$args) $opt_arg = NULL; if (($spec = strstr($short_options, $opt)) === FALSE || - $arg[$i] == ':') { + $arg[$i] == ':' + ) { throw new PHPUnit_Framework_Exception( "unrecognized option -- $opt" ); } if (strlen($spec) > 1 && $spec[1] == ':') { - if (strlen($spec) > 2 && $spec[2] == ':') { - if ($i + 1 < $argLen) { - $opts[] = array($opt, substr($arg, $i + 1)); - break; - } - } else { - if ($i + 1 < $argLen) { - $opts[] = array($opt, substr($arg, $i + 1)); - break; - } - - else if (list(, $opt_arg) = each($args)) { - } - - else { + if ($i + 1 < $argLen) { + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } + if (!(strlen($spec) > 2 && $spec[2] == ':')) { + if (false === $opt_arg = current($args)) { throw new PHPUnit_Framework_Exception( "option requires an argument -- $opt" ); } + next($args); } } @@ -183,11 +181,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 PHPUnit_Framework_Exception( - "option --$opt requires an argument" - ); + if (!strlen($opt_arg)) { + if (false === $opt_arg = current($args)) { + throw new PHPUnit_Framework_Exception( + "option --$opt requires an argument" + ); + } + next($args); } } } @@ -198,7 +198,9 @@ protected static function parseLongOption($arg, $long_options, &$opts, &$args) ); } - $opts[] = array('--' . $opt, $opt_arg); + $full_option = '--' . preg_replace('/={1,2}$/', '', $long_opt); + $opts[] = array($full_option, $opt_arg); + return; } diff --git a/Tests/Util/GetoptTest.php b/Tests/Util/GetoptTest.php new file mode 100644 index 00000000000..6eee83406ce --- /dev/null +++ b/Tests/Util/GetoptTest.php @@ -0,0 +1,204 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +class Util_GetoptTest extends PHPUnit_Framework_TestCase +{ + public function testItIncludeTheLongOptionsAfterTheArgument() + { + $args = array( + 'command', + 'myArgument', + '--colors', + ); + $actual = PHPUnit_Util_Getopt::getopt($args, '', array('colors==')); + + $expected = array( + array( + array( + '--colors', + null, + ), + ), + array( + 'myArgument', + ), + ); + + $this->assertEquals($expected, $actual); + } + + public function testItIncludeTheShortOptionsAfterTheArgument() + { + $args = array( + 'command', + 'myArgument', + '-v', + ); + $actual = PHPUnit_Util_Getopt::getopt($args, 'v'); + + $expected = array( + array( + array( + 'v', + null, + ), + ), + array( + 'myArgument', + ), + ); + + $this->assertEquals($expected, $actual); + } + + public function testShortOptionUnrecognizedException() + { + $args = array( + 'command', + 'myArgument', + '-v', + ); + + $this->setExpectedException('PHPUnit_Framework_Exception', 'unrecognized option -- v'); + + PHPUnit_Util_Getopt::getopt($args, ''); + } + + public function testShortOptionRequiresAnArgumentException() + { + $args = array( + 'command', + 'myArgument', + '-f', + ); + + $this->setExpectedException('PHPUnit_Framework_Exception', 'option requires an argument -- f'); + + PHPUnit_Util_Getopt::getopt($args, 'f:'); + } + + public function testShortOptionHandleAnOptionalValue() + { + $args = array( + 'command', + 'myArgument', + '-f', + ); + $actual = PHPUnit_Util_Getopt::getopt($args, 'f::'); + $expected = array( + array( + array( + 'f', + null, + ), + ), + array( + 'myArgument', + ), + ); + $this->assertEquals($expected, $actual); + } + + public function testLongOptionIsAmbiguousException() + { + $args = array( + 'command', + '--col', + ); + + $this->setExpectedException('PHPUnit_Framework_Exception', 'option --col is ambiguous'); + + PHPUnit_Util_Getopt::getopt($args, '', array('columns', 'colors')); + } + + public function testLongOptionUnrecognizedException() + { + // the exception 'unrecognized option --option' is not thrown + // if the there are not defined extended options + $args = array( + 'command', + '--foo', + ); + + $this->setExpectedException('PHPUnit_Framework_Exception', 'unrecognized option --foo'); + + PHPUnit_Util_Getopt::getopt($args, '', array('colors')); + } + + public function testLongOptionRequiresAnArgumentException() + { + $args = array( + 'command', + '--foo', + ); + + $this->setExpectedException('PHPUnit_Framework_Exception', 'option --foo requires an argument'); + + PHPUnit_Util_Getopt::getopt($args, '', array('foo=')); + } + + public function testLongOptionDoesNotAllowAnArgumentException() + { + $args = array( + 'command', + '--foo=bar', + ); + + $this->setExpectedException('PHPUnit_Framework_Exception', "option --foo doesn't allow an argument"); + + PHPUnit_Util_Getopt::getopt($args, '', array('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 = array( + array( + array('--exec', null), + array('--conf', 'config.xml'), + array('--optn', null), + array('--optn', 'content-of-o'), + ), + array( + 'parameter-0', + 'parameter-1', + 'parameter-2', + 'parameter-n', + ), + ); + $actual = PHPUnit_Util_Getopt::getopt($args, '', array('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 = array( + array( + array('x', null), + array('c', 'config.xml'), + array('o', null), + array('o', 'content-of-o'), + ), + array( + 'parameter-0', + 'parameter-1', + 'parameter-2', + 'parameter-n', + ), + ); + $actual = PHPUnit_Util_Getopt::getopt($args, 'xc:o::'); + $this->assertEquals($expected, $actual); + } +}