SetupGenerator::generateSuite()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
4
namespace SmartWeb\ModuleTesting\Codeception\SmartWeb;
5
6
use InvalidArgumentException;
7
use SmartWeb\ModuleTesting\Codeception\GlobalConfiguration;
8
use SmartWeb\ModuleTesting\Codeception\GlobalConfigurationInterface;
9
use SmartWeb\ModuleTesting\Codeception\SetupGeneratorInterface;
10
use SmartWeb\ModuleTesting\Codeception\SetupInterface;
11
use SmartWeb\ModuleTesting\Codeception\SuiteInfoInterface;
12
use SmartWeb\ModuleTesting\Util\InteractsWithFiles;
13
use Symfony\Component\Process\Exception\ProcessFailedException;
14
use Symfony\Component\Process\Process;
15
use Symfony\Component\Yaml\Yaml;
16
use const DIRECTORY_SEPARATOR;
17
use function collect;
18
use function implode;
19
20
21
/**
22
 * Class Generator
23
 *
24
 * @package SmartWeb\ModuleTesting\Codeception
25
 */
26
class SetupGenerator implements SetupGeneratorInterface
27
{
28
    
29
    use InteractsWithFiles;
30
    
31
    /**
32
     * @var SetupInterface
33
     */
34
    protected $setup;
35
    
36
    /**
37
     * @var GlobalConfigurationInterface
38
     */
39
    protected $globalConfiguration;
40
    
41
    /**
42
     * Generator constructor.
43
     *
44
     * @param SetupInterface $setup
45
     */
46
    public function __construct(SetupInterface $setup)
47
    {
48
        $this->setup = $setup;
49
        $this->disk = $setup->getDisk();
50
    }
51
    
52
    /**
53
     * @param string $name
54
     *
55
     * @return mixed
56
     */
57
    public function __get($name)
58
    {
59
        if ($this->globalConfiguration->has($name)) {
60
            return $this->globalConfiguration->get($name);
61
        }
62
        
63
        throw new InvalidArgumentException("'{$name}' was not found in the global configuration");
64
    }
65
    
66
    /**
67
     * @param string[] $suites
68
     *
69
     * @return void
70
     */
71
    public function generate($suites = [])
72
    {
73
        $testDir = $this->setup->getTestsDir();
74
        $namespace = $this->setup->getNamespace() . '\\' . $testDir;
75
        
76
        $this->globalConfiguration = new GlobalConfiguration(
77
            [
78
                'namespace'  => $namespace,
79
                'actor'      => 'Tester',
80
                'paths'      => [
81
                    'tests'   => $testDir,
82
                    'data'    => $testDir . DIRECTORY_SEPARATOR . '_data',
83
                    'output'  => $testDir . DIRECTORY_SEPARATOR . '_output',
84
                    'support' => $testDir . DIRECTORY_SEPARATOR . '_support',
85
                    'envs'    => $testDir . DIRECTORY_SEPARATOR . '_envs',
86
                ],
87
                'extensions' => [
88
                    'enabled' => [
89
                        'Codeception\Extension\RunFailed',
90
                    ],
91
                ],
92
            ]
93
        );
94
        
95
        $this->createGlobalConfiguration();
96
        $this->createTestsDir();
97
        $this->createSupportingDirs();
98
        
99
        $this->createSuites($suites);
100
        $this->build();
101
    }
102
    
103
    /**
104
     * @param string $suite
105
     */
106
    public function createSuiteAndBuild(string $suite)
107
    {
108
        $this->generateSuite(new SuiteInfo($suite));
109
        $this->build();
110
    }
111
    
112
    /**
113
     * @param SuiteInfoInterface $suiteInfo
114
     *
115
     * @return void
116
     */
117
    protected function generateSuite(SuiteInfoInterface $suiteInfo)
118
    {
119
        $suite = $suiteInfo->getName();
120
        $actor = $suiteInfo->getActor();
121
        
122
        $this->executeCodeceptionCommand("g:suite {$suite} {$actor}");
123
    }
124
    
125
    /**
126
     * Build Actor classes
127
     *
128
     * @return void
129
     */
130
    protected function build()
131
    {
132
        $this->executeCodeceptionCommand('build');
133
    }
134
    
135
    /**
136
     * @param string $command
137
     */
138
    protected function executeCodeceptionCommand(string $command)
139
    {
140
        $command = $this->parseCommand(
141
            'vendor/bin/codecept',
142
            $command, "-c {$this->setup->getWorkDir()}", '--quiet'
143
        );
144
        
145
        $process = new Process($command);
146
        
147
        try {
148
            $process->mustRun();
149
            
150
            echo $process->getOutput();
151
        } catch (ProcessFailedException $e) {
152
            echo $e->getMessage();
153
        }
154
    }
155
    
156
    /**
157
     * @param string   $command
158
     * @param string[] ...$arguments
159
     *
160
     * @return string
161
     */
162
    protected function parseCommand(string $command, string ...$arguments) : string
163
    {
164
        return $command . ' ' . implode(' ', $arguments);
165
    }
166
    
167
    protected function createGlobalConfiguration()
168
    {
169
        $str = Yaml::dump($this->globalConfiguration->toArray(), 4);
170
        
171
        $this->createFile('codeception.yml', $str, true);
172
    }
173
    
174
    protected function createTestsDir()
175
    {
176
        $this->createDir($this->setup->getTestsDir(), true);
177
    }
178
    
179
    protected function createSupportingDirs()
180
    {
181
        foreach ($this->globalConfiguration->getSupportingDirs() as $dir) {
182
            $this->createEmptyDir($dir);
183
        }
184
    }
185
    
186
    /**
187
     * @param string[] $suites
188
     */
189
    protected function createSuites($suites)
190
    {
191
        collect($suites)
192
            ->mapIntoWithValues(SuiteInfo::class)
193
            ->each(
194
                function (SuiteInfoInterface $suiteInfo)
195
                {
196
                    $this->generateSuite($suiteInfo);
197
                }
198
            );
199
    }
200
    
201
    /**
202
     * @param string $path
203
     * @param bool   $inBasePath
204
     *
205
     * @return string
206
     */
207 View Code Duplication
    final protected function getPath(string $path, bool $inBasePath = false) : string
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
    {
209
        $pathPrefix = $this->setup->getWorkDir() . DIRECTORY_SEPARATOR;
210
        
211
        return $inBasePath
212
            ? $pathPrefix . $path
213
            : $pathPrefix . $this->setup->getTestsDir() . DIRECTORY_SEPARATOR . $path;
214
    }
215
    
216
    /**
217
     * @param string $path
218
     * @param bool   $inBasePath
219
     *
220
     * @return bool
221
     */
222
    protected function createEmptyDir(string $path, bool $inBasePath = false) : bool
223
    {
224
        if ($this->createDir($path, $inBasePath)) {
225
            return $this->createGitKeep($path, $inBasePath);
226
        }
227
        
228
        return false;
229
    }
230
    
231
    /**
232
     * @param string $dir
233
     * @param bool   $inBasePath
234
     *
235
     * @return bool
236
     */
237
    protected function createGitKeep(string $dir, bool $inBasePath = false) : bool
238
    {
239
        return $this->createFile($dir . DIRECTORY_SEPARATOR . '.gitkeep', '', $inBasePath);
240
    }
241
    
242
}
243