/**
  * Starts script execution.
  *
  * @return void
  *
  * @throws \Exception   On errors
  */
 public function run()
 {
     $this->setAsTerminator();
     $eventHandlerRegistry = Application::getInstance()->getDiContainer()->getEventHandlerRegistry();
     $eventHandlerRegistry->raise(new Event(Event::TYPE_APPLICATION_BEFORE_RUN));
     $this->prepareSwitches();
     try {
         $this->parseSwitches($this->cliHelper->getParsedArgs());
     } catch (\Exception $exception) {
         $this->cliHelper->setErrorMessage($exception->getMessage());
         // Set the exit code to invocation error if it's currently set to success.
         if ($this->getExitCode() == self::EXIT_CODE_SUCCESS) {
             $this->setExitCode(self::EXIT_CODE_INVOCATION_ERROR);
         }
         echo $this->cliHelper->getUsageOutput(false);
         // Re-throw the exception
         throw $exception;
     }
     $this->runBefore();
     try {
         if ($this->currentUsage == self::HELP_USAGE) {
             echo $this->cliHelper->getUsageOutput(true);
         } else {
             $eventHandlerRegistry->raise(new Event(Event::TYPE_CONTROLLER_BEFORE_ACTION));
             $this->execute();
             $eventHandlerRegistry->raise(new Event(Event::TYPE_CONTROLLER_AFTER_ACTION));
         }
     } catch (\Exception $exception) {
         $this->removeSignalHandler();
         if (self::EXIT_CODE_SUCCESS == $this->getExitCode()) {
             $this->setExitCode(self::EXIT_CODE_UNHANDLED_EXCEPTION);
         }
         Application::getInstance()->getDiContainer()->getErrorHandlerRegistry()->handleException($exception);
     }
     $this->removeSignalHandler();
     $this->runAfter();
     $eventHandlerRegistry->raise(new Event(Event::TYPE_APPLICATION_AFTER_RUN));
 }
 public function testErrors()
 {
     $helper = new CliUserInterfaceHelper('test script', 'test.php');
     try {
         $helper->getUsageOutput();
         $this->fail('No Exception is thrown when getting usage without any defined usages');
     } catch (Exception $e) {
     }
     $testUsage = $helper->addUsage('test');
     $helper->addSwitch('a', 'test', 'Test', null);
     try {
         $helper->addSwitch(null, null, 'Test', null);
         $this->fail('No Exception is thrown when adding a switch with neither short nor long name');
     } catch (Exception $e) {
     }
     try {
         $helper->addSwitch('a', null, 'Test', null);
         $this->fail('No exception is thrown when adding a duplicate short switch');
     } catch (Exception $e) {
     }
     try {
         $helper->addSwitch(null, 'test', 'Test', null);
         $this->fail('No exception is thrown when adding a duplicate long switch');
     } catch (Exception $e) {
     }
     try {
         $helper->addSwitch('b', null, 'test', $testUsage + 1);
         $this->fail('No exception is thrown when adding a switch to an invalid usage');
     } catch (Exception $e) {
     }
     try {
         $helper->addSwitch('c', null, 'test', array($testUsage, $testUsage + 1));
         $this->fail('No exception is thrown when adding a switch to an invalid usage with an array');
     } catch (Exception $e) {
     }
 }