1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
namespace Codeception\Command;
use Codeception\Configuration;
use Codeception\Lib\Generator\Helper;
use Codeception\Util\Template;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Codeception\Lib\Generator\Actor as ActorGenerator;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Yaml;
/**
* Create new test suite. Requires suite name and actor name
*
* * ``
* * `codecept g:suite api` -> api + ApiTester
* * `codecept g:suite integration Code` -> integration + CodeTester
* * `codecept g:suite frontend Front` -> frontend + FrontTester
*
*/
class GenerateSuite extends Command
{
use Shared\FileSystem;
use Shared\Config;
use Shared\Style;
protected function configure()
{
$this->setDefinition([
new InputArgument('suite', InputArgument::REQUIRED, 'suite to be generated'),
new InputArgument('actor', InputArgument::OPTIONAL, 'name of new actor class'),
]);
}
public function getDescription()
{
return 'Generates new test suite';
}
public function execute(InputInterface $input, OutputInterface $output)
{
$this->addStyles($output);
$suite = $input->getArgument('suite');
$actor = $input->getArgument('actor');
if ($this->containsInvalidCharacters($suite)) {
$output->writeln("<error>Suite name '$suite' contains invalid characters. ([A-Za-z0-9_]).</error>");
return;
}
$config = $this->getGlobalConfig();
if (!$actor) {
$actor = ucfirst($suite) . $config['actor_suffix'];
}
$dir = Configuration::testsDir();
if (file_exists($dir . $suite . '.suite.yml')) {
throw new \Exception("Suite configuration file '$suite.suite.yml' already exists.");
}
$this->createDirectoryFor($dir . $suite);
if ($config['settings']['bootstrap']) {
// generate bootstrap file
$this->createFile(
$dir . $suite . DIRECTORY_SEPARATOR . $config['settings']['bootstrap'],
"<?php\n",
true
);
}
$helperName = ucfirst($suite);
$file = $this->createDirectoryFor(
Configuration::supportDir() . "Helper",
"$helperName.php"
) . "$helperName.php";
$gen = new Helper($helperName, $config['namespace']);
// generate helper
$this->createFile(
$file,
$gen->produce()
);
$output->writeln("Helper <info>" . $gen->getHelperName() . "</info> was created in $file");
$yamlSuiteConfigTemplate = <<<EOF
actor: {{actor}}
modules:
enabled:
- {{helper}}
EOF;
$this->createFile(
$dir . $suite . '.suite.yml',
$yamlSuiteConfig = (new Template($yamlSuiteConfigTemplate))
->place('actor', $actor)
->place('helper', $gen->getHelperName())
->produce()
);
Configuration::append(Yaml::parse($yamlSuiteConfig));
$actorGenerator = new ActorGenerator(Configuration::config());
$content = $actorGenerator->produce();
$file = $this->createDirectoryFor(
Configuration::supportDir(),
$actor
) . $this->getShortClassName($actor);
$file .= '.php';
$this->createFile($file, $content);
$output->writeln("Actor <info>" . $actor . "</info> was created in $file");
$output->writeln("Suite config <info>$suite.suite.yml</info> was created.");
$output->writeln(' ');
$output->writeln("Next steps:");
$output->writeln("1. Edit <bold>$suite.suite.yml</bold> to enable modules for this suite");
$output->writeln("2. Create first test with <bold>generate:cest testName</bold> ( or test|cept) command");
$output->writeln("3. Run tests of this suite with <bold>codecept run $suite</bold> command");
$output->writeln("<info>Suite $suite generated</info>");
}
private function containsInvalidCharacters($suite)
{
return preg_match('#[^A-Za-z0-9_]#', $suite) ? true : false;
}
}