function setup()
 {
     $this->application = new ApplicationWithTerminalWidth('TestApplication', '0.0.0');
     $this->commandFactory = new AnnotatedCommandFactory();
     // $factory->addListener(...);
     $alterOptionsEventManager = new AlterOptionsCommandEvent($this->application);
     $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
     $eventDispatcher->addSubscriber($this->commandFactory->commandProcessor()->hookManager());
     $eventDispatcher->addSubscriber($alterOptionsEventManager);
     $this->application->setDispatcher($eventDispatcher);
     $this->application->setAutoExit(false);
     $discovery = new CommandFileDiscovery();
     $discovery->setSearchPattern('*CommandFile.php')->setIncludeFilesAtBase(false)->setSearchLocations(['alpha']);
     chdir(__DIR__);
     $commandFiles = $discovery->discover('.', '\\Consolidation\\TestUtils');
     $formatter = new FormatterManager();
     $formatter->addDefaultFormatters();
     $formatter->addDefaultSimplifiers();
     $terminalWidthOption = new PrepareTerminalWidthOption();
     $terminalWidthOption->setApplication($this->application);
     $this->commandFactory->commandProcessor()->setFormatterManager($formatter);
     $this->commandFactory->commandProcessor()->addPrepareFormatter($terminalWidthOption);
     $this->commandFactory->setIncludeAllPublicMethods(false);
     $this->addDiscoveredCommands($this->commandFactory, $commandFiles);
     $helpCommandfile = new HelpCommand($this->application);
     $commandList = $this->commandFactory->createCommandsFromClass($helpCommandfile);
     foreach ($commandList as $command) {
         $this->application->add($command);
     }
 }
    function testCommandsAndHooks()
    {
        // First, search for commandfiles in the 'alpha'
        // directory. Note that this same functionality
        // is tested more thoroughly in isolation in
        // testCommandFileDiscovery.php
        $discovery = new CommandFileDiscovery();
        $discovery->setSearchPattern('*CommandFile.php')->setIncludeFilesAtBase(false)->setSearchLocations(['alpha']);
        chdir(__DIR__);
        $commandFiles = $discovery->discover('.', '\\Consolidation\\TestUtils');
        $formatter = new FormatterManager();
        $formatter->addDefaultFormatters();
        $formatter->addDefaultSimplifiers();
        $hookManager = new HookManager();
        $terminalWidthOption = new PrepareTerminalWidthOption();
        $terminalWidthOption->setApplication($this->application);
        $commandProcessor = new CommandProcessor($hookManager);
        $commandProcessor->setFormatterManager($formatter);
        $commandProcessor->addPrepareFormatter($terminalWidthOption);
        // Create a new factory, and load all of the files
        // discovered above.
        $factory = new AnnotatedCommandFactory();
        $factory->setCommandProcessor($commandProcessor);
        // Add a listener to configure our command handler object
        $factory->addListernerCallback(function ($command) use($hookManager) {
            if ($command instanceof CustomEventAwareInterface) {
                $command->setHookManager($hookManager);
            }
        });
        $factory->setIncludeAllPublicMethods(false);
        $this->addDiscoveredCommands($factory, $commandFiles);
        $this->assertRunCommandViaApplicationContains('list', ['example:table'], ['additional:option', 'without:annotations']);
        $this->assertTrue($this->application->has('example:table'));
        $this->assertFalse($this->application->has('without:annotations'));
        // Run the use:event command that defines a custom event, my-event.
        $this->assertRunCommandViaApplicationEquals('use:event', 'one,two');
        // Watch as we dynamically add a custom event to the hook manager to change the command results:
        $hookManager->add(function () {
            return 'three';
        }, HookManager::ON_EVENT, 'my-event');
        $this->assertRunCommandViaApplicationEquals('use:event', 'one,three,two');
        // Fetch a reference to the 'example:table' command and test its valid format types
        $exampleTableCommand = $this->application->find('example:table');
        $returnType = $exampleTableCommand->getReturnType();
        $this->assertEquals('\\Consolidation\\OutputFormatters\\StructuredData\\RowsOfFields', $returnType);
        $validFormats = $formatter->validFormats($returnType);
        $this->assertEquals('csv,json,list,php,print-r,sections,string,table,tsv,var_export,xml,yaml', implode(',', $validFormats));
        // Control: run commands without hooks.
        $this->assertRunCommandViaApplicationEquals('always:fail', 'This command always fails.', 13);
        $this->assertRunCommandViaApplicationEquals('simulated:status', '42');
        $this->assertRunCommandViaApplicationEquals('example:output', 'Hello, World.');
        $this->assertRunCommandViaApplicationEquals('example:cat bet alpha --flip', 'alphabet');
        $this->assertRunCommandViaApplicationEquals('example:echo a b c', "a\tb\tc");
        $this->assertRunCommandViaApplicationEquals('example:message', 'Shipwrecked; send bananas.');
        $this->assertRunCommandViaApplicationEquals('command:with-one-optional-argument', 'Hello, world');
        $this->assertRunCommandViaApplicationEquals('command:with-one-optional-argument Joe', 'Hello, Joe');
        // Add some hooks.
        $factory->hookManager()->addValidator(new ExampleValidator());
        $factory->hookManager()->addResultProcessor(new ExampleResultProcessor());
        $factory->hookManager()->addAlterResult(new ExampleResultAlterer());
        $factory->hookManager()->addStatusDeterminer(new ExampleStatusDeterminer());
        $factory->hookManager()->addOutputExtractor(new ExampleOutputExtractor());
        // Run the same commands as before, and confirm that results
        // are different now that the hooks are in place.
        $this->assertRunCommandViaApplicationEquals('simulated:status', '', 42);
        $this->assertRunCommandViaApplicationEquals('example:output', 'Hello, World!');
        $this->assertRunCommandViaApplicationEquals('example:cat bet alpha --flip', 'alphareplaced');
        $this->assertRunCommandViaApplicationEquals('example:echo a b c', 'a,b,c');
        $this->assertRunCommandViaApplicationEquals('example:message', 'Shipwrecked; send bananas.');
        $expected = <<<EOT
 ------ ------ -------
  I      II     III
 ------ ------ -------
  One    Two    Three
  Eins   Zwei   Drei
  Ichi   Ni     San
  Uno    Dos    Tres
 ------ ------ -------
EOT;
        $this->assertRunCommandViaApplicationEquals('example:table', $expected);
        $expected = <<<EOT
 ------- ------
  III     II
 ------- ------
  Three   Two
  Drei    Zwei
  San     Ni
  Tres    Dos
 ------- ------
EOT;
        $this->assertRunCommandViaApplicationEquals('example:table --fields=III,II', $expected);
        $expectedSingleField = <<<EOT
Two
Zwei
Ni
Dos
EOT;
        // When --field is specified (instead of --fields), then the format
        // is forced to 'string'.
        $this->assertRunCommandViaApplicationEquals('example:table --field=II', $expectedSingleField);
        // Check the help for the example table command and see if the options
        // from the alter hook were added.  We expect that we should not see
        // any of the information from the alter hook in the 'beta' folder yet.
        $this->assertRunCommandViaApplicationContains('help example:table', ['Option added by @hook option example:table', 'example:table --french', 'Add a row with French numbers.'], ['chinese', 'kanji']);
        $expectedOutputWithFrench = <<<EOT
 ------ ------ -------
  I      II     III
 ------ ------ -------
  One    Two    Three
  Eins   Zwei   Drei
  Ichi   Ni     San
  Uno    Dos    Tres
  Un     Deux   Trois
 ------ ------ -------
EOT;
        $this->assertRunCommandViaApplicationEquals('example:table --french', $expectedOutputWithFrench);
        $expectedAssociativeListTable = <<<EOT
 --------------- ----------------------------------------------------------------------------------------
  SFTP Command    sftp -o Port=2222 dev@appserver.dev.drush.in
  Git Command     git clone ssh://codeserver.dev@codeserver.dev.drush.in:2222/~/repository.git wp-update
  MySQL Command   mysql -u pantheon -p4b33cb -h dbserver.dev.drush.in -P 16191 pantheon
 --------------- ----------------------------------------------------------------------------------------
EOT;
        $this->assertRunCommandViaApplicationEquals('example:list', $expectedAssociativeListTable);
        $this->assertRunCommandViaApplicationEquals('example:list --field=sftp_command', 'sftp -o Port=2222 dev@appserver.dev.drush.in');
        $this->assertRunCommandViaApplicationEquals('get:serious', 'very serious');
        $this->assertRunCommandViaApplicationContains('get:lost', 'Command "get:lost" is not defined.', [], 1);
        $this->assertRunCommandViaApplicationContains('help example:wrap', ['Test word wrapping', '[default: "table"]']);
        $expectedUnwrappedOutput = <<<EOT
-------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------
  First                                                                                                                      Second
 -------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------
  This is a really long cell that contains a lot of data. When it is rendered, it should be wrapped across multiple lines.   This is the second column of the same table. It is also very long, and should be wrapped across multiple lines, just like the first column.
 -------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------
EOT;
        $this->application->setWidthAndHeight(0, 0);
        $this->assertRunCommandViaApplicationEquals('example:wrap', $expectedUnwrappedOutput);
        $expectedWrappedOutput = <<<EOT
 ------------------- --------------------
  First               Second
 ------------------- --------------------
  This is a really    This is the second
  long cell that      column of the same
  contains a lot of   table. It is also
  data. When it is    very long, and
  rendered, it        should be wrapped
  should be wrapped   across multiple
  across multiple     lines, just like
  lines.              the first column.
 ------------------- --------------------
EOT;
        $this->application->setWidthAndHeight(42, 24);
        $this->assertRunCommandViaApplicationEquals('example:wrap', $expectedWrappedOutput);
    }