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

Generator/EntityTestGenerator.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Oro\Bundle\TestGeneratorBundle\Generator;
4
5
class EntityTestGenerator extends AbstractTestGenerator
6
{
7
    /**
8
     * @var string
9
     */
10
    protected $className;
11
12
    /**
13
     * @param string $className
14
     */
15 View Code Duplication
    public function generate($className)
16
    {
17
        $this->className = $className;
18
        $class = new \ReflectionClass($className);
19
        $propertiesData = $this->getProperties($class);
20
        $fullTestNameSpace = $this->getNamespaceForTest($className, 'unit');
21
        $parts = explode('\\', $fullTestNameSpace);
22
        $testClassName = array_pop($parts);
23
        $partsOfOriginClass = explode('\\', $className);
24
        $testedClassName = array_pop($partsOfOriginClass);
25
        $nameSpace = implode('\\', $parts);
26
        $testPath = $this->getTestPath($fullTestNameSpace);
27
        $constructor = $class->getConstructor();
28
        $dependencies = $constructor ? $this->getDependencies($constructor) : [];
29
        $dependenciesData = $this->getDependenciesData($dependencies);
30
        $this->addClassToUses($className);
31
        $this->addClassToUses('Oro\Component\Testing\Unit\EntityTestCaseTrait');
32
        $orderedUses = $this->getOrderedUses($this->usedClasses);
33
        $content = $this->twig->render(
34
            '@OroTestGenerator/Tests/entity_template.php.twig',
35
            [
36
                'namespace' => $nameSpace,
37
                'vendors' => $orderedUses,
38
                'className' => $testClassName,
39
                'testedClassName' => $testedClassName,
40
                'testedClassNameVariable' => lcfirst($testedClassName),
41
                'dependenciesData' => $dependenciesData,
42
                'propertiesData' => $propertiesData
43
            ]
44
        );
45
        $this->createFile($testPath, $content);
46
    }
47
48
    /**
49
     * @param \ReflectionClass $class
50
     * @return array
51
     */
52
    protected function getProperties(\ReflectionClass $class)
53
    {
54
        $data = [];
55
        $uses = $this->getUses($class);
56
        foreach ($class->getProperties() as $property) {
57
            $type = $this->getPropertyType($property);
58
            $temp = [];
59
            $temp['propertyName'] = $property->getName();
60
            if ($type) {
61
                if ($type === 'integer' || $type === 'float'
62
                    || $type === 'string' || $type === 'bool' || $type === 'boolean'
63
                ) {
64
                    $temp['type'] = $type;
65
                    $temp = $this->fillScalarType($type, $temp);
66
                } elseif (strpos($type, '[]') !== false) {
67
                    $temp['type'] = str_replace('[]', '', $type);
68
                    $temp['fullClass'] = $this->getFullClassName($temp['type'], $uses);
69
                    $temp['collection'] = true;
70
                    $this->addClassToUses($temp['fullClass']);
71
                } else {
72
                    $temp['type'] = $type;
73
                    $temp['fullClass'] = $this->getFullClassName($type, $uses);
74
                    $this->addClassToUses($temp['fullClass']);
0 ignored issues
show
It seems like $temp['fullClass'] can also be of type boolean; however, Oro\Bundle\TestGenerator...rator::addClassToUses() does only seem to accept object<ReflectionClass>|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
75
                }
76
                $data[] = $temp;
77
            }
78
        }
79
80
        return $this->groupPropertiesByCollection($data);
81
    }
82
83
    /**
84
     * @param array $properties
85
     * @return array
86
     */
87
    protected function groupPropertiesByCollection($properties)
88
    {
89
        $result['collection'] = [];
90
        $result['simple'] = [];
91
        foreach ($properties as $property) {
92
            if (isset($property['collection'])) {
93
                unset($property['collection']);
94
                $result['collection'][] = $property;
95
            } else {
96
                $result['simple'][] = $property;
97
            }
98
        }
99
100
        return $result;
101
    }
102
103
    /**
104
     * @param \ReflectionProperty $property
105
     * @return string|false
106
     */
107
    protected function getPropertyType(\ReflectionProperty $property)
108
    {
109
        $doc = $property->getDocComment();
110
        preg_match_all('#@(.*?)\n#s', $doc, $annotations);
111
        $annotations = $annotations[1];
112
        $resultAnnotation = null;
113
        foreach ($annotations as $annotation) {
114
            if (strpos($annotation, 'var ') !== false) {
115
                $annotation = str_replace('var ', '', $annotation);
116
                if (strpos($annotation, '$') !== false) {
117
                    $annotation = explode(' ', $annotation)[0];
118
                }
119
                $resultAnnotation = $annotation;
120
                break;
121
            }
122
        }
123
        if (!$resultAnnotation) {
124
            return false;
125
        }
126
        if (strpos($resultAnnotation, '|') === false) {
127
            return $resultAnnotation;
128
        } else {
129
            $parts = explode('|', $resultAnnotation);
130
            foreach ($parts as $part) {
131
                if (strpos($part, '[]') !== false) {
132
                    return $part;
133
                }
134
            }
135
        }
136
137
        return false;
138
    }
139
140
    /**
141
     * @param \ReflectionClass $class
142
     * @return array
143
     */
144
    protected function getUses(\ReflectionClass $class)
145
    {
146
        $result = [];
147
        $lines = file($class->getFileName());
148
        $i = 4;
149
        while (strpos($lines[$i], '/*') === false && strpos($lines[$i], 'class ') === false) {
150
            if ($lines[$i] !== "\n" && strpos($lines[$i], ' as ') === false) {
151
                $result[] = str_replace(['use ', ';' . PHP_EOL], '', $lines[$i]);
152
            }
153
            $i++;
154
        }
155
156
        return $result;
157
    }
158
159
    /**
160
     * @param $className
161
     * @param string[] $fullClassNames
162
     * @return bool|string
163
     */
164
    protected function getFullClassName($className, $fullClassNames)
165
    {
166
        if (strpos($className, '\\') === 0) {
167
            return $className;
168
        }
169
170
        foreach ($fullClassNames as $fullClassName) {
171
            $parts = explode('\\', $fullClassName);
172
            if ($className === end($parts)) {
173
                return $fullClassName;
174
            }
175
        }
176
        $parts = explode('\\', $this->className);
177
        array_pop($parts);
178
179
        return implode('\\', $parts) . '\\' . $className;
180
    }
181
182
    /**
183
     * @param string $type
184
     * @param array $temp
185
     * @return array
186
     */
187
    protected function fillScalarType($type, $temp)
188
    {
189
        if ($type === 'integer') {
190
            $temp['value'] = 42;
191
192
            return $temp;
193
        } elseif ($type === 'float') {
194
            $temp['value'] = 3.1415926;
195
196
            return $temp;
197
        } elseif ($type === 'bool' || $type === 'boolean') {
198
            $temp['value'] = true;
199
200
            return $temp;
201
        } else {
202
            $temp['value'] = 'some string';
203
            $temp['quotes'] = true;
204
205
            return $temp;
206
        }
207
    }
208
}
209