Completed
Push — develop ( e58221...7a35e1 )
by Jaap
08:17 queued 01:05
created

testGetResponseReturnsReturnType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * phpDocumentor
4
 *
5
 * PHP Version 5.3
6
 *
7
 * @copyright 2010-2013 Mike van Riel / Naenius (http://www.naenius.com)
8
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
9
 * @link      http://phpdoc.org
10
 */
11
12
namespace phpDocumentor\Descriptor;
13
14
use \Mockery as m;
15
use phpDocumentor\Descriptor\Tag\AuthorDescriptor;
16
use phpDocumentor\Descriptor\Tag\ReturnDescriptor;
17
use phpDocumentor\Descriptor\Tag\VersionDescriptor;
18
use phpDocumentor\Reflection\DocBlock\Tags\Return_;
19
use phpDocumentor\Reflection\Types\String_;
20
21
/**
22
 * Tests the functionality for the MethodDescriptor class.
23
 *
24
 * @coversDefaultClass \phpDocumentor\Descriptor\MethodDescriptor
25
 * @covers ::<private>
26
 * @covers ::<protected>
27
 */
28
class MethodDescriptorTest extends \Mockery\Adapter\Phpunit\MockeryTestCase
29
{
30
    /** @var MethodDescriptor $fixture */
31
    protected $fixture;
32
33
    /**
34
     * Creates a new (empty) fixture object.
35
     */
36
    protected function setUp()
37
    {
38
        $this->fixture = new MethodDescriptor();
39
        $this->fixture->setName('method');
40
    }
41
42
    /**
43
     * Tests whether all collection objects are properly initialized.
44
     *
45
     * @covers ::__construct
46
     */
47
    public function testInitialize()
48
    {
49
        $this->assertAttributeInstanceOf(Collection::class, 'arguments', $this->fixture);
50
    }
51
52
    /**
53
     * @covers ::setArguments
54
     * @covers ::getArguments
55
     */
56
    public function testSettingAndGettingArguments()
57
    {
58
        $this->assertInstanceOf(Collection::class, $this->fixture->getArguments());
59
60
        $mock = m::mock(Collection::class);
61
        $mock->shouldReceive('getIterator')->andReturn(new \ArrayIterator(array()));
0 ignored issues
show
Bug introduced by
The method andReturn does only exist in Mockery\ExpectationInterface, but not in Mockery\HigherOrderMessage.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
62
63
        $this->fixture->setArguments($mock);
64
65
        $this->assertSame($mock, $this->fixture->getArguments());
66
    }
67
68
    /**
69
     * @covers ::isAbstract
70
     * @covers ::setAbstract
71
     */
72
    public function testSettingAndGettingWhetherMethodIsAbstract()
73
    {
74
        $this->assertFalse($this->fixture->isAbstract());
75
76
        $this->fixture->setAbstract(true);
77
78
        $this->assertTrue($this->fixture->isAbstract());
79
    }
80
81
    /**
82
     * @covers ::isFinal
83
     * @covers ::setFinal
84
     */
85
    public function testSettingAndGettingWhetherMethodIsFinal()
86
    {
87
        $this->assertFalse($this->fixture->isFinal());
88
89
        $this->fixture->setFinal(true);
90
91
        $this->assertTrue($this->fixture->isFinal());
92
    }
93
94
    /**
95
     * @covers ::isStatic
96
     * @covers ::setStatic
97
     */
98
    public function testSettingAndGettingWhetherMethodIsStatic()
99
    {
100
        $this->assertFalse($this->fixture->isStatic());
101
102
        $this->fixture->setStatic(true);
103
104
        $this->assertTrue($this->fixture->isStatic());
105
    }
106
107
    /**
108
     * @covers ::getVisibility
109
     * @covers ::setVisibility
110
     */
111
    public function testSettingAndGettingVisibility()
112
    {
113
        $this->assertEquals('public', $this->fixture->getVisibility());
114
115
        $this->fixture->setVisibility('private');
116
117
        $this->assertEquals('private', $this->fixture->getVisibility());
118
    }
119
120
    /**
121
     * @covers ::getResponse
122
     */
123
    public function testRetrieveReturnTagForResponse()
124
    {
125
        $mock = new ReturnDescriptor('return');
126
        $mock->setTypes(new String_());
127
128
        $this->assertNull($this->fixture->getResponse()->getTypes());
129
130
        $this->fixture->getTags()->set('return', new Collection(array($mock)));
131
132
        $this->assertSame($mock, $this->fixture->getResponse());
133
    }
134
135
    /**
136
     * @covers ::setReturnType
137
     * @covers ::getResponse
138
     */
139
    public function testGetResponseReturnsReturnType()
140
    {
141
        $returnType = new String_();
142
        $this->fixture->setReturnType($returnType);
143
144
        $this->assertSame($returnType, $this->fixture->getResponse()->getTypes());
145
    }
146
147
    /**
148
     * @covers ::getFile
149
     */
150
    public function testRetrieveFileAssociatedWithAMethod()
151
    {
152
        // Arrange
153
        $file = $this->whenFixtureIsRelatedToAClassWithFile();
154
155
        // Act
156
        $result = $this->fixture->getFile();
157
158
        // Assert
159
        $this->assertAttributeSame(null, 'fileDescriptor', $this->fixture);
160
        $this->assertSame($file, $result);
161
    }
162
163
    /**
164
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getSummary
165
     */
166
    public function testSummaryInheritsWhenNoneIsPresent()
167
    {
168
        // Arrange
169
        $summary = 'This is a summary';
170
        $this->fixture->setSummary(null);
171
        $parentMethod = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
172
        $parentMethod->setSummary($summary);
173
174
        // Act
175
        $result = $this->fixture->getSummary();
176
177
        // Assert
178
        $this->assertSame($summary, $result);
179
    }
180
181
    /**
182
     * @covers ::getSummary
183
     */
184
    public function testSummaryInheritsFromImplementedInterfaceWhenNoneIsPresent()
185
    {
186
        // Arrange
187
        $summary = 'This is a summary';
188
        $this->fixture->setSummary(null);
189
        $parentMethod = $this->whenFixtureHasMethodInImplementedInterfaceWithSameName($this->fixture->getName());
190
        $parentMethod->setSummary($summary);
191
192
        // Act
193
        $result = $this->fixture->getSummary();
194
195
        // Assert
196
        $this->assertSame($summary, $result);
197
    }
198
199
    /**
200
     * @covers ::getDescription
201
     */
202
    public function testDescriptionInheritsWhenNoneIsPresent()
203
    {
204
        // Arrange
205
        $description = 'This is a description';
206
        $this->fixture->setDescription(null);
207
        $parentMethod = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
208
        $parentMethod->setDescription($description);
209
210
        // Act
211
        $result = $this->fixture->getDescription();
212
213
        // Assert
214
        $this->assertSame($description, $result);
215
    }
216
217
    /**
218
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getDescription
219
     */
220
    public function testDescriptionInheritsWhenInheritDocIsPresent()
221
    {
222
        // Arrange
223
        $description = 'This is a description';
224
        $this->fixture->setDescription('{@inheritDoc}');
225
        $parentMethod = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
226
        $parentMethod->setDescription($description);
227
228
        // Act
229
        $result = $this->fixture->getDescription();
230
231
        // Assert
232
        $this->assertSame($description, $result);
233
    }
234
235
    /**
236
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getDescription
237
     */
238
    public function testDescriptionIsAugmentedWhenInheritDocInlineTagIsPresent()
239
    {
240
        // Arrange
241
        $description = 'This is a description';
242
        $this->fixture->setDescription('Original description {@inheritDoc}');
243
        $parentMethod = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
244
        $parentMethod->setDescription($description);
245
246
        // Act
247
        $result = $this->fixture->getDescription();
248
249
        // Assert
250
        $this->assertSame('Original description ' . $description, $result);
251
    }
252
253
    /**
254
     * @covers ::getReturn
255
     */
256
    public function testReturnTagsInheritWhenNoneArePresent()
257
    {
258
        // Arrange
259
        $returnTagDescriptor = new AuthorDescriptor('return');
260
        $returnCollection = new Collection(array($returnTagDescriptor));
261
        $this->fixture->getTags()->clear();
262
        $parentProperty = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
263
        $parentProperty->getTags()->set('return', $returnCollection);
264
265
        // Act
266
        $result = $this->fixture->getReturn();
267
268
        // Assert
269
        $this->assertSame($returnCollection, $result);
270
    }
271
272
    /**
273
     * @covers ::getParam
274
     */
275
    public function testParamTagsInheritWhenNoneArePresent()
276
    {
277
        // Arrange
278
        $paramTagDescriptor = new AuthorDescriptor('param');
279
        $paramCollection = new Collection(array($paramTagDescriptor));
280
        $this->fixture->getTags()->clear();
281
        $parentProperty = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
282
        $parentProperty->getTags()->set('param', $paramCollection);
283
284
        // Act
285
        $result = $this->fixture->getParam();
286
287
        // Assert
288
        $this->assertSame($paramCollection, $result);
289
    }
290
291
    /**
292
     * @covers ::getAuthor
293
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getAuthor
294
     */
295
    public function testAuthorTagsInheritWhenNoneArePresent()
296
    {
297
        // Arrange
298
        $authorTagDescriptor = new AuthorDescriptor('author');
299
        $authorCollection = new Collection(array($authorTagDescriptor));
300
        $this->fixture->getTags()->clear();
301
        $parentProperty = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
302
        $parentProperty->getTags()->set('author', $authorCollection);
303
304
        // Act
305
        $result = $this->fixture->getAuthor();
306
307
        // Assert
308
        $this->assertSame($authorCollection, $result);
309
    }
310
311
    /**
312
     * @covers ::getVersion
313
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getVersion
314
     */
315
    public function testVersionTagsInheritWhenNoneArePresent()
316
    {
317
        // Arrange
318
        $versionTagDescriptor = new VersionDescriptor('version');
319
        $versionCollection = new Collection(array($versionTagDescriptor));
320
        $this->fixture->getTags()->clear();
321
        $parentProperty = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
322
        $parentProperty->getTags()->set('version', $versionCollection);
323
324
        // Act
325
        $result = $this->fixture->getVersion();
326
327
        // Assert
328
        $this->assertSame($versionCollection, $result);
329
    }
330
331
    /**
332
     * @covers ::getCopyright
333
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getCopyright
334
     */
335
    public function testCopyrightTagsInheritWhenNoneArePresent()
336
    {
337
        // Arrange
338
        $copyrightTagDescriptor = new TagDescriptor('copyright');
339
        $copyrightCollection = new Collection(array($copyrightTagDescriptor));
340
        $this->fixture->getTags()->clear();
341
        $parentProperty = $this->whenFixtureHasMethodInParentClassWithSameName($this->fixture->getName());
342
        $parentProperty->getTags()->set('copyright', $copyrightCollection);
343
344
        // Act
345
        $result = $this->fixture->getCopyright();
346
347
        // Assert
348
        $this->assertSame($copyrightCollection, $result);
349
    }
350
351
    /**
352
     * Sets up mocks as such that the fixture has a file.
353
     *
354
     * @return m\MockInterface|FileDescriptor
355
     */
356
    protected function whenFixtureIsDirectlyRelatedToAFile()
357
    {
358
        $file = m::mock(FileDescriptor::class);
359
        $this->fixture->setFile($file);
360
        return $file;
361
    }
362
363
    /**
364
     * Sets up mocks as such that the fixture has a parent class, with a file.
365
     *
366
     * @return m\MockInterface|FileDescriptor
367
     */
368
    protected function whenFixtureIsRelatedToAClassWithFile()
369
    {
370
        $file = m::mock(FileDescriptor::class);
371
        $parent = m::mock(ClassDescriptor::class);
372
        $parent->shouldReceive('getFile')->andReturn($file);
0 ignored issues
show
Bug introduced by
The method andReturn does only exist in Mockery\ExpectationInterface, but not in Mockery\HigherOrderMessage.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
373
        $parent->shouldReceive('getFullyQualifiedStructuralElementName')->andReturn('Class1');
374
        $this->fixture->setParent($parent);
375
376
        return $file;
377
    }
378
379
    /**
380
     * @param string $name The name of the current method.
381
     *
382
     * @return MethodDescriptor
383
     */
384
    protected function whenFixtureHasMethodInParentClassWithSameName($name): MethodDescriptor
385
    {
386
        $result = new MethodDescriptor;
387
        $result->setName($name);
388
389
        $parent = new ClassDescriptor();
390
        $parent->getMethods()->set($name, $result);
391
392
        $class  = new ClassDescriptor();
393
        $class->setParent($parent);
394
395
        $this->fixture->setParent($class);
396
397
        return $result;
398
    }
399
400
    /**
401
     * @param string $name The name of the current method.
402
     *
403
     * @return MethodDescriptor
404
     */
405
    protected function whenFixtureHasMethodInImplementedInterfaceWithSameName($name): MethodDescriptor
406
    {
407
        $result = new MethodDescriptor;
408
        $result->setName($name);
409
410
        $parent = new InterfaceDescriptor();
411
        $parent->getMethods()->set($name, $result);
412
413
        $class  = new ClassDescriptor();
414
        $class->getInterfaces()->set('Implemented', $parent);
415
416
        $this->fixture->setParent($class);
417
418
        return $result;
419
    }
420
}
421