Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify command classes #6750

Open
wants to merge 2 commits into
base: 5.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions composer.json
Expand Up @@ -28,12 +28,12 @@
"phpunit/php-timer": "^5.0.3 || ^6.0 || ^7.0",
"sebastian/comparator": "^4.0.5 || ^5.0 || ^6.0",
"sebastian/diff": "^4.0.3 || ^5.0 || ^6.0",
"symfony/console": ">=4.4.24 <8.0",
"symfony/css-selector": ">=4.4.24 <8.0",
"symfony/event-dispatcher": ">=4.4.24 <8.0",
"symfony/finder": ">=4.4.24 <8.0",
"symfony/yaml": ">=4.4.24 <8.0",
"symfony/var-dumper": ">=4.4.24 <8.0",
"symfony/console": ">=5.4.24 <8.0",
"symfony/css-selector": ">=5.4.24 <8.0",
"symfony/event-dispatcher": ">=5.4.24 <8.0",
"symfony/finder": ">=5.4.24 <8.0",
"symfony/yaml": ">=5.4.24 <8.0",
"symfony/var-dumper": ">=5.4.24 <8.0",
"psy/psysh": "^0.11.2 || ^0.12"
},
"require-dev": {
Expand All @@ -46,8 +46,8 @@
"codeception/module-filesystem": "*@dev",
"codeception/module-phpbrowser": "*@dev",
"codeception/util-universalframework": "*@dev",
"symfony/process": ">=4.4.24 <8.0",
"symfony/dotenv": ">=4.4.24 <8.0",
"symfony/process": ">=5.4.24 <8.0",
"symfony/dotenv": ">=5.4.24 <8.0",
"vlucas/phpdotenv": "^5.1",
"jetbrains/phpstorm-attributes": "^1.0"
},
Expand Down
34 changes: 11 additions & 23 deletions src/Codeception/Command/Bootstrap.php
Expand Up @@ -15,7 +15,7 @@
* Creates default config, tests directory and sample suites for current project.
* Use this command to start building a test suite.
*
* By default it will create 3 suites **Acceptance**, **Functional**, and **Unit**.
* By default, it will create 3 suites **Acceptance**, **Functional**, and **Unit**.
*
* * `codecept bootstrap` - creates `tests` dir and `codeception.yml` in current dir.
* * `codecept bootstrap --empty` - creates `tests` dir without suites
Expand All @@ -28,33 +28,21 @@ class Bootstrap extends Command
{
protected function configure(): void
{
$this->setDefinition(
[
new InputArgument('path', InputArgument::OPTIONAL, 'custom installation dir', null),
new InputOption(
'namespace',
's',
InputOption::VALUE_OPTIONAL,
'Namespace to add for actor classes and helpers'
),
new InputOption('actor', 'a', InputOption::VALUE_OPTIONAL, 'Custom actor instead of Tester'),
new InputOption('empty', 'e', InputOption::VALUE_NONE, "Don't create standard suites")
]
);
$this->setDescription('Creates default test suites and generates all required files')
->addArgument('path', InputArgument::OPTIONAL, 'custom installation dir')
->addOption('namespace', 's', InputOption::VALUE_OPTIONAL, 'Namespace to add for actor classes and helpers')
->addOption('actor', 'a', InputOption::VALUE_OPTIONAL, 'Custom actor instead of Tester')
->addOption('empty', 'e', InputOption::VALUE_NONE, "Don't create standard suites");
}

public function getDescription(): string
{
return "Creates default test suites and generates all required files";
}

public function execute(InputInterface $input, OutputInterface $output): int
protected function execute(InputInterface $input, OutputInterface $output): int
{
$bootstrap = new BootstrapTemplate($input, $output);
if ($input->getArgument('path')) {
$bootstrap->initDir($input->getArgument('path'));
if ($path = $input->getArgument('path')) {
$bootstrap->initDir($path);
}

$bootstrap->setup();
return 0;
return Command::SUCCESS;
}
}
6 changes: 3 additions & 3 deletions src/Codeception/Command/Build.php
Expand Up @@ -39,7 +39,7 @@ protected function execute(InputInterface $input, SymfonyOutputInterface $output
{
$this->output = $output;
$this->buildActorsForConfig();
return 0;
return Command::SUCCESS;
}

private function buildActor(array $settings): bool
Expand All @@ -65,7 +65,7 @@ private function buildActions(array $settings): bool
$actionsGenerator = new ActionsGenerator($settings);
$content = $actionsGenerator->produce();
$this->output->writeln(
" -> {$settings['actor']}Actions.php generated successfully. "
sprintf(' -> %sActions.php generated successfully. ', $settings['actor'])
. $actionsGenerator->getNumMethods() . " methods added"
);

Expand All @@ -89,7 +89,7 @@ private function buildSuiteActors(): void
$actorBuilt = $this->buildActor($settings);

if ($actorBuilt) {
$this->output->writeln("{$settings['actor']}.php created.");
$this->output->writeln($settings['actor'] . '.php created.');
}
}
}
Expand Down
14 changes: 6 additions & 8 deletions src/Codeception/Command/Clean.php
Expand Up @@ -20,30 +20,28 @@ class Clean extends Command
{
use Shared\ConfigTrait;

public function getDescription(): string
protected function configure(): void
{
return 'Recursively cleans log and generated code';
$this->setDescription('Recursively cleans log and generated code');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$projectDir = Configuration::projectDir();
$this->cleanProjectsRecursively($output, $projectDir);
$this->cleanProjectsRecursively($output, Configuration::projectDir());
$output->writeln("Done");
return 0;
return Command::SUCCESS;
}

private function cleanProjectsRecursively(OutputInterface $output, string $projectDir): void
{
$config = Configuration::config($projectDir);
$logDir = Configuration::outputDir();
$output->writeln("<info>Cleaning up output " . $logDir . "...</info>");
$output->writeln(sprintf('<info>Cleaning up output %s...</info>', $logDir));
FileSystem::doEmptyDir($logDir);

$subProjects = $config['include'];
foreach ($subProjects as $subProject) {
$subProjectDir = $projectDir . $subProject;
$this->cleanProjectsRecursively($output, $subProjectDir);
$this->cleanProjectsRecursively($output, $projectDir . $subProject);
}
}
}
3 changes: 2 additions & 1 deletion src/Codeception/Command/Completion.php
Expand Up @@ -10,6 +10,7 @@
use Stecman\Component\Symfony\Console\BashCompletion\Completion\ShellPathCompletion;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionCommand;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionHandler;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputDefinition as SymfonyInputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand Down Expand Up @@ -72,7 +73,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

parent::execute($input, $output);
return 0;
return Command::SUCCESS;
}

protected function createDefinition(): SymfonyInputDefinition
Expand Down
2 changes: 1 addition & 1 deletion src/Codeception/Command/CompletionFallback.php
Expand Up @@ -31,6 +31,6 @@ protected function configure(): void
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln("Install optional <comment>stecman/symfony-console-completion</comment>");
return 0;
return Command::SUCCESS;
}
}
28 changes: 10 additions & 18 deletions src/Codeception/Command/ConfigValidate.php
Expand Up @@ -46,22 +46,13 @@ class ConfigValidate extends Command

protected function configure(): void
{
$this->setDefinition(
[
new InputArgument('suite', InputArgument::OPTIONAL, 'to show suite configuration'),
new InputOption('config', 'c', InputOption::VALUE_OPTIONAL, 'Use custom path for config'),
new InputOption('override', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Override config values'),
]
);
parent::configure();
$this->setDescription('Validates and prints config to screen')
->addArgument('suite', InputArgument::OPTIONAL, 'To show suite configuration')
->addOption('config', 'c', InputOption::VALUE_OPTIONAL, 'Use custom path for config')
->addOption('override', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Override config values');
}

public function getDescription(): string
{
return 'Validates and prints config to screen';
}

public function execute(InputInterface $input, OutputInterface $output): int
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->addStyles($output);

Expand All @@ -72,8 +63,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
$output->writeln("------------------------------\n");
$output->writeln("<info>{$suite} Suite Config</info>:\n");
$output->writeln($this->formatOutput($config));

return 0;
return Command::SUCCESS;
}

$output->write("Validating global config... ");
Expand All @@ -82,8 +72,9 @@ public function execute(InputInterface $input, OutputInterface $output): int
if (!empty($input->getOption('override'))) {
$config = $this->overrideConfig($input->getOption('override'));
}
$suites = Configuration::suites();

$output->writeln("Ok");
$suites = Configuration::suites();

$output->writeln("------------------------------\n");
$output->writeln("<info>Codeception Config</info>:\n");
Expand All @@ -104,7 +95,8 @@ public function execute(InputInterface $input, OutputInterface $output): int
}

$output->writeln("Execute <info>codecept config:validate [<suite>]</info> to see config for a suite");
return 0;

return Command::SUCCESS;
}

protected function formatOutput($config): ?string
Expand Down
19 changes: 6 additions & 13 deletions src/Codeception/Command/Console.php
Expand Up @@ -49,20 +49,12 @@ class Console extends Command

protected function configure(): void
{
$this->setDefinition([
new InputArgument('suite', InputArgument::REQUIRED, 'suite to be executed'),
new InputOption('colors', '', InputOption::VALUE_NONE, 'Use colors in output'),
]);

parent::configure();
}

public function getDescription(): string
{
return 'Launches interactive test console';
$this->setDescription('Launches interactive test console')
->addArgument('suite', InputArgument::REQUIRED, 'suite to be executed')
->addOption('colors', '', InputOption::VALUE_NONE, 'Use colors in output');
}

public function execute(InputInterface $input, OutputInterface $output): int
protected function execute(InputInterface $input, OutputInterface $output): int
{
$suiteName = $input->getArgument('suite');
$this->output = $output;
Expand Down Expand Up @@ -103,6 +95,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
if (isset($config['namespace']) && $config['namespace'] !== '') {
$settings['actor'] = $config['namespace'] . '\\Support\\' . $settings['actor'];
}

$actor = $settings['actor'];
$I = new $actor($scenario);

Expand All @@ -126,7 +119,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
$eventDispatcher->dispatch(new SuiteEvent($this->suite), Events::SUITE_AFTER);

$output->writeln("<info>Bye-bye!</info>");
return 0;
return Command::SUCCESS;
}

protected function listenToSignals(): void
Expand Down
9 changes: 5 additions & 4 deletions src/Codeception/Command/DryRun.php
Expand Up @@ -18,6 +18,7 @@
use Codeception\Test\Test;
use Exception;
use InvalidArgumentException;
use ReflectionClass;
use ReflectionIntersectionType;
use ReflectionMethod;
use ReflectionNamedType;
Expand Down Expand Up @@ -62,7 +63,7 @@ public function getDescription(): string
return 'Prints step-by-step scenario-driven test or a feature';
}

public function execute(InputInterface $input, OutputInterface $output): int
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->addStyles($output);
$suite = $input->getArgument('suite');
Expand Down Expand Up @@ -106,7 +107,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
return 0;
}

protected function matchTestFromFilename($filename, $testsPath)
protected function matchTestFromFilename($filename, $testsPath): array
{
$filename = str_replace(['//', '\/', '\\'], '/', $filename);
$res = preg_match("#^{$testsPath}/(.*?)/(.*)$#", $filename, $matches);
Expand Down Expand Up @@ -143,7 +144,7 @@ protected function dryRunTest(OutputInterface $output, EventDispatcher $eventDis
private function mockModule(string $moduleName, ModuleContainer $moduleContainer): void
{
$module = $moduleContainer->getModule($moduleName);
$class = new \ReflectionClass($module);
$class = new ReflectionClass($module);
$methodResults = [];
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if ($method->isConstructor()) {
Expand All @@ -155,7 +156,7 @@ private function mockModule(string $moduleName, ModuleContainer $moduleContainer
$moduleContainer->mock($moduleName, Stub::makeEmpty($module, $methodResults));
}

private function getDefaultResultForMethod(\ReflectionClass $class, ReflectionMethod $method): mixed
private function getDefaultResultForMethod(ReflectionClass $class, ReflectionMethod $method): mixed
{
$returnType = $method->getReturnType();

Expand Down
20 changes: 7 additions & 13 deletions src/Codeception/Command/GenerateCest.php
Expand Up @@ -28,18 +28,12 @@ class GenerateCest extends Command

protected function configure(): void
{
$this->setDefinition([
new InputArgument('suite', InputArgument::REQUIRED, 'suite where tests will be put'),
new InputArgument('class', InputArgument::REQUIRED, 'test name'),
]);
$this->setDescription('Generates empty Cest file in suite')
->addArgument('suite', InputArgument::REQUIRED, 'suite where tests will be put')
->addArgument('class', InputArgument::REQUIRED, 'test name');
}

public function getDescription(): string
{
return 'Generates empty Cest file in suite';
}

public function execute(InputInterface $input, OutputInterface $output): int
protected function execute(InputInterface $input, OutputInterface $output): int
{
$suite = $input->getArgument('suite');
$class = $input->getArgument('class');
Expand All @@ -53,16 +47,16 @@ public function execute(InputInterface $input, OutputInterface $output): int

if (file_exists($filename)) {
$output->writeln("<error>Test {$filename} already exists</error>");
return 1;
return Command::FAILURE;
}
$cest = new CestGenerator($class, $config);
$res = $this->createFile($filename, $cest->produce());
if (!$res) {
$output->writeln("<error>Test {$filename} already exists</error>");
return 1;
return Command::FAILURE;
}

$output->writeln("<info>Test was created in {$filename}</info>");
return 0;
return Command::SUCCESS;
}
}