1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Console\Tests\Helper;
13
14use PHPUnit\Framework\TestCase;
15use Symfony\Component\Console\Helper\DebugFormatterHelper;
16use Symfony\Component\Console\Helper\HelperSet;
17use Symfony\Component\Console\Helper\ProcessHelper;
18use Symfony\Component\Console\Output\StreamOutput;
19use Symfony\Component\Process\Process;
20
21class ProcessHelperTest extends TestCase
22{
23    /**
24     * @dataProvider provideCommandsAndOutput
25     */
26    public function testVariousProcessRuns($expected, $cmd, $verbosity, $error)
27    {
28        $helper = new ProcessHelper();
29        $helper->setHelperSet(new HelperSet([new DebugFormatterHelper()]));
30        $output = $this->getOutputStream($verbosity);
31        $helper->run($output, $cmd, $error);
32        $this->assertEquals($expected, $this->getOutput($output));
33    }
34
35    public function testPassedCallbackIsExecuted()
36    {
37        $helper = new ProcessHelper();
38        $helper->setHelperSet(new HelperSet([new DebugFormatterHelper()]));
39        $output = $this->getOutputStream(StreamOutput::VERBOSITY_NORMAL);
40
41        $executed = false;
42        $callback = function () use (&$executed) { $executed = true; };
43
44        $helper->run($output, 'php -r "echo 42;"', null, $callback);
45        $this->assertTrue($executed);
46    }
47
48    public function provideCommandsAndOutput()
49    {
50        $successOutputVerbose = <<<'EOT'
51  RUN  php -r "echo 42;"
52  RES  Command ran successfully
53
54EOT;
55        $successOutputDebug = <<<'EOT'
56  RUN  php -r "echo 42;"
57  OUT  42
58  RES  Command ran successfully
59
60EOT;
61        $successOutputDebugWithTags = <<<'EOT'
62  RUN  php -r "echo '<info>42</info>';"
63  OUT  <info>42</info>
64  RES  Command ran successfully
65
66EOT;
67        $successOutputProcessDebug = <<<'EOT'
68  RUN  'php' '-r' 'echo 42;'
69  OUT  42
70  RES  Command ran successfully
71
72EOT;
73        $syntaxErrorOutputVerbose = <<<'EOT'
74  RUN  php -r "fwrite(STDERR, 'error message');usleep(50000);fwrite(STDOUT, 'out message');exit(252);"
75  RES  252 Command did not run successfully
76
77EOT;
78        $syntaxErrorOutputDebug = <<<'EOT'
79  RUN  php -r "fwrite(STDERR, 'error message');usleep(500000);fwrite(STDOUT, 'out message');exit(252);"
80  ERR  error message
81  OUT  out message
82  RES  252 Command did not run successfully
83
84EOT;
85
86        $errorMessage = 'An error occurred';
87        $args = new Process(['php', '-r', 'echo 42;']);
88        $args = $args->getCommandLine();
89        $successOutputProcessDebug = str_replace("'php' '-r' 'echo 42;'", $args, $successOutputProcessDebug);
90
91        return [
92            ['', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null],
93            [$successOutputVerbose, 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERY_VERBOSE, null],
94            [$successOutputDebug, 'php -r "echo 42;"', StreamOutput::VERBOSITY_DEBUG, null],
95            [$successOutputDebugWithTags, 'php -r "echo \'<info>42</info>\';"', StreamOutput::VERBOSITY_DEBUG, null],
96            ['', 'php -r "syntax error"', StreamOutput::VERBOSITY_VERBOSE, null],
97            [$syntaxErrorOutputVerbose, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, null],
98            [$syntaxErrorOutputDebug, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, null],
99            [$errorMessage.\PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERBOSE, $errorMessage],
100            [$syntaxErrorOutputVerbose.$errorMessage.\PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, $errorMessage],
101            [$syntaxErrorOutputDebug.$errorMessage.\PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage],
102            [$successOutputProcessDebug, ['php', '-r', 'echo 42;'], StreamOutput::VERBOSITY_DEBUG, null],
103            [$successOutputDebug, new Process('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null],
104        ];
105    }
106
107    private function getOutputStream($verbosity)
108    {
109        return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, false);
110    }
111
112    private function getOutput(StreamOutput $output)
113    {
114        rewind($output->getStream());
115
116        return stream_get_contents($output->getStream());
117    }
118}
119