4 * This file is part of the Behat Testwork.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
11 namespace Behat\Testwork\Output\Cli;
13 use Behat\Testwork\Cli\Controller;
14 use Behat\Testwork\Output\Formatter;
15 use Behat\Testwork\Output\OutputManager;
16 use Symfony\Component\Console\Command\Command;
17 use Symfony\Component\Console\Input\InputInterface;
18 use Symfony\Component\Console\Input\InputOption;
19 use Symfony\Component\Console\Output\OutputInterface;
22 * Configures formatters based on user input.
24 * @author Konstantin Kudryashov <ever.zet@gmail.com>
26 class OutputController implements Controller
34 * Initializes controller.
36 * @param OutputManager $manager
38 public function __construct(OutputManager $manager)
40 $this->manager = $manager;
46 public function configure(Command $command)
50 '--format', '-f', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
51 'How to format tests output. <comment>pretty</comment> is default.' . PHP_EOL .
52 'Available formats are:' . PHP_EOL . $this->getFormatterDescriptions() .
53 'You can use multiple formats at the same time.'
56 '--out', '-o', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
57 'Write format output to a file/directory instead of' . PHP_EOL .
58 'STDOUT <comment>(output_path)</comment>. You can also provide different' . PHP_EOL .
59 'outputs to multiple formats.'
62 '--format-settings', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
63 'Set formatters parameters using json object.' . PHP_EOL .
64 'Keys are parameter names, values are values.'
71 public function execute(InputInterface $input, OutputInterface $output)
73 $formats = $input->getOption('format');
74 $outputs = $input->getOption('out');
76 $this->configureFormatters($formats, $input, $output);
77 $this->configureOutputs($formats, $outputs, $output->isDecorated());
81 * Configures formatters based on container, input and output configurations.
83 * @param array $formats
84 * @param InputInterface $input
85 * @param OutputInterface $output
87 protected function configureFormatters(array $formats, InputInterface $input, OutputInterface $output)
89 $this->enableFormatters($formats);
90 $this->setFormattersParameters($input, $output);
96 * @param array $formats
98 protected function enableFormatters(array $formats)
100 if (count($formats)) {
101 $this->manager->disableAllFormatters();
102 foreach ($formats as $format) {
103 $this->manager->enableFormatter($format);
109 * Sets formatters parameters based on input & output.
111 * @param InputInterface $input
112 * @param OutputInterface $output
114 protected function setFormattersParameters(InputInterface $input, OutputInterface $output)
116 $this->manager->setFormattersParameter('output_decorate', $output->isDecorated());
118 if ($input->getOption('format-settings')) {
119 foreach ($input->getOption('format-settings') as $jsonSettings) {
120 $this->loadJsonSettings($jsonSettings);
126 * Locates output path from relative one.
128 * @param string $path
132 protected function locateOutputPath($path)
134 if ($this->isAbsolutePath($path)) {
138 $path = getcwd() . DIRECTORY_SEPARATOR . $path;
140 if (!file_exists($path)) {
142 $path = realpath($path);
145 $path = realpath($path);
152 * Initializes multiple formatters with different outputs.
154 * @param array $formats
155 * @param array $outputs
156 * @param Boolean $decorated
158 private function configureOutputs(array $formats, array $outputs, $decorated = false)
160 if (1 == count($outputs) && !$this->isStandardOutput($outputs[0])) {
161 $outputPath = $this->locateOutputPath($outputs[0]);
163 $this->manager->setFormattersParameter('output_path', $outputPath);
164 $this->manager->setFormattersParameter('output_decorate', $decorated);
169 foreach ($outputs as $i => $out) {
170 if ($this->isStandardOutput($out)) {
174 $outputPath = $this->locateOutputPath($out);
175 if (isset($formats[$i])) {
176 $this->manager->setFormatterParameter($formats[$i], 'output_path', $outputPath);
177 $this->manager->setFormatterParameter($formats[$i], 'output_decorate', $decorated);
183 * Checks if provided output identifier represents standard output.
185 * @param string $outputId
189 private function isStandardOutput($outputId)
191 return 'std' === $outputId || 'null' === $outputId || 'false' === $outputId;
195 * Returns whether the file path is an absolute path.
197 * @param string $file A file path
201 private function isAbsolutePath($file)
203 if ($file[0] == '/' || $file[0] == '\\'
204 || (strlen($file) > 3 && ctype_alpha($file[0])
206 && ($file[2] == '\\' || $file[2] == '/')
208 || null !== parse_url($file, PHP_URL_SCHEME)
217 * Returns formatters description.
221 private function getFormatterDescriptions()
226 function (Formatter $formatter) {
227 $comment = '- <comment>' . $formatter->getName() . '</comment>: ';
228 $comment .= $formatter->getDescription();
231 }, $this->manager->getFormatters()
237 * Loads JSON settings as formatter parameters.
239 * @param string $jsonSettings
241 private function loadJsonSettings($jsonSettings)
243 $settings = @json_decode($jsonSettings, true);
245 if (!is_array($settings)) {
249 foreach ($settings as $name => $value) {
250 $this->manager->setFormattersParameter($name, $value);