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\Tester\Cli;
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;
34 * @author Konstantin Kudryashov <ever.zet@gmail.com>
36 final class ExerciseController implements Controller
39 * @var SuiteRepository
41 private $suiteRepository;
43 * @var SpecificationFinder
45 private $specificationFinder;
51 * @var ResultInterpreter
53 private $resultInterpreter;
60 * Initializes controller.
62 * @param SuiteRepository $suiteRepository
63 * @param SpecificationFinder $specificationFinder
64 * @param Exercise $exercise
65 * @param ResultInterpreter $resultInterpreter
66 * @param Boolean $skip
68 public function __construct(
69 SuiteRepository $suiteRepository,
70 SpecificationFinder $specificationFinder,
72 ResultInterpreter $resultInterpreter,
75 $this->suiteRepository = $suiteRepository;
76 $this->specificationFinder = $specificationFinder;
77 $this->exercise = $exercise;
78 $this->resultInterpreter = $resultInterpreter;
85 public function configure(Command $command)
87 $locatorsExamples = implode(PHP_EOL, array_map(
89 return '- ' . $locator;
90 }, $this->specificationFinder->getExampleLocators()
94 ->addArgument('paths', InputArgument::OPTIONAL,
95 'Optional path(s) to execute. Could be:' . PHP_EOL . $locatorsExamples
97 ->addOption('--dry-run', null, InputOption::VALUE_NONE,
98 'Invokes formatters without executing the tests and hooks.'
105 public function execute(InputInterface $input, OutputInterface $output)
107 $specs = $this->findSpecifications($input);
108 $result = $this->testSpecifications($input, $specs);
110 if ($input->getArgument('paths') && TestResults::NO_TESTS === $result->getResultCode()) {
111 throw new WrongPathsException(
113 'No specifications found at path(s) `%s`. This might be because of incorrect paths configuration in your `suites`.',
114 $input->getArgument('paths')
116 $input->getArgument('paths')
120 return $this->resultInterpreter->interpretResult($result);
124 * Finds exercise specifications.
126 * @param InputInterface $input
128 * @return SpecificationIterator[]
130 private function findSpecifications(InputInterface $input)
132 return $this->findSuitesSpecifications($this->getAvailableSuites(), $input->getArgument('paths'));
136 * Tests exercise specifications.
138 * @param InputInterface $input
139 * @param SpecificationIterator[] $specifications
143 private function testSpecifications(InputInterface $input, array $specifications)
145 $skip = $input->getOption('dry-run') || $this->skip;
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);
152 $result = new IntegerTestResult($testResult->getResultCode());
154 return new TestWithSetupResult($setup, $result, $teardown);
158 * Returns all currently available suites.
162 private function getAvailableSuites()
164 return $this->suiteRepository->getSuites();
168 * Finds specification iterators for all provided suites using locator.
170 * @param Suite[] $suites
171 * @param null|string $locator
173 * @return SpecificationIterator[]
175 private function findSuitesSpecifications($suites, $locator)
177 return $this->specificationFinder->findSuitesSpecifications($suites, $locator);