PhpFileModel   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 218
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 60
dl 0
loc 218
rs 10
c 0
b 0
f 0
wmc 27

17 Methods

Rating   Name   Duplication   Size   Complexity  
A addUse() 0 3 1
A hasUse() 0 3 1
A getInterfaces() 0 3 1
A addTrait() 0 3 1
A getMockAnnotations() 0 4 1
A addClass() 0 3 1
A getConcreteUses() 0 3 1
A addInterface() 0 3 1
A getTraits() 0 3 1
A getClasses() 0 3 1
A getFullNameFor() 0 4 2
A getUse() 0 9 2
A getClassLikeCollection() 0 6 1
A addConcreteUse() 0 26 6
A __construct() 0 7 1
A getInterfacesFunctionsCount() 0 7 2
A getTestableFunctionsCount() 0 10 3
1
<?php
2
3
/**
4
 * This file is part of PhpUnitGen.
5
 *
6
 * (c) 2017-2018 Paul Thébaud <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11
12
namespace PhpUnitGen\Model;
13
14
use Doctrine\Common\Collections\ArrayCollection;
15
use Doctrine\Common\Collections\Collection;
16
use PhpUnitGen\Annotation\AnnotationInterface\AnnotationInterface;
17
use PhpUnitGen\Annotation\MockAnnotation;
18
use PhpUnitGen\Exception\ParseException;
19
use PhpUnitGen\Model\ModelInterface\ClassModelInterface;
20
use PhpUnitGen\Model\ModelInterface\InterfaceModelInterface;
21
use PhpUnitGen\Model\ModelInterface\PhpFileModelInterface;
22
use PhpUnitGen\Model\ModelInterface\TraitModelInterface;
23
use PhpUnitGen\Model\PropertyTrait\ClassLikeTrait;
24
use PhpUnitGen\Model\PropertyTrait\DocumentationTrait;
25
use PhpUnitGen\Model\PropertyTrait\NamespaceTrait;
26
use PhpUnitGen\Model\PropertyTrait\NameTrait;
27
use PhpUnitGen\Model\PropertyTrait\NodeTrait;
28
use Respect\Validation\Validator;
29
30
/**
31
 * Class PhpFileModel.
32
 *
33
 * @author     Paul Thébaud <[email protected]>.
34
 * @copyright  2017-2018 Paul Thébaud <[email protected]>.
35
 * @license    https://opensource.org/licenses/MIT The MIT license.
36
 * @link       https://github.com/paul-thebaud/phpunit-generator
37
 * @since      Class available since Release 2.0.0.
38
 */
39
class PhpFileModel implements PhpFileModelInterface
40
{
41
    use NameTrait;
42
    use NamespaceTrait;
43
    use NodeTrait;
44
    use ClassLikeTrait;
45
    use DocumentationTrait;
46
47
    /**
48
     * This array is constructed with the full name as key, and the class name as a value.
49
     * @var string[] $uses Imports needed for tests skeletons.
50
     */
51
    private $concreteUses = [];
52
53
    /**
54
     * @var string[] $uses Imports contained in the file.
55
     */
56
    private $uses = [];
57
58
    /**
59
     * @var ClassModelInterface[]|Collection $classes Classes contained in the file.
60
     */
61
    private $classes;
62
63
    /**
64
     * @var TraitModelInterface[]|Collection $traits Traits contained in the file.
65
     */
66
    private $traits;
67
68
    /**
69
     * @var InterfaceModelInterface[]|Collection $interfaces Interfaces contained in the file.
70
     */
71
    private $interfaces;
72
73
    /**
74
     * PhpFileModel constructor.
75
     */
76
    public function __construct()
77
    {
78
        $this->functions   = new ArrayCollection();
79
        $this->classes     = new ArrayCollection();
80
        $this->traits      = new ArrayCollection();
81
        $this->interfaces  = new ArrayCollection();
82
        $this->annotations = new ArrayCollection();
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function getTestableFunctionsCount(): int
89
    {
90
        $sum = $this->countNotAbstractFunctions();
91
        foreach ($this->getTraits() as $trait) {
92
            $sum += $trait->countNotAbstractFunctions();
93
        }
94
        foreach ($this->getClasses() as $class) {
95
            $sum += $class->countNotAbstractFunctions();
96
        }
97
        return $sum;
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function getInterfacesFunctionsCount(): int
104
    {
105
        $sum = 0;
106
        foreach ($this->getInterfaces() as $interface) {
107
            $sum += $interface->countNotAbstractFunctions();
108
        }
109
        return $sum;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function getFullNameFor(string $name): string
116
    {
117
        $namespace = $this->getNamespaceString();
118
        return $namespace === null? $name : $namespace . '\\' . $name;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    public function addConcreteUse(string $fullName, string $name): void
125
    {
126
        // Remove the backslash at beginning of full name
127
        $fullName = preg_replace('/^\\\\/', '', $fullName);
128
129
        // Full name exists and concrete use correspond to this one
130
        if (Validator::key($fullName)->validate($this->concreteUses)
131
            && $name === $this->concreteUses[$fullName]
132
        ) {
133
            // Do not add
134
            return;
135
        }
136
137
        // Delete duplicate class name
138
        $iteration = 0;
139
        while (Validator::contains($name)->validate($this->concreteUses)) {
140
            if ($iteration === 0 && Validator::contains($fullName)->validate($this->uses)) {
141
                // If a known alias exists
142
                $name = array_search($fullName, $this->uses);
143
            } else {
144
                // Give a default alias
145
                $name .= 'Alias';
146
            }
147
            $iteration++;
148
        }
149
        $this->concreteUses[$fullName] = $name;
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function getConcreteUses(): array
156
    {
157
        return $this->concreteUses;
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163
    public function addUse(string $name, string $fullName): void
164
    {
165
        $this->uses[$name] = $fullName;
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function hasUse(string $name): bool
172
    {
173
        return Validator::key($name)->validate($this->uses);
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179
    public function getUse(string $name): string
180
    {
181
        if (! $this->hasUse($name)) {
182
            throw new ParseException(sprintf(
183
                'Trying to get a full class name for "%s", but it does not exists',
184
                $name
185
            ));
186
        }
187
        return $this->uses[$name];
188
    }
189
190
    /**
191
     * {@inheritdoc}
192
     */
193
    public function addClass(ClassModelInterface $class): void
194
    {
195
        $this->classes->add($class);
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201
    public function getClasses(): Collection
202
    {
203
        return $this->classes;
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209
    public function addTrait(TraitModelInterface $trait): void
210
    {
211
        $this->traits->add($trait);
212
    }
213
214
    /**
215
     * {@inheritdoc}
216
     */
217
    public function getTraits(): Collection
218
    {
219
        return $this->traits;
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225
    public function addInterface(InterfaceModelInterface $interface): void
226
    {
227
        $this->interfaces->add($interface);
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     */
233
    public function getInterfaces(): Collection
234
    {
235
        return $this->interfaces;
236
    }
237
238
    /**
239
     * {@inheritdoc}
240
     */
241
    public function getClassLikeCollection(): Collection
242
    {
243
        return new ArrayCollection(array_merge(
244
            $this->classes->toArray(),
245
            $this->traits->toArray(),
246
            $this->interfaces->toArray()
247
        ));
248
    }
249
250
    /**
251
     * @return Collection|MockAnnotation[] The mock annotations.
252
     */
253
    public function getMockAnnotations(): Collection
254
    {
255
        return $this->annotations->filter(function (AnnotationInterface $annotation) {
256
            return $annotation->getType() === AnnotationInterface::TYPE_MOCK;
257
        });
258
    }
259
}
260