+++ /dev/null
-<?php
-
-/*
- * This file is part of the Behat.
- * (c) Konstantin Kudryashov <ever.zet@gmail.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Behat\Behat\Tester\Cli;
-
-use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
-use Behat\Behat\EventDispatcher\Event\ExampleTested;
-use Behat\Behat\EventDispatcher\Event\ScenarioTested;
-use Behat\Testwork\Cli\Controller;
-use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
-use Behat\Testwork\Tester\Result\TestResult;
-use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Input\InputOption;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-
-/**
- * Caches failed scenarios and reruns only them if `--rerun` option provided.
- *
- * @author Konstantin Kudryashov <ever.zet@gmail.com>
- */
-final class RerunController implements Controller
-{
- /**
- * @var EventDispatcherInterface
- */
- private $eventDispatcher;
- /**
- * @var null|string
- */
- private $cachePath;
- /**
- * @var string
- */
- private $key;
- /**
- * @var string[]
- */
- private $lines = array();
- /**
- * @var string
- */
- private $basepath;
-
- /**
- * Initializes controller.
- *
- * @param EventDispatcherInterface $eventDispatcher
- * @param null|string $cachePath
- * @param string $basepath
- */
- public function __construct(EventDispatcherInterface $eventDispatcher, $cachePath, $basepath)
- {
- $this->eventDispatcher = $eventDispatcher;
- $this->cachePath = null !== $cachePath ? rtrim($cachePath, DIRECTORY_SEPARATOR) : null;
- $this->basepath = $basepath;
- }
-
- /**
- * Configures command to be executable by the controller.
- *
- * @param Command $command
- */
- public function configure(Command $command)
- {
- $command->addOption('--rerun', null, InputOption::VALUE_NONE,
- 'Re-run scenarios that failed during last execution.'
- );
- }
-
- /**
- * Executes controller.
- *
- * @param InputInterface $input
- * @param OutputInterface $output
- *
- * @return null|integer
- */
- public function execute(InputInterface $input, OutputInterface $output)
- {
- $this->eventDispatcher->addListener(ScenarioTested::AFTER, array($this, 'collectFailedScenario'), -50);
- $this->eventDispatcher->addListener(ExampleTested::AFTER, array($this, 'collectFailedScenario'), -50);
- $this->eventDispatcher->addListener(ExerciseCompleted::AFTER, array($this, 'writeCache'), -50);
-
- $this->key = $this->generateKey($input);
-
- if (!$input->getOption('rerun')) {
- return;
- }
-
- if (!$this->getFileName() || !file_exists($this->getFileName())) {
- return;
- }
-
- $input->setArgument('paths', $this->getFileName());
- }
-
- /**
- * Records scenario if it is failed.
- *
- * @param AfterScenarioTested $event
- */
- public function collectFailedScenario(AfterScenarioTested $event)
- {
- if (!$this->getFileName()) {
- return;
- }
-
- if ($event->getTestResult()->getResultCode() !== TestResult::FAILED) {
- return;
- }
-
- $feature = $event->getFeature();
- $scenario = $event->getScenario();
- $suitename = $event->getSuite()->getName();
-
- $this->lines[$suitename][] = $feature->getFile() . ':' . $scenario->getLine();
- }
-
- /**
- * Writes failed scenarios cache.
- */
- public function writeCache()
- {
- if (!$this->getFileName()) {
- return;
- }
-
- if (file_exists($this->getFileName())) {
- unlink($this->getFileName());
- }
-
- if (0 === count($this->lines)) {
- return;
- }
-
- file_put_contents($this->getFileName(), json_encode($this->lines));
- }
-
- /**
- * Generates cache key.
- *
- * @param InputInterface $input
- *
- * @return string
- */
- private function generateKey(InputInterface $input)
- {
- return md5(
- $input->getParameterOption(array('--profile', '-p')) .
- $input->getOption('suite') .
- implode(' ', $input->getOption('name')) .
- implode(' ', $input->getOption('tags')) .
- $input->getOption('role') .
- $input->getArgument('paths') .
- $this->basepath
- );
- }
-
- /**
- * Returns cache filename (if exists).
- *
- * @return null|string
- */
- private function getFileName()
- {
- if (null === $this->cachePath || null === $this->key) {
- return null;
- }
-
- if (!is_dir($this->cachePath)) {
- mkdir($this->cachePath, 0777);
- }
-
- return $this->cachePath . DIRECTORY_SEPARATOR . $this->key . '.rerun';
- }
-}