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'); |
|
|
|
|
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]); |
|
|
|
|
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()]); |
|
|
|
|
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'); |
|
|
|
|
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'); |
|
|
|
|
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
|
|
|
|
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.