Class_Test::testClassWithParent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of phpDocumentor.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @copyright 2010-2018 Mike van Riel<[email protected]>
9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link      http://phpdoc.org
11
 */
12
13
namespace phpDocumentor\Reflection\Php\Factory;
14
15
use Mockery as m;
16
use phpDocumentor\Reflection\DocBlock as DocBlockElement;
17
use phpDocumentor\Reflection\Fqsen;
18
use phpDocumentor\Reflection\Php\Class_ as ClassElement;
19
use phpDocumentor\Reflection\Php\Constant as ConstantElement;
20
use phpDocumentor\Reflection\Php\Method as MethodElement;
21
use phpDocumentor\Reflection\Php\ProjectFactoryStrategy;
22
use phpDocumentor\Reflection\Php\Property as PropertyElement;
23
use phpDocumentor\Reflection\Php\StrategyContainer;
24
use PhpParser\Comment\Doc;
25
use PhpParser\Node\Const_;
26
use PhpParser\Node\Expr\Variable;
27
use PhpParser\Node\Name;
28
use PhpParser\Node\Stmt\Class_ as ClassNode;
29
use PhpParser\Node\Stmt\ClassConst;
30
use PhpParser\Node\Stmt\ClassMethod;
31
use PhpParser\Node\Stmt\Property as PropertyNode;
32
use PhpParser\Node\Stmt\PropertyProperty;
33
use PhpParser\Node\Stmt\TraitUse;
34
35
/**
36
 * Class Class_Test
37
 * @coversDefaultClass phpDocumentor\Reflection\Php\Factory\Class_
38
 * @covers ::<!public>
39
 */
40
// @codingStandardsIgnoreStart
41
class Class_Test extends TestCase
42
// @codingStandardsIgnoreEnd
43
{
44
    protected function setUp()
45
    {
46
        $this->fixture = new Class_();
47
    }
48
49
    /**
50
     * @covers ::matches
51
     */
52
    public function testMatches()
53
    {
54
        $this->assertFalse($this->fixture->matches(new \stdClass()));
55
        $this->assertTrue($this->fixture->matches(m::mock(ClassNode::class)));
56
    }
57
58
    /**
59
     * @covers ::create
60
     */
61
    public function testSimpleCreate()
62
    {
63
        $containerMock = m::mock(StrategyContainer::class);
64
        $classMock = $this->buildClassMock();
65
        $classMock->shouldReceive('getDocComment')->andReturnNull();
66
67
        /** @var ClassElement $class */
68
        $class = $this->fixture->create($classMock, $containerMock);
69
70
        $this->assertInstanceOf(ClassElement::class, $class);
71
        $this->assertEquals('\Space\MyClass', (string) $class->getFqsen());
72
        $this->assertNull($class->getParent());
73
        $this->assertTrue($class->isFinal());
74
        $this->assertTrue($class->isAbstract());
75
    }
76
77
    /**
78
     * @covers ::create
79
     */
80
    public function testClassWithParent()
81
    {
82
        $containerMock = m::mock(StrategyContainer::class);
83
        $classMock = $this->buildClassMock();
84
        $classMock->shouldReceive('getDocComment')->andReturnNull();
85
        $classMock->extends = 'Space\MyParent';
86
87
        /** @var ClassElement $class */
88
        $class = $this->fixture->create($classMock, $containerMock);
89
90
        $this->assertInstanceOf(ClassElement::class, $class);
91
        $this->assertEquals('\Space\MyClass', (string) $class->getFqsen());
92
        $this->assertEquals('\Space\MyParent', (string) $class->getParent());
93
    }
94
95
    /**
96
     * @covers ::create
97
     */
98
    public function testClassImplementingInterface()
99
    {
100
        $containerMock = m::mock(StrategyContainer::class);
101
        $classMock = $this->buildClassMock();
102
        $classMock->shouldReceive('getDocComment')->andReturnNull();
103
        $classMock->extends = 'Space\MyParent';
104
        $classMock->implements = [
105
            new Name('MyInterface'),
106
        ];
107
108
        /** @var ClassElement $class */
109
        $class = $this->fixture->create($classMock, $containerMock);
110
111
        $this->assertInstanceOf(ClassElement::class, $class);
112
        $this->assertEquals('\Space\MyClass', (string) $class->getFqsen());
113
114
        $this->assertEquals(
115
            ['\MyInterface' => new Fqsen('\MyInterface')],
116
            $class->getInterfaces()
117
        );
118
    }
119
120
    /**
121
     * @covers ::create
122
     */
123
    public function testWithMethodMembers()
124
    {
125
        $method1 = new ClassMethod('MyClass::method1');
126
        $method1Descriptor = new MethodElement(new Fqsen('\MyClass::method1'));
127
        $strategyMock = m::mock(ProjectFactoryStrategy::class);
128
        $containerMock = m::mock(StrategyContainer::class);
129
        $classMock = $this->buildClassMock();
130
        $classMock->shouldReceive('getDocComment')->andReturnNull();
131
        $classMock->stmts = [
132
            $method1,
133
        ];
134
135
        $strategyMock->shouldReceive('create')
136
            ->with($method1, $containerMock, null)
137
            ->andReturn($method1Descriptor);
138
139
        $containerMock->shouldReceive('findMatching')
140
            ->with($method1)
141
            ->andReturn($strategyMock);
142
143
        /** @var ClassDescriptor $class */
144
        $class = $this->fixture->create($classMock, $containerMock);
145
146
        $this->assertInstanceOf(ClassElement::class, $class);
147
        $this->assertEquals('\Space\MyClass', (string) $class->getFqsen());
148
        $this->assertEquals(
149
            ['\MyClass::method1' => $method1Descriptor],
150
            $class->getMethods()
151
        );
152
    }
153
154
    /**
155
     * @covers ::create
156
     */
157
    public function testWithPropertyMembers()
158
    {
159
        $propertyProperty = new PropertyProperty('\MyClass::$property');
160
        $property = new PropertyNode(1, [$propertyProperty]);
161
        $propertyDescriptor = new PropertyElement(new Fqsen('\MyClass::$property'));
162
        $strategyMock = m::mock(ProjectFactoryStrategy::class);
163
        $containerMock = m::mock(StrategyContainer::class);
164
        $classMock = $this->buildClassMock();
165
        $classMock->shouldReceive('getDocComment')->andReturnNull();
166
        $classMock->stmts = [
167
            $property,
168
        ];
169
170
        $strategyMock->shouldReceive('create')
171
            ->with(m::type(PropertyIterator::class), $containerMock, null)
172
            ->andReturn($propertyDescriptor);
173
174
        $containerMock->shouldReceive('findMatching')
175
            ->with(m::type(PropertyIterator::class))
176
            ->andReturn($strategyMock);
177
178
        /** @var ClassElement $class */
179
        $class = $this->fixture->create($classMock, $containerMock);
180
181
        $this->assertInstanceOf(ClassElement::class, $class);
182
        $this->assertEquals('\Space\MyClass', (string) $class->getFqsen());
183
        $this->assertEquals(
184
            ['\MyClass::$property' => $propertyDescriptor],
185
            $class->getProperties()
186
        );
187
    }
188
189
    /**
190
     * @covers ::create
191
     */
192
    public function testWithUsedTraits()
193
    {
194
        $trait = new TraitUse([new Name('MyTrait'), new Name('OtherTrait')]);
195
        $containerMock = m::mock(StrategyContainer::class);
196
        $containerMock->shouldReceive('findMatching')->never();
197
        $classMock = $this->buildClassMock();
198
        $classMock->shouldReceive('getDocComment')->andReturnNull();
199
        $classMock->stmts = [
200
            $trait,
201
        ];
202
203
        /** @var ClassElement $class */
204
        $class = $this->fixture->create($classMock, $containerMock);
205
206
        $this->assertEquals(
207
            [
208
                '\MyTrait' => new Fqsen('\MyTrait'),
209
                '\OtherTrait' => new Fqsen('\OtherTrait'),
210
            ],
211
            $class->getUsedTraits()
212
        );
213
    }
214
215
    /**
216
     * @covers ::create
217
     */
218
    public function testWithConstants()
219
    {
220
        $const = new Const_('\Space\MyClass::MY_CONST', new Variable('a'));
221
        $constant = new ClassConst([$const]);
222
223
        $result = new ConstantElement(new Fqsen('\Space\MyClass::MY_CONST'));
224
        $strategyMock = m::mock(ProjectFactoryStrategy::class);
225
        $containerMock = m::mock(StrategyContainer::class);
226
227
        $strategyMock->shouldReceive('create')
228
            ->with(m::type(ClassConstantIterator::class), $containerMock, null)
229
            ->andReturn($result);
230
231
        $containerMock->shouldReceive('findMatching')
232
            ->with(m::type(ClassConstantIterator::class))
233
            ->andReturn($strategyMock);
234
235
        $classMock = $this->buildClassMock();
236
        $classMock->shouldReceive('getDocComment')->andReturnNull();
237
        $classMock->stmts = [
238
            $constant,
239
        ];
240
241
        /** @var ClassElement $class */
242
        $class = $this->fixture->create($classMock, $containerMock);
243
244
        $this->assertEquals(
245
            [
246
                '\Space\MyClass::MY_CONST' => $result,
247
            ],
248
            $class->getConstants()
249
        );
250
    }
251
252
    /**
253
     * @covers ::create
254
     */
255
    public function testCreateWithDocBlock()
256
    {
257
        $doc = m::mock(Doc::class);
258
        $classMock = $this->buildClassMock();
259
        $classMock->shouldReceive('getDocComment')->andReturn($doc);
260
261
        $docBlock = new DocBlockElement('');
262
263
        $strategyMock = m::mock(ProjectFactoryStrategy::class);
264
        $containerMock = m::mock(StrategyContainer::class);
265
266
        $strategyMock->shouldReceive('create')
267
            ->with($doc, $containerMock, null)
268
            ->andReturn($docBlock);
269
270
        $containerMock->shouldReceive('findMatching')
271
            ->with($doc)
272
            ->andReturn($strategyMock);
273
274
        /** @var ClassElement $class */
275
        $class = $this->fixture->create($classMock, $containerMock);
276
277
        $this->assertSame($docBlock, $class->getDocBlock());
278
    }
279
280
    /**
281
     * @return m\MockInterface|ClassNode
282
     */
283
    private function buildClassMock()
284
    {
285
        $classMock = m::mock(ClassNode::class);
286
        $classMock->fqsen = new Fqsen('\Space\MyClass');
287
        $classMock->shouldReceive('isFinal')->andReturn(true);
288
        $classMock->shouldReceive('isAbstract')->andReturn(true);
289
        $classMock->shouldReceive('getLine')->andReturn(1);
290
        return $classMock;
291
    }
292
}
293