Completed
Push — master ( e32eeb...714cda )
by
unknown
89:50 queued 46:29
created

AbstractTestGenerator::getDependenciesData()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 30
Code Lines 23

Duplication

Lines 5
Ratio 16.67 %
Metric Value
dl 5
loc 30
rs 8.439
cc 6
eloc 23
nc 6
nop 1
1
<?php
2
3
namespace Oro\Bundle\TestGeneratorBundle\Generator;
4
5
use Symfony\Component\HttpKernel\KernelInterface;
6
7
abstract class AbstractTestGenerator
8
{
9
    /**
10
     * @var \Twig_Environment
11
     */
12
    protected $twig;
13
14
    /**
15
     * @var  KernelInterface
16
     */
17
    protected $kernel;
18
19
    /**
20
     * @var array
21
     */
22
    protected $usedClasses;
23
24
    /**
25
     * @param \Twig_Environment $twig
26
     * @param KernelInterface $kernelInterface
27
     */
28
    public function __construct(
29
        \Twig_Environment $twig,
30
        KernelInterface $kernelInterface
31
    ) {
32
        $this->twig = $twig;
33
        $this->kernel = $kernelInterface;
34
        $this->usedClasses = [];
35
    }
36
37
    /**
38
     * @param string $className
39
     */
40
    abstract public function generate($className);
41
42
    /**
43
     * @param \ReflectionClass $class
44
     * @return array
45
     */
46
    protected function getMethodsData(\ReflectionClass $class)
47
    {
48
        $data = [];
49
        $methods = $this->getPublicMethods($class);
50
        foreach ($methods as $method) {
51
            $methodName = $method->getName();
52
            if ($methodName !== '__construct') {
53
                $params = $method->getParameters();
54
                $arguments = [];
55
                foreach ($params as $param) {
56
                    $arguments = $this->fillArguments($param, $arguments);
57
                }
58
                $data[] = [
59
                    'name' => $methodName,
60
                    'arguments' => $arguments,
61
                    'testName' => 'test' . ucfirst($methodName)
62
                ];
63
            }
64
        }
65
66
        return $data;
67
    }
68
69
70
    /**
71
     * @param \ReflectionClass $class
72
     * @return \ReflectionMethod[]
73
     */
74
    protected function getPublicMethods(\ReflectionClass $class)
75
    {
76
        $methods = [];
77
        foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
78
            if ($method->getDeclaringClass()->getName() === $class->getName()) {
79
                $methods[] = $method;
80
            }
81
        }
82
83
        return $methods;
84
    }
85
86
    /**
87
     * @param array $dependencies
88
     * @return array
89
     */
90
    protected function getDependenciesData($dependencies)
91
    {
92
        $data = [];
93
        foreach ($dependencies as $dependency) {
94
            $temp = [];
95
            if ($dependency['class'] !== 'non_object') {
96
                if (strpos($dependency['class'], '\\')) {
97
                    $parts = explode('\\', $dependency['class']);
98
                    $temp['class'] = end($parts);
99
                    $temp['fullClassName'] = $dependency['class'];
100
                } else {
101
                    $temp['class'] = '\\' . $dependency['class'];
102
                    $temp['fullClassName'] = '\\' . $dependency['class'];
103
                }
104
                $class = new \ReflectionClass($dependency['class']);
105
                $constructor = $class->getConstructor();
106 View Code Duplication
                if ($constructor && $constructor->getParameters()) {
107
                    $temp['has_constructor'] = true;
108
                } else {
109
                    $temp['has_constructor'] = false;
110
                }
111
            } else {
112
                $temp['class'] = '';
113
            }
114
            $temp['variable'] = $dependency['name'];
115
            $data[] = $temp;
116
        }
117
118
        return $data;
119
    }
120
121
    /**
122
     * @param string[] $classes
123
     * @return array
124
     */
125
    protected function getOrderedUses(array  $classes)
126
    {
127
        $result = [];
128
        foreach ($classes as $class) {
129
            $slashPos = strpos($class, '\\');
130
            if ($slashPos) {
131
                $vendor = substr($class, 0, $slashPos);
132
                $result[$vendor][] = $class;
133
            }
134
        }
135
136
        return $result;
137
    }
138
139
    /**
140
     * @param string $className
141
     * @param string $testType
142
     * @return string
143
     */
144
    protected function getNamespaceForTest($className, $testType)
145
    {
146
        $parts = explode('\\', $className);
147
        $i = count($parts);
148
        while ($i > 0) {
149
            $i--;
150
            if (strpos($parts[$i], 'Bundle')) {
151
                break;
152
            }
153
        }
154
        $result = [];
155
        foreach ($parts as $key => $part) {
156
            $result[] = $part;
157
            if ($key === $i) {
158
                $result[] = 'Tests';
159
                $result[] = ucfirst($testType);
160
            }
161
        }
162
163
        return implode('\\', $result) . 'Test';
164
    }
165
166
    /**
167
     * @param string $namespace
168
     * @return string
169
     */
170
    protected function getTestPath($namespace)
171
    {
172
        $root = $this->kernel->getRootDir();
173
        $parts = explode(DIRECTORY_SEPARATOR, $root);
174
        array_pop($parts);
175
176
        //for monolithic
177
        if (strpos($root, DIRECTORY_SEPARATOR . 'application' . DIRECTORY_SEPARATOR) !== false) {
178
            $application = array_pop($parts);
179
            array_pop($parts);
180
            $parts[] = 'package';
181
            $parts[] = $application;
182
        }
183
        $parts[] = 'src';
184
185
        return implode(DIRECTORY_SEPARATOR, $parts)
186
            . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . '.php';
187
    }
188
189
    /**
190
     * @param string $path
191
     * @param string $content
192
     */
193
    protected function createFile($path, $content)
194
    {
195
        if (!file_exists(dirname($path))) {
196
            mkdir(dirname($path), 0777, true);
197
        }
198
        $fp = fopen($path, 'w');
199
        fwrite($fp, $content);
200
        fclose($fp);
201
    }
202
203
    /**
204
     * @param \ReflectionMethod $constructor
205
     * @return array
206
     */
207
    protected function getDependencies(\ReflectionMethod $constructor)
208
    {
209
        $dependencies = [];
210
        if ($constructor) {
211
            $params = $constructor->getParameters();
212
            foreach ($params as $param) {
213
                $class = $param->getClass();
214
                $this->addClassToUses($class);
215
                $dependencies[] = ['class' => $class ? $class->getName() : 'non_object', 'name' => $param->getName()];
216
            }
217
218
            return $dependencies;
219
        }
220
221
        return $dependencies;
222
    }
223
224
    /**
225
     * @param \ReflectionParameter $param
226
     * @param array $arguments
227
     * @return array
228
     */
229
    protected function fillArguments(\ReflectionParameter $param, $arguments)
230
    {
231
        $temp = [];
232
        $class = $param->getClass();
233
        if ($class) {
234
            $this->addClassToUses($class);
235
            $constructor = $class->getConstructor();
236 View Code Duplication
            if ($constructor && $constructor->getParameters()) {
237
                $temp['has_constructor'] = true;
238
            } else {
239
                $temp['has_constructor'] = false;
240
            }
241
        }
242
        $fullClassName = $class ? $class->getName() : 'non_object';
243
        if (strpos($fullClassName, '\\')) {
244
            $parts = explode('\\', $fullClassName);
245
            $temp['class'] = end($parts);
246
            $temp['fullClass'] = $fullClassName;
247
        } elseif ($fullClassName !== 'non_object') {
248
            $temp['class'] = '\\' . $fullClassName;
249
            $temp['fullClass'] = $temp['class'];
250
        } else {
251
            $temp['class'] = '';
252
        }
253
254
        $temp['name'] = $param->getName();
255
        $arguments[] = $temp;
256
257
        return $arguments;
258
    }
259
260
    /**
261
     * @param \ReflectionClass|string $class
262
     */
263
    protected function addClassToUses($class)
264
    {
265
        if ($class instanceof \ReflectionClass) {
266
            if (!in_array($class->getName(), $this->usedClasses, true)) {
267
                $this->usedClasses[] = $class->getName();
268
            }
269
        } elseif ($class && !in_array($class, $this->usedClasses, true) && strpos($class, '\\') !== 0) {
270
            $this->usedClasses[] = $class;
271
        }
272
    }
273
}
274