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); }