Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Testwork / Tester / Cli / ExerciseController.php
1 <?php
2
3 /*
4  * This file is part of the Behat Testwork.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Testwork\Tester\Cli;
12
13 use Behat\Testwork\Cli\Controller;
14 use Behat\Testwork\Specification\SpecificationFinder;
15 use Behat\Testwork\Specification\SpecificationIterator;
16 use Behat\Testwork\Suite\Suite;
17 use Behat\Testwork\Suite\SuiteRepository;
18 use Behat\Testwork\Tester\Exception\WrongPathsException;
19 use Behat\Testwork\Tester\Exercise;
20 use Behat\Testwork\Tester\Result\IntegerTestResult;
21 use Behat\Testwork\Tester\Result\ResultInterpreter;
22 use Behat\Testwork\Tester\Result\TestResult;
23 use Behat\Testwork\Tester\Result\TestResults;
24 use Behat\Testwork\Tester\Result\TestWithSetupResult;
25 use Symfony\Component\Console\Command\Command;
26 use Symfony\Component\Console\Input\InputArgument;
27 use Symfony\Component\Console\Input\InputInterface;
28 use Symfony\Component\Console\Input\InputOption;
29 use Symfony\Component\Console\Output\OutputInterface;
30
31 /**
32  * Executes exercise.
33  *
34  * @author Konstantin Kudryashov <ever.zet@gmail.com>
35  */
36 final class ExerciseController implements Controller
37 {
38     /**
39      * @var SuiteRepository
40      */
41     private $suiteRepository;
42     /**
43      * @var SpecificationFinder
44      */
45     private $specificationFinder;
46     /**
47      * @var Exercise
48      */
49     private $exercise;
50     /**
51      * @var ResultInterpreter
52      */
53     private $resultInterpreter;
54     /**
55      * @var Boolean
56      */
57     private $skip;
58
59     /**
60      * Initializes controller.
61      *
62      * @param SuiteRepository     $suiteRepository
63      * @param SpecificationFinder $specificationFinder
64      * @param Exercise            $exercise
65      * @param ResultInterpreter   $resultInterpreter
66      * @param Boolean             $skip
67      */
68     public function __construct(
69         SuiteRepository $suiteRepository,
70         SpecificationFinder $specificationFinder,
71         Exercise $exercise,
72         ResultInterpreter $resultInterpreter,
73         $skip = false
74     ) {
75         $this->suiteRepository = $suiteRepository;
76         $this->specificationFinder = $specificationFinder;
77         $this->exercise = $exercise;
78         $this->resultInterpreter = $resultInterpreter;
79         $this->skip = $skip;
80     }
81
82     /**
83      * {@inheritdoc}
84      */
85     public function configure(Command $command)
86     {
87         $locatorsExamples = implode(PHP_EOL, array_map(
88             function ($locator) {
89                 return '- ' . $locator;
90             }, $this->specificationFinder->getExampleLocators()
91         ));
92
93         $command
94             ->addArgument('paths', InputArgument::OPTIONAL,
95                 'Optional path(s) to execute. Could be:' . PHP_EOL . $locatorsExamples
96             )
97             ->addOption('--dry-run', null, InputOption::VALUE_NONE,
98                 'Invokes formatters without executing the tests and hooks.'
99             );
100     }
101
102     /**
103      * {@inheritdoc}
104      */
105     public function execute(InputInterface $input, OutputInterface $output)
106     {
107         $specs = $this->findSpecifications($input);
108         $result = $this->testSpecifications($input, $specs);
109
110         if ($input->getArgument('paths') && TestResults::NO_TESTS === $result->getResultCode()) {
111             throw new WrongPathsException(
112                 sprintf(
113                     'No specifications found at path(s) `%s`. This might be because of incorrect paths configuration in your `suites`.',
114                     $input->getArgument('paths')
115                 ),
116                 $input->getArgument('paths')
117             );
118         }
119
120         return $this->resultInterpreter->interpretResult($result);
121     }
122
123     /**
124      * Finds exercise specifications.
125      *
126      * @param InputInterface $input
127      *
128      * @return SpecificationIterator[]
129      */
130     private function findSpecifications(InputInterface $input)
131     {
132         return $this->findSuitesSpecifications($this->getAvailableSuites(), $input->getArgument('paths'));
133     }
134
135     /**
136      * Tests exercise specifications.
137      *
138      * @param InputInterface          $input
139      * @param SpecificationIterator[] $specifications
140      *
141      * @return TestResult
142      */
143     private function testSpecifications(InputInterface $input, array $specifications)
144     {
145         $skip = $input->getOption('dry-run') || $this->skip;
146
147         $setup = $this->exercise->setUp($specifications, $skip);
148         $skip = !$setup->isSuccessful() || $skip;
149         $testResult = $this->exercise->test($specifications, $skip);
150         $teardown = $this->exercise->tearDown($specifications, $skip, $testResult);
151
152         $result = new IntegerTestResult($testResult->getResultCode());
153
154         return new TestWithSetupResult($setup, $result, $teardown);
155     }
156
157     /**
158      * Returns all currently available suites.
159      *
160      * @return Suite[]
161      */
162     private function getAvailableSuites()
163     {
164         return $this->suiteRepository->getSuites();
165     }
166
167     /**
168      * Finds specification iterators for all provided suites using locator.
169      *
170      * @param Suite[]     $suites
171      * @param null|string $locator
172      *
173      * @return SpecificationIterator[]
174      */
175     private function findSuitesSpecifications($suites, $locator)
176     {
177         return $this->specificationFinder->findSuitesSpecifications($suites, $locator);
178     }
179 }