Passed
Push — develop ( 4c7678...74dbd7 )
by Paul
02:25
created

PhpFileModel::addUse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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