MDL-78570 behat: Remove the skip-passed legacy option

This option (--skip-passed) was implemented because of some bugs in the initial
versions of Behat 3 with the --rerun option.

After Behat 3.2.0 those bugs were fixed and we switched back to use
the upstream --rerun option, abandoning --skip-passed.

More yet, this option wasn't ever documented much, neither in docs or cli.

So it's time to remove it, one less thing to maintain for nothing.

Note that this commit is a 99.99% revert of the original one that was
applied to the moodle-behat-extension (now in core):

https://github.com/moodlehq/moodle-behat-extension/commit/c4b25158d212509b
This commit is contained in:
Eloy Lafuente (stronk7) 2023-06-24 19:28:51 +02:00
parent 3cd84747cb
commit dc0869fc12
No known key found for this signature in database
GPG Key ID: 53487A05E6228820
3 changed files with 0 additions and 350 deletions

View File

@ -1,106 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace Moodle\BehatExtension\Locator;
use Behat\Behat\Gherkin\Specification\LazyFeatureIterator;
use Behat\Gherkin\Gherkin;
use Behat\Testwork\Specification\Locator\SpecificationLocator;
use Behat\Testwork\Specification\NoSpecificationsIterator;
use Behat\Testwork\Suite\Suite;
// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
/**
* Skips gherkin features using a file with the list of scenarios.
*
* @package core
* @copyright 2016 onwards Rajesh Taneja
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class FilesystemSkipPassedListLocator implements SpecificationLocator {
/**
* @var Gherkin
*/
private $gherkin;
/**
* Initializes locator.
*
* @param Gherkin $gherkin
*/
public function __construct(Gherkin $gherkin) {
$this->gherkin = $gherkin;
}
/**
* Returns array of strings representing examples of supported specification locators.
*
* @return string[]
*/
public function getLocatorExamples() {
return [];
}
/**
* Locates specifications and wraps them into iterator.
*
* @param Suite $suite
* @param string $locator
*
* @return SpecificationIterator
*/
public function locateSpecifications(Suite $suite, $locator) {
if (!$locator || !is_file($locator) || 'passed' !== pathinfo($locator, PATHINFO_EXTENSION)) {
return new NoSpecificationsIterator($suite);
}
$scenarios = json_decode(trim(file_get_contents($locator)), true);
if (empty($scenarios) || empty($scenarios[$suite->getName()])) {
return new NoSpecificationsIterator($suite);
}
$suitepaths = $this->getSuitePaths($suite);
$scenarios = array_diff($suitepaths, array_values($scenarios[$suite->getName()]));
return new LazyFeatureIterator($suite, $this->gherkin, $scenarios);
}
/**
* Returns array of feature paths configured for the provided suite.
*
* @param Suite $suite
*
* @return string[]
*
* @throws SuiteConfigurationException If `paths` setting is not an array
*/
private function getSuitePaths(Suite $suite) {
if (!is_array($suite->getSetting('paths'))) {
throw new SuiteConfigurationException(
sprintf(
'"paths" setting of the "%s" suite is expected to be an array, %s given.',
$suite->getName(),
gettype($suite->getSetting('paths'))
),
$suite->getName()
);
}
return $suite->getSetting('paths');
}
}

View File

@ -25,7 +25,6 @@ use Behat\Testwork\Output\ServiceContainer\OutputExtension;
use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
use Behat\Testwork\ServiceContainer\ExtensionManager;
use Behat\Testwork\ServiceContainer\ServiceProcessor;
use Behat\Testwork\Specification\ServiceContainer\SpecificationExtension;
use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
use Moodle\BehatExtension\Driver\WebDriverFactory;
use Moodle\BehatExtension\Output\Formatter\MoodleProgressFormatterFactory;
@ -51,9 +50,6 @@ class BehatExtension implements ExtensionInterface {
/** @var string Extension configuration ID */
const MOODLE_ID = 'moodle';
/** @var string Gherkin ID */
const GHERKIN_ID = 'gherkin';
/** @var ServiceProcessor */
private $processor;
@ -100,10 +96,6 @@ class BehatExtension implements ExtensionInterface {
// Load namespace alias.
$this->alias_old_namespaces();
// Load skip passed controller and list locator.
$this->loadSkipPassedController($container, $config['passed_cache']);
$this->loadFilesystemSkipPassedScenariosListLocator($container);
}
/**
@ -166,38 +158,6 @@ class BehatExtension implements ExtensionInterface {
]);
}
/**
* Loads skip passed controller.
*
* @param ContainerBuilder $container
* @param null|string $cachepath
*/
protected function loadSkipPassedController(ContainerBuilder $container, $cachepath) {
$definition = new Definition('Moodle\BehatExtension\Tester\Cli\SkipPassedController', [
new Reference(EventDispatcherExtension::DISPATCHER_ID),
$cachepath,
$container->getParameter('paths.base')
]);
$definition->addTag(CliExtension::CONTROLLER_TAG, ['priority' => 200]);
$container->setDefinition(CliExtension::CONTROLLER_TAG . '.passed', $definition);
}
/**
* Loads filesystem passed scenarios list locator.
*
* @param ContainerBuilder $container
*/
private function loadFilesystemSkipPassedScenariosListLocator(ContainerBuilder $container) {
$definition = new Definition('Moodle\BehatExtension\Locator\FilesystemSkipPassedListLocator', [
new Reference(self::GHERKIN_ID)
]);
$definition->addTag(SpecificationExtension::LOCATOR_TAG, ['priority' => 50]);
$container->setDefinition(
SpecificationExtension::LOCATOR_TAG . '.filesystem_skip_passed_scenarios_list',
$definition
);
}
/**
* Loads definition printers.
*
@ -277,14 +237,6 @@ class BehatExtension implements ExtensionInterface {
->scalarNode('moodledirroot')
->defaultNull()
->end()
->scalarNode('passed_cache')
->info('Sets the passed cache path')
->defaultValue(
is_writable(sys_get_temp_dir())
? sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat_passed_cache'
: null
)
->end()
->end()
->end();
// phpcs:enable PEAR.WhiteSpace.ObjectOperatorIndent.Incorrect

View File

@ -1,196 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace Moodle\BehatExtension\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;
// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
/**
* Caches passed scenarios and skip only them if `--skip-passed` option provided.
*
* @package core
* @copyright 2016 onwards Rajesh Taneja
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class SkipPassedController implements Controller {
/**
* @var EventDispatcherInterface
*/
private $eventdispatcher;
/**
* @var null|string
*/
private $cachepath;
/**
* @var string
*/
private $key;
/**
* @var string[]
*/
private $lines = [];
/**
* @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('--skip-passed', null, InputOption::VALUE_NONE,
'Skip scenarios that passed during last execution.'
);
}
/**
* Executes controller.
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @return null|integer
*/
public function execute(InputInterface $input, OutputInterface $output) {
if (!$input->getOption('skip-passed')) {
// If no skip option is passed then remove any old file which we are saving.
if (!$this->getFileName()) {
return;
}
if (file_exists($this->getFileName())) {
unlink($this->getFileName());
}
return;
}
$this->eventdispatcher->addListener(ScenarioTested::AFTER, [$this, 'collectPassedScenario'], -50);
$this->eventdispatcher->addListener(ExampleTested::AFTER, [$this, 'collectPassedScenario'], -50);
$this->eventdispatcher->addListener(ExerciseCompleted::AFTER, [$this, 'writeCache'], -50);
$this->key = $this->generateKey($input);
if (!$this->getFileName() || !file_exists($this->getFileName())) {
return;
}
$input->setArgument('paths', $this->getFileName());
$existing = json_decode(file_get_contents($this->getFileName()), true);
if (!empty($existing)) {
$this->lines = array_merge_recursive($existing, $this->lines);
}
}
/**
* Records scenario if it is passed.
*
* @param AfterScenarioTested $event
*/
public function collectPassedScenario(AfterScenarioTested $event) {
if (!$this->getFileName()) {
return;
}
$feature = $event->getFeature();
$suitename = $event->getSuite()->getName();
if (
($event->getTestResult()->getResultCode() !== TestResult::PASSED) &&
($event->getTestResult()->getResultCode() !== TestResult::SKIPPED)
) {
unset($this->lines[$suitename][$feature->getFile()]);
return;
}
$this->lines[$suitename][$feature->getFile()] = $feature->getFile();
}
/**
* Writes passed scenarios cache.
*/
public function writeCache() {
if (!$this->getFileName()) {
return;
}
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(['--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 . '.passed';
}
}