Completed
Push — develop ( 904dd0...7938f1 )
by Jaap
02:53
created

FileTest::testFileDocBlockWithComments()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 24
rs 8.9713
cc 1
eloc 15
nc 1
nop 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-2015 Mike van Riel<[email protected]>
9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link      http://phpdoc.org
11
 */
12
13
14
namespace phpDocumentor\Reflection\Php\Factory;
15
16
use Mockery as m;
17
use phpDocumentor\Reflection\DocBlock as DocBlockDescriptor;
18
use phpDocumentor\Reflection\File as SourceFile;
19
use phpDocumentor\Reflection\Fqsen;
20
use phpDocumentor\Reflection\Middleware\Middleware;
21
use phpDocumentor\Reflection\Php\NodesFactory;
22
use phpDocumentor\Reflection\Php\StrategyContainer;
23
use phpDocumentor\Reflection\Php\File as FileElement;
24
use phpDocumentor\Reflection\Php\Class_ as ClassElement;
25
use phpDocumentor\Reflection\Php\Function_ as FunctionElement;
26
use phpDocumentor\Reflection\Php\Interface_ as InterfaceElement;
27
use phpDocumentor\Reflection\Php\Trait_ as TraitElement;
28
use PhpParser\Comment as CommentNode;
29
use PhpParser\Comment\Doc as DocBlockNode;
30
use PhpParser\Node\Name;
31
use PhpParser\Node\Stmt\Class_ as ClassNode;
32
use PhpParser\Node\Stmt\Function_ as FunctionNode;
33
use PhpParser\Node\Stmt\Interface_ as InterfaceNode;
34
use PhpParser\Node\Stmt\Namespace_ as NamespaceNode;
35
use PhpParser\Node\Stmt\Trait_ as TraitNode;
36
37
/**
38
 * Test case for \phpDocumentor\Reflection\Php\Factory\File
39
 * @coversDefaultClass \phpDocumentor\Reflection\Php\Factory\File
40
 * @covers ::<!public>
41
 * @covers ::__construct
42
 */
43
class FileTest extends TestCase
44
{
45
    /**
46
     * @var m\MockInterface
47
     */
48
    private $nodesFactoryMock;
49
50
    protected function setUp()
51
    {
52
        $this->nodesFactoryMock = m::mock(NodesFactory::class);
53
        $this->fixture = new File($this->nodesFactoryMock);
54
    }
55
56
    /**
57
     * @covers ::matches
58
     */
59
    public function testMatches()
60
    {
61
        $this->assertFalse($this->fixture->matches(new \stdClass()));
62
        $this->assertTrue($this->fixture->matches(m::mock(SourceFile::class)));
63
    }
64
65
    /**
66
     * @covers ::create
67
     */
68
    public function testFileWithFunction()
69
    {
70
        $functionNode = new FunctionNode('myFunction');
71
        $this->nodesFactoryMock->shouldReceive('create')
72
            ->with(file_get_contents(__FILE__))
73
            ->andReturn(
74
                [
75
                    $functionNode
76
                ]
77
            );
78
79
        $containerMock = m::mock(StrategyContainer::class);
80
        $containerMock->shouldReceive('findMatching->create')
81
            ->once()
82
            ->with($functionNode, $containerMock, m::any())
83
            ->andReturn(new FunctionElement(new Fqsen('\myFunction()')));
84
85
        /** @var FileElement $file */
86
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
87
88
        $this->assertEquals(__FILE__, $file->getPath());
89
        $this->assertArrayHasKey('\myFunction()', $file->getFunctions());
90
    }
91
92
    /**
93
     * @covers ::create
94
     */
95
    public function testFileWithClass()
96
    {
97
        $classNode = new ClassNode('myClass');
98
        $this->nodesFactoryMock->shouldReceive('create')
99
            ->with(file_get_contents(__FILE__))
100
            ->andReturn(
101
                [
102
                    $classNode
103
                ]
104
            );
105
106
        $containerMock = m::mock(StrategyContainer::class);
107
        $containerMock->shouldReceive('findMatching->create')
108
            ->once()
109
            ->with($classNode, $containerMock, m::any())
110
            ->andReturn(new ClassElement(new Fqsen('\myClass')));
111
112
        /** @var FileElement $file */
113
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
114
115
        $this->assertEquals(__FILE__, $file->getPath());
116
        $this->assertArrayHasKey('\myClass', $file->getClasses());
117
    }
118
119
    /**
120
     * @covers ::create
121
     */
122
    public function testFileWithNamespace()
123
    {
124
        $namespaceNode = new NamespaceNode(new Name('mySpace'));
125
        $namespaceNode->fqsen = new Fqsen('\mySpace');
0 ignored issues
show
Bug introduced by
The property fqsen does not seem to exist in PhpParser\Node\Stmt\Namespace_.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
126
        $this->nodesFactoryMock->shouldReceive('create')
127
            ->with(file_get_contents(__FILE__))
128
            ->andReturn(
129
                [
130
                    $namespaceNode
131
                ]
132
            );
133
134
        $containerMock = m::mock(StrategyContainer::class);
135
136
        /** @var FileElement $file */
137
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
138
139
        $this->assertEquals(__FILE__, $file->getPath());
140
        $this->assertArrayHasKey('\mySpace', $file->getNamespaces());
141
    }
142
143
    /**
144
     * @covers ::create
145
     */
146
    public function testFileWithInterface()
147
    {
148
        $interfaceNode = new InterfaceNode('myInterface');
149
        $this->nodesFactoryMock->shouldReceive('create')
150
            ->with(file_get_contents(__FILE__))
151
            ->andReturn(
152
                [
153
                    $interfaceNode
154
                ]
155
            );
156
157
        $containerMock = m::mock(StrategyContainer::class);
158
        $containerMock->shouldReceive('findMatching->create')
159
            ->once()
160
            ->with($interfaceNode, $containerMock, m::any())
161
            ->andReturn(new InterfaceElement(new Fqsen('\myInterface')));
162
163
        /** @var FileElement $file */
164
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
165
166
        $this->assertEquals(__FILE__, $file->getPath());
167
        $this->assertArrayHasKey('\myInterface', $file->getInterfaces());
168
    }
169
170
    /**
171
     * @covers ::create
172
     */
173
    public function testFileWithTrait()
174
    {
175
        $traitNode = new TraitNode('\myTrait');
176
        $this->nodesFactoryMock->shouldReceive('create')
177
            ->with(file_get_contents(__FILE__))
178
            ->andReturn(
179
                [
180
                    $traitNode
181
                ]
182
            );
183
184
        $containerMock = m::mock(StrategyContainer::class);
185
        $containerMock->shouldReceive('findMatching->create')
186
            ->once()
187
            ->with($traitNode, $containerMock, m::any())
188
            ->andReturn(new TraitElement(new Fqsen('\myTrait')));
189
190
        /** @var FileElement $file */
191
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
192
193
        $this->assertEquals(__FILE__, $file->getPath());
194
        $this->assertArrayHasKey('\myTrait', $file->getTraits());
195
    }
196
197
    /**
198
     * @covers ::create
199
     */
200
    public function testMiddlewareIsExecuted()
201
    {
202
        $file = new FileElement('aa', __FILE__);
203
        $this->nodesFactoryMock->shouldReceive('create')
204
            ->with(file_get_contents(__FILE__))
205
            ->andReturn([]);
206
207
        $middleware = m::mock(Middleware::class);
208
        $middleware->shouldReceive('execute')
209
            ->once()
210
            ->andReturn($file);
211
        $fixture = new File($this->nodesFactoryMock, [$middleware]);
0 ignored issues
show
Documentation introduced by
array($middleware) is of type array<integer,object<Moc...kery\\MockInterface>"}>, but the function expects a array<integer,object<php...Middleware\Middleware>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
212
213
        $containerMock = m::mock(StrategyContainer::class);
214
        $result = $fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
215
216
        $this->assertSame($result, $file);
217
    }
218
219
    /**
220
     * @expectedException \InvalidArgumentException
221
     */
222
    public function testMiddlewareIsChecked()
223
    {
224
        new File($this->nodesFactoryMock, [new \stdClass()]);
0 ignored issues
show
Documentation introduced by
array(new \stdClass()) is of type array<integer,object<std...0":"object<stdClass>"}>, but the function expects a array<integer,object<php...Middleware\Middleware>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
225
    }
226
227
    /**
228
     * @covers ::create
229
     */
230
    public function testFileDocBlockWithNamespace()
231
    {
232
        $docBlockNode = new DocBlockNode('');
233
        $docBlockDescriptor = new DocBlockDescriptor('');
234
235
        $namespaceNode = new NamespaceNode(new Name('mySpace'));
236
        $namespaceNode->fqsen = new Fqsen('\mySpace');
0 ignored issues
show
Bug introduced by
The property fqsen does not seem to exist in PhpParser\Node\Stmt\Namespace_.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
237
        $namespaceNode->setAttribute('comments', [ $docBlockNode ]);
238
239
        $this->nodesFactoryMock->shouldReceive('create')
240
            ->with(file_get_contents(__FILE__))
241
            ->andReturn([ $namespaceNode ]);
242
243
        $containerMock = m::mock(StrategyContainer::class);
244
245
        $containerMock->shouldReceive('findMatching->create')
246
            ->with($docBlockNode, $containerMock, m::any())
247
            ->andReturn($docBlockDescriptor);
248
249
        /** @var FileElement $file */
250
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
251
252
        $this->assertSame($docBlockDescriptor, $file->getDocBlock());
253
    }
254
255
    /**
256
     * @covers ::create
257
     */
258
    public function testFileDocBlockWithClass()
259
    {
260
        $docBlockNode = new DocBlockNode('');
261
        $docBlockDescriptor = new DocBlockDescriptor('');
262
263
        $classNode = new ClassNode('myClass');
264
        $classNode->setAttribute('comments', [ $docBlockNode, new DocBlockNode('') ]);
265
266
        $this->nodesFactoryMock->shouldReceive('create')
267
            ->with(file_get_contents(__FILE__))
268
            ->andReturn([ $classNode ]);
269
270
        $containerMock = m::mock(StrategyContainer::class);
271
272
        $containerMock->shouldReceive('findMatching->create')
273
            ->once()
274
            ->with($classNode, $containerMock, m::any())
275
            ->andReturn(new ClassElement(new Fqsen('\myClass')));
276
277
        $containerMock->shouldReceive('findMatching->create')
278
            ->with($docBlockNode, $containerMock, m::any())
279
            ->andReturn($docBlockDescriptor);
280
281
        /** @var FileElement $file */
282
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
283
284
        $this->assertSame($docBlockDescriptor, $file->getDocBlock());
285
    }
286
287
    /**
288
     * @covers ::create
289
     */
290
    public function testFileDocBlockWithComments()
291
    {
292
        $docBlockNode = new DocBlockNode('');
293
        $docBlockDescriptor = new DocBlockDescriptor('');
294
295
        $namespaceNode = new NamespaceNode(new Name('mySpace'));
296
        $namespaceNode->fqsen = new Fqsen('\mySpace');
0 ignored issues
show
Bug introduced by
The property fqsen does not seem to exist in PhpParser\Node\Stmt\Namespace_.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
297
        $namespaceNode->setAttribute('comments', [ new CommentNode('@codingStandardsIgnoreStart'), $docBlockNode ]);
298
299
        $this->nodesFactoryMock->shouldReceive('create')
300
            ->with(file_get_contents(__FILE__))
301
            ->andReturn([ $namespaceNode ]);
302
303
        $containerMock = m::mock(StrategyContainer::class);
304
305
        $containerMock->shouldReceive('findMatching->create')
306
            ->with($docBlockNode, $containerMock, m::any())
307
            ->andReturn($docBlockDescriptor);
308
309
        /** @var FileElement $file */
310
        $file = $this->fixture->create(new SourceFile\LocalFile(__FILE__), $containerMock);
311
312
        $this->assertSame($docBlockDescriptor, $file->getDocBlock());
313
    }
314
}
315