/**
  * Tests the parsing functions.
  *
  * @return void
  */
 public function testParsing()
 {
     $parser = new CliArgumentParser();
     $parser->addSwitch('a', 'switch-a');
     $parser->addSwitch('b', null);
     $parser->addSwitch(null, 'switch-c');
     $parser->addSwitch('v', 'value', true);
     $parser->addSwitch('o', 'optional', true, true);
     // Test parsing for no arguments
     $parser->parse(array());
     $this->assertSame(array(), $parser->getParsedSwitches(), 'Invalid switches parsed for empty arg list');
     $this->assertSame(array(), $parser->getParsedOperands(), 'Invalid operands parsed for empty arg list');
     // Test parsing for simple switches ('-a -b --switch-c')
     $expectedSwitches = array('a' => 1, 'switch-a' => 1, 'b' => 1, 'switch-c' => 1);
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('-a', '-b', '--switch-c'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for value switches without a separator ('-vvalue1 -ovalue2')
     $expectedSwitches = array('v' => 'value1', 'value' => 'value1', 'o' => 'value2', 'optional' => 'value2');
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('-vvalue1', '-ovalue2'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for value switches with = as separator for short versions ('-v=value1 -o=value2')
     $expectedSwitches = array('v' => 'value1', 'value' => 'value1', 'o' => 'value2', 'optional' => 'value2');
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('-v=value1', '-o=value2'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for value switches with space separator for short versions ('-v value1')
     $expectedSwitches = array('v' => 'value1', 'value' => 'value1');
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('-v', 'value1'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for value switches with = as separator for short versions ('--value=value1 --optional=value2')
     $expectedSwitches = array('v' => 'value1', 'value' => 'value1', 'o' => 'value2', 'optional' => 'value2');
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('--value=value1', '--optional=value2'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for value switches with space separator for short versions ('--value value1')
     $expectedSwitches = array('v' => 'value1', 'value' => 'value1');
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('--value', 'value1'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for collapsed syntax, with one value switch ('-abvvalue1')
     $expectedSwitches = array('a' => 1, 'switch-a' => 1, 'b' => 1, 'v' => 'value1', 'value' => 'value1');
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('-abvvalue1'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for collapsed syntax for non-value switches with multiple invocations ('-aaba')
     $expectedSwitches = array('a' => 3, 'switch-a' => 3, 'b' => 1);
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('-aaba'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for operands ('-b test1, test2')
     $expectedSwitches = array('b' => 1);
     ksort($expectedSwitches);
     $expectedOperands = array('test1', 'test2');
     $parser->parse(array('-b', 'test1', 'test2'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for finish operator ('-a -- -b')
     $expectedSwitches = array('a' => 1, 'switch-a' => 1);
     ksort($expectedSwitches);
     $expectedOperands = array('-b');
     $parser->parse(array('-a', '--', '-b'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing for optional value and operand ('-o test')
     $expectedSwitches = array('o' => false, 'optional' => false);
     ksort($expectedSwitches);
     $expectedOperands = array('test');
     $parser->parse(array('-o', 'test'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
     // Test parsing when the same value switch is added multiple times ('-vvalue1 -vvalue2')
     $expectedSwitches = array('v' => 'value2', 'value' => 'value2');
     ksort($expectedSwitches);
     $expectedOperands = array();
     $parser->parse(array('-vvalue1', '-vvalue2'));
     $switches = $parser->getParsedSwitches();
     ksort($switches);
     $this->assertSame($expectedSwitches, $switches, 'Invalid switches were parsed');
     $this->assertSame($expectedOperands, $parser->getParsedOperands(), 'Invalid operands were parsed');
 }
 /**
  * Adds a new switch to the script.
  *
  * @param string    $shortName         Short name of the switch.
  * @param string    $longName          Long name of the switch.
  * @param string    $description       Description of the switch.
  * @param int|array $usageIndexes      An array containing the usage indexes for the switch, or optionally an int
  *                                     if the switch is only valid for one usage method. If set to NULL, it will be
  *                                     added to all usages.{@see self::addUsage()}
  * @param bool      $isOptional        If TRUE, the switch is not required.
  * @param null      $paramName         Name of the switch parameter to display.
  * @param bool      $paramIsOptional   If TRUE, the switch parameter is treated as optional.
  *
  * @return void
  *
  * @throws \YapepBase\Exception\Exception
  */
 public function addSwitch($shortName, $longName, $description, $usageIndexes, $isOptional = false, $paramName = null, $paramIsOptional = false)
 {
     $description = preg_replace('/\\s{2,}/', ' ', str_replace(array("\n", "\r"), ' ', trim($description)));
     $switchData = array('shortName' => $shortName, 'longName' => $longName, 'description' => $description, 'isOptional' => $isOptional, 'paramName' => $paramName, 'paramIsOptional' => $paramIsOptional);
     if (empty($shortName) && empty($longName)) {
         throw new Exception('Neither short, nor long name given for the switch');
     }
     if (!empty($shortName)) {
         if (in_array($shortName, $this->shortSwitches)) {
             throw new Exception('Short switch already added: ' . $shortName);
         } else {
             $this->shortSwitches[] = $shortName;
         }
     }
     if (!empty($longName)) {
         if (in_array($longName, $this->longSwitches)) {
             throw new Exception('Long switch already added: ' . $longName);
         } else {
             $this->longSwitches[] = $longName;
         }
     }
     if (mb_strlen($longName, 'UTF-8') > $this->longestSwitchNameLength) {
         $this->longestSwitchNameLength = mb_strlen($longName, 'UTF-8');
     }
     $this->switches[] = $switchData;
     if (is_null($usageIndexes)) {
         $this->usageSwitches[self::ALL_USAGE_KEY][] = $switchData;
     } elseif (is_array($usageIndexes)) {
         foreach ($usageIndexes as $index) {
             if (!isset($this->usageSwitches[$index])) {
                 throw new Exception('The specified usage index is not set: ' . $index);
             }
             $this->usageSwitches[$index][] = $switchData;
         }
     } elseif (is_numeric($usageIndexes) && isset($this->usageSwitches[$usageIndexes])) {
         $this->usageSwitches[$usageIndexes][] = $switchData;
     } else {
         throw new Exception('The specified usage index is not set: ' . $usageIndexes);
     }
     $this->argumentParser->addSwitch($shortName, $longName, !empty($paramName), $paramIsOptional);
 }