ClassDescriptorTest   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 511
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 9
dl 0
loc 511
rs 10
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 4 1
A testInitialize() 0 7 1
A testSettingAndGettingAParent() 0 10 1
A testSettingNoParent() 0 8 1
A testSettingAndGettingInterfaces() 0 10 1
A testSettingAndGettingConstants() 0 10 1
A testSettingAndGettingProperties() 0 10 1
A testSettingAndGettingMethods() 0 10 1
A testRetrievingInheritedMethodsReturnsEmptyCollectionWithoutParent() 0 6 1
A testRetrievingInheritedMethodsReturnsCollectionWithParent() 0 14 1
A testRetrievingInheritedMethodsReturnsTraitMethods() 0 15 1
A testRetrievingInheritedMethodsDoesNotCrashWhenUsedTraitIsNotInProject() 0 14 1
A testSettingAndGettingWhetherClassIsAbstract() 0 8 1
A testSettingAndGettingWhetherClassIsFinal() 0 8 1
A testGetMagicPropertiesUsingPropertyTags() 0 32 1
A testGetInheritedConstantsNoParent() 0 8 1
A testGetInheritedConstantsWithClassDescriptorParent() 0 16 1
A testGetInheritedPropertiesNoParent() 0 8 1
A testGetInheritedPropertiesWithClassDescriptorParent() 0 16 1
A testRetrievingInheritedPropertiesReturnsTraitProperties() 0 15 1
A testRetrievingInheritedPropertiesDoesNotCrashWhenUsedTraitIsNotInProject() 0 14 1
A testGetMagicMethods() 0 38 1
A provideMagicMethodProperties() 0 9 1
A testSetPackage() 0 47 1
A testCall() 0 5 1
A testSummaryInheritsWhenNoneIsPresent() 0 14 1
A testDescriptionInheritsWhenNoneIsPresent() 0 14 1
A whenFixtureHasParentClass() 0 7 1
1
<?php
2
/**
3
 * phpDocumentor
4
 *
5
 * PHP Version 5.3
6
 *
7
 * @copyright 2010-2018 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\ReturnDescriptor;
16
use phpDocumentor\Reflection\Types\String_;
17
18
/**
19
 * Tests the functionality for the ClassDescriptor class.
20
 */
21
class ClassDescriptorTest extends \Mockery\Adapter\Phpunit\MockeryTestCase
22
{
23
    /** @var ClassDescriptor $fixture */
24
    protected $fixture;
25
26
    /**
27
     * Creates a new (emoty) fixture object.
28
     */
29
    protected function setUp()
30
    {
31
        $this->fixture = new ClassDescriptor();
32
    }
33
34
    /**
35
     * Tests whether all collection objects are properly initialized.
36
     *
37
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::__construct
38
     */
39
    public function testInitialize()
40
    {
41
        $this->assertAttributeInstanceOf('phpDocumentor\Descriptor\Collection', 'implements', $this->fixture);
42
        $this->assertAttributeInstanceOf('phpDocumentor\Descriptor\Collection', 'constants', $this->fixture);
43
        $this->assertAttributeInstanceOf('phpDocumentor\Descriptor\Collection', 'properties', $this->fixture);
44
        $this->assertAttributeInstanceOf('phpDocumentor\Descriptor\Collection', 'methods', $this->fixture);
45
    }
46
47
    /**
48
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setParent
49
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getParent
50
     */
51
    public function testSettingAndGettingAParent()
52
    {
53
        $this->assertNull($this->fixture->getParent());
54
55
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
56
57
        $this->fixture->setParent($mock);
58
59
        $this->assertSame($mock, $this->fixture->getParent());
60
    }
61
62
    /**
63
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setParent
64
     */
65
    public function testSettingNoParent()
66
    {
67
        $mock = null;
68
69
        $this->fixture->setParent($mock);
0 ignored issues
show
Documentation introduced by Mike van Riel
$mock is of type null, but the function expects a object<phpDocumentor\Des...tor\DescriptorAbstract>.

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...
70
71
        $this->assertSame($mock, $this->fixture->getParent());
72
    }
73
74
    /**
75
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setInterfaces
76
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInterfaces
77
     */
78
    public function testSettingAndGettingInterfaces()
79
    {
80
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $this->fixture->getInterfaces());
81
82
        $mock = m::mock('phpDocumentor\Descriptor\Collection');
83
84
        $this->fixture->setInterfaces($mock);
85
86
        $this->assertSame($mock, $this->fixture->getInterfaces());
87
    }
88
89
    /**
90
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setConstants
91
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getConstants
92
     */
93
    public function testSettingAndGettingConstants()
94
    {
95
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $this->fixture->getConstants());
96
97
        $mock = m::mock('phpDocumentor\Descriptor\Collection');
98
99
        $this->fixture->setConstants($mock);
100
101
        $this->assertSame($mock, $this->fixture->getConstants());
102
    }
103
104
    /**
105
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setProperties
106
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getProperties
107
     */
108
    public function testSettingAndGettingProperties()
109
    {
110
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $this->fixture->getProperties());
111
112
        $mock = m::mock('phpDocumentor\Descriptor\Collection');
113
114
        $this->fixture->setProperties($mock);
115
116
        $this->assertSame($mock, $this->fixture->getProperties());
117
    }
118
119
    /**
120
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setMethods
121
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getMethods
122
     */
123
    public function testSettingAndGettingMethods()
124
    {
125
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $this->fixture->getMethods());
126
127
        $mock = m::mock('phpDocumentor\Descriptor\Collection');
128
129
        $this->fixture->setMethods($mock);
130
131
        $this->assertSame($mock, $this->fixture->getMethods());
132
    }
133
134
    /**
135
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedMethods
136
     */
137
    public function testRetrievingInheritedMethodsReturnsEmptyCollectionWithoutParent()
138
    {
139
        $inheritedMethods = $this->fixture->getInheritedMethods();
140
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $inheritedMethods);
141
        $this->assertCount(0, $inheritedMethods);
142
    }
143
144
    /**
145
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedMethods
146
     */
147
    public function testRetrievingInheritedMethodsReturnsCollectionWithParent()
148
    {
149
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
150
        $mock->shouldReceive('getMethods')->andReturn(new Collection(['methods']));
0 ignored issues
show
Bug introduced by Ceeram
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...
151
        $mock->shouldReceive('getInheritedMethods')->andReturn(new Collection(['inherited']));
152
153
        $this->fixture->setParent($mock);
154
        $result = $this->fixture->getInheritedMethods();
155
156
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $result);
157
158
        $expected = ['methods', 'inherited'];
159
        $this->assertSame($expected, $result->getAll());
160
    }
161
162
    /**
163
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedMethods
164
     */
165
    public function testRetrievingInheritedMethodsReturnsTraitMethods()
166
    {
167
        // Arrange
168
        $expected = ['methods'];
169
        $traitDescriptorMock = m::mock('phpDocumentor\Descriptor\TraitDescriptor');
170
        $traitDescriptorMock->shouldReceive('getMethods')->andReturn(new Collection(['methods']));
0 ignored issues
show
Bug introduced by Mike van Riel
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...
171
        $this->fixture->setUsedTraits(new Collection([$traitDescriptorMock]));
172
173
        // Act
174
        $result = $this->fixture->getInheritedMethods();
175
176
        // Assert
177
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $result);
178
        $this->assertSame($expected, $result->getAll());
179
    }
180
181
    /**
182
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedMethods
183
     * @ticket https://github.com/phpDocumentor/phpDocumentor2/issues/1307
184
     */
185
    public function testRetrievingInheritedMethodsDoesNotCrashWhenUsedTraitIsNotInProject()
186
    {
187
        // Arrange
188
        $expected = [];
189
        // unknown traits are not converted to TraitDescriptors but kept as strings
190
        $this->fixture->setUsedTraits(new Collection(['unknownTrait']));
191
192
        // Act
193
        $result = $this->fixture->getInheritedMethods();
194
195
        // Assert
196
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $result);
197
        $this->assertSame($expected, $result->getAll());
198
    }
199
200
    /**
201
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::isAbstract
202
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setAbstract
203
     */
204
    public function testSettingAndGettingWhetherClassIsAbstract()
205
    {
206
        $this->assertFalse($this->fixture->isAbstract());
207
208
        $this->fixture->setAbstract(true);
209
210
        $this->assertTrue($this->fixture->isAbstract());
211
    }
212
213
    /**
214
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::isFinal
215
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setFinal
216
     */
217
    public function testSettingAndGettingWhetherClassIsFinal()
218
    {
219
        $this->assertFalse($this->fixture->isFinal());
220
221
        $this->fixture->setFinal(true);
222
223
        $this->assertTrue($this->fixture->isFinal());
224
    }
225
226
    /**
227
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getMagicProperties
228
     */
229
    public function testGetMagicPropertiesUsingPropertyTags()
230
    {
231
        $variableName = 'variableName';
232
        $description = 'description';
233
        $types = new Collection(['string']);
0 ignored issues
show
Unused Code introduced by Jaapio
$types is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
234
235
        $this->assertEquals(0, $this->fixture->getMagicProperties()->count());
236
237
        $propertyMock = m::mock('phpDocumentor\Descriptor\Tag\PropertyDescriptor');
238
        $propertyMock->shouldReceive('getVariableName')->andReturn($variableName);
0 ignored issues
show
Bug introduced by Mike van Riel
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...
239
        $propertyMock->shouldReceive('getDescription')->andReturn($description);
240
        $propertyMock->shouldReceive('getType')->andReturn(new String_());
241
242
        $this->fixture->getTags()->get('property', new Collection())->add($propertyMock);
243
244
        $magicProperties = $this->fixture->getMagicProperties();
245
246
        $this->assertCount(1, $magicProperties);
247
248
        /** @var PropertyDescriptor $magicProperty */
249
        $magicProperty = current($magicProperties->getAll());
250
        $this->assertEquals($variableName, $magicProperty->getName());
251
        $this->assertEquals($description, $magicProperty->getDescription());
252
        $this->assertEquals([new String_()], $magicProperty->getTypes());
253
254
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
255
        $mock->shouldReceive('getMagicProperties')->andReturn(new Collection(['magicProperties']));
256
        $this->fixture->setParent($mock);
257
258
        $magicProperties = $this->fixture->getMagicProperties();
259
        $this->assertCount(2, $magicProperties);
260
    }
261
262
    /**
263
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedConstants
264
     */
265
    public function testGetInheritedConstantsNoParent()
266
    {
267
        $descriptor = new ClassDescriptor();
268
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $descriptor->getInheritedConstants());
269
270
        $descriptor->setParent(new \stdClass());
0 ignored issues
show
Documentation introduced by Ceeram
new \stdClass() is of type object<stdClass>, but the function expects a object<phpDocumentor\Des...tor\DescriptorAbstract>.

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...
271
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $descriptor->getInheritedConstants());
272
    }
273
274
    /**
275
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedConstants
276
     */
277
    public function testGetInheritedConstantsWithClassDescriptorParent()
278
    {
279
        $collectionMock = m::mock('phpDocumentor\Descriptor\Collection');
280
        $collectionMock->shouldReceive('get');
281
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
282
        $mock->shouldReceive('getConstants')->andReturn(new Collection(['constants']));
0 ignored issues
show
Bug introduced by Ceeram
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...
283
        $mock->shouldReceive('getInheritedConstants')->andReturn(new Collection(['inherited']));
284
285
        $this->fixture->setParent($mock);
286
        $result = $this->fixture->getInheritedConstants();
287
288
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $result);
289
290
        $expected = ['constants', 'inherited'];
291
        $this->assertSame($expected, $result->getAll());
292
    }
293
294
    /**
295
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedProperties
296
     */
297
    public function testGetInheritedPropertiesNoParent()
298
    {
299
        $descriptor = new ClassDescriptor();
300
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $descriptor->getInheritedProperties());
301
302
        $descriptor->setParent(new \stdClass());
0 ignored issues
show
Documentation introduced by Ceeram
new \stdClass() is of type object<stdClass>, but the function expects a object<phpDocumentor\Des...tor\DescriptorAbstract>.

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...
303
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $descriptor->getInheritedProperties());
304
    }
305
306
    /**
307
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedProperties
308
     */
309
    public function testGetInheritedPropertiesWithClassDescriptorParent()
310
    {
311
        $collectionMock = m::mock('phpDocumentor\Descriptor\Collection');
312
        $collectionMock->shouldReceive('get');
313
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
314
        $mock->shouldReceive('getProperties')->andReturn(new Collection(['properties']));
0 ignored issues
show
Bug introduced by Ceeram
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...
315
        $mock->shouldReceive('getInheritedProperties')->andReturn(new Collection(['inherited']));
316
317
        $this->fixture->setParent($mock);
318
        $result = $this->fixture->getInheritedProperties();
319
320
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $result);
321
322
        $expected = ['properties', 'inherited'];
323
        $this->assertSame($expected, $result->getAll());
324
    }
325
326
    /**
327
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedProperties
328
     */
329
    public function testRetrievingInheritedPropertiesReturnsTraitProperties()
330
    {
331
        // Arrange
332
        $expected = ['properties'];
333
        $traitDescriptorMock = m::mock('phpDocumentor\Descriptor\TraitDescriptor');
334
        $traitDescriptorMock->shouldReceive('getProperties')->andReturn(new Collection(['properties']));
0 ignored issues
show
Bug introduced by Mike van Riel
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...
335
        $this->fixture->setUsedTraits(new Collection([$traitDescriptorMock]));
336
337
        // Act
338
        $result = $this->fixture->getInheritedProperties();
339
340
        // Assert
341
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $result);
342
        $this->assertSame($expected, $result->getAll());
343
    }
344
345
    /**
346
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getInheritedProperties
347
     * @ticket https://github.com/phpDocumentor/phpDocumentor2/issues/1307
348
     */
349
    public function testRetrievingInheritedPropertiesDoesNotCrashWhenUsedTraitIsNotInProject()
350
    {
351
        // Arrange
352
        $expected = [];
353
        // unknown traits are not converted to TraitDescriptors but kept as strings
354
        $this->fixture->setUsedTraits(new Collection(['unknownTrait']));
355
356
        // Act
357
        $result = $this->fixture->getInheritedProperties();
358
359
        // Assert
360
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $result);
361
        $this->assertSame($expected, $result->getAll());
362
    }
363
364
    /**
365
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::getMagicMethods
366
     * @dataProvider provideMagicMethodProperties
367
     * @param bool $isStatic
368
     */
369
    public function testGetMagicMethods($isStatic)
370
    {
371
        $methodName = 'methodName';
372
        $description = 'description';
373
        $response = new ReturnDescriptor('return');
374
        $response->setType(new String_());
375
        $arguments = m::mock('phpDocumentor\Descriptor\Tag\ArgumentDescriptor');
376
        $arguments->shouldReceive('setMethod');
377
378
        $this->assertEquals(0, $this->fixture->getMagicMethods()->count());
379
380
        $methodMock = m::mock('phpDocumentor\Descriptor\Tag\MethodDescriptor');
381
        $methodMock->shouldReceive('getMethodName')->andReturn($methodName);
0 ignored issues
show
Bug introduced by Ceeram
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...
382
        $methodMock->shouldReceive('getDescription')->andReturn($description);
383
        $methodMock->shouldReceive('getResponse')->andReturn($response);
384
        $methodMock->shouldReceive('getArguments')->andReturn($arguments);
385
        $methodMock->shouldReceive('isStatic')->andReturn($isStatic);
386
387
        $this->fixture->getTags()->get('method', new Collection())->add($methodMock);
388
389
        $magicMethods = $this->fixture->getMagicMethods();
390
391
        $this->assertCount(1, $magicMethods);
392
393
        /** @var MethodDescriptor $magicMethod */
394
        $magicMethod = current($magicMethods->getAll());
395
        $this->assertEquals($methodName, $magicMethod->getName());
396
        $this->assertEquals($description, $magicMethod->getDescription());
397
        $this->assertEquals($response, $magicMethod->getResponse());
398
        $this->assertEquals($isStatic, $magicMethod->isStatic());
399
400
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
401
        $mock->shouldReceive('getMagicMethods')->andReturn(new Collection(['magicMethods']));
402
        $this->fixture->setParent($mock);
403
404
        $magicMethods = $this->fixture->getMagicMethods();
405
        $this->assertCount(2, $magicMethods);
406
    }
407
408
    /**
409
     * Provider to test different properties for a class magic method
410
     * (provides isStatic)
411
     * @return bool[][]
412
     */
413
    public function provideMagicMethodProperties()
414
    {
415
        return [
416
            // Instance magic method (default)
417
            [false],
418
            // Static magic method
419
            [true],
420
        ];
421
    }
422
423
    /**
424
     * @covers \phpDocumentor\Descriptor\ClassDescriptor::setPackage
425
     */
426
    public function testSetPackage()
427
    {
428
        $package = 'Package';
429
430
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
431
        $mock->shouldDeferMissing();
0 ignored issues
show
Deprecated Code introduced by Ceeram
The method Mockery\MockInterface::shouldDeferMissing() has been deprecated with message: 2.0.0 Please use makePartial() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
432
433
        $constantDescriptor = m::mock('phpDocumentor\Descriptor\ConstantDescriptor');
434
435
        /** @var m\mockInterface|Collection */
436
        $constantCollection = m::mock('phpDocumentor\Descriptor\Collection');
437
        $constantCollection->shouldDeferMissing();
0 ignored issues
show
Deprecated Code introduced by Ceeram
The method Mockery\MockInterface::shouldDeferMissing() has been deprecated with message: 2.0.0 Please use makePartial() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
438
        $constantCollection->add($constantDescriptor);
0 ignored issues
show
Bug introduced by Ceeram
The method add() does not seem to exist on object<Mockery\MockInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
439
440
        $propertyDescriptor = m::mock('phpDocumentor\Descriptor\PropertyDescriptor');
441
442
        /** @var m\mockInterface|Collection */
443
        $propertyCollection = m::mock('phpDocumentor\Descriptor\Collection');
444
        $propertyCollection->shouldDeferMissing();
0 ignored issues
show
Deprecated Code introduced by Ceeram
The method Mockery\MockInterface::shouldDeferMissing() has been deprecated with message: 2.0.0 Please use makePartial() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
445
        $propertyCollection->add($propertyDescriptor);
0 ignored issues
show
Bug introduced by Ceeram
The method add() does not seem to exist on object<Mockery\MockInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
446
447
        $methodDescriptor = m::mock('phpDocumentor\Descriptor\MethodDescriptor');
448
449
        /** @var m\mockInterface|Collection */
450
        $methodCollection = m::mock('phpDocumentor\Descriptor\Collection');
451
        $methodCollection->shouldDeferMissing();
0 ignored issues
show
Deprecated Code introduced by Ceeram
The method Mockery\MockInterface::shouldDeferMissing() has been deprecated with message: 2.0.0 Please use makePartial() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
452
        $methodCollection->add($methodDescriptor);
0 ignored issues
show
Bug introduced by Ceeram
The method add() does not seem to exist on object<Mockery\MockInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
453
454
        /** @var m\mockInterface|ClassDescriptor */
455
        $mock = m::mock('phpDocumentor\Descriptor\ClassDescriptor');
456
        $mock->shouldDeferMissing();
0 ignored issues
show
Deprecated Code introduced by Ceeram
The method Mockery\MockInterface::shouldDeferMissing() has been deprecated with message: 2.0.0 Please use makePartial() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
457
        $mock->shouldReceive('getProperties')->andReturn($propertyCollection);
0 ignored issues
show
Bug introduced by Ceeram
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...
458
459
        $mock->shouldReceive('getConstants')->andReturn($constantCollection);
460
        $constantDescriptor->shouldReceive('setPackage')->with($package);
461
462
        $mock->shouldReceive('getProperties')->andReturn($propertyCollection);
463
        $propertyDescriptor->shouldReceive('setPackage')->with($package);
464
465
        $mock->shouldReceive('getMethods')->andReturn($methodCollection);
466
        $methodDescriptor->shouldReceive('setPackage')->with($package);
467
468
        /** @var ClassDescriptor */
469
        $mock->setPackage($package);
0 ignored issues
show
Bug introduced by Ceeram
The method setPackage() does not seem to exist on object<Mockery\MockInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
470
471
        $this->assertTrue(true);
472
    }
473
474
    /**
475
     * Test to cover magic method of parent abstract class
476
     *
477
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::__call
478
     */
479
    public function testCall()
480
    {
481
        $this->assertNull($this->fixture->__call('notexisting', []));
482
        $this->assertInstanceOf('phpDocumentor\Descriptor\Collection', $this->fixture->__call('getNotexisting', []));
483
    }
484
485
    /**
486
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getSummary
487
     */
488
    public function testSummaryInheritsWhenNoneIsPresent()
489
    {
490
        // Arrange
491
        $summary = 'This is a summary';
492
        $this->fixture->setSummary(null);
493
        $parentInterface = $this->whenFixtureHasParentClass();
494
        $parentInterface->setSummary($summary);
495
496
        // Act
497
        $result = $this->fixture->getSummary();
498
499
        // Assert
500
        $this->assertSame($summary, $result);
501
    }
502
503
    /**
504
     * @covers \phpDocumentor\Descriptor\DescriptorAbstract::getDescription
505
     */
506
    public function testDescriptionInheritsWhenNoneIsPresent()
507
    {
508
        // Arrange
509
        $description = 'This is a description';
510
        $this->fixture->setDescription(null);
511
        $parentInterface = $this->whenFixtureHasParentClass();
512
        $parentInterface->setDescription($description);
513
514
        // Act
515
        $result = $this->fixture->getDescription();
516
517
        // Assert
518
        $this->assertSame($description, $result);
519
    }
520
521
    /**
522
     * @return ClassDescriptor
523
     */
524
    protected function whenFixtureHasParentClass()
525
    {
526
        $class = new ClassDescriptor();
527
        $this->fixture->setParent($class);
528
529
        return $class;
530
    }
531
}
532