Completed
Push — develop ( 4b49c4...89d32a )
by Jaap
09:06 queued 05:30
created

testWhetherTypesAreAddedWhenPresentAndTypeIsCompound()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 0
dl 0
loc 21
rs 9.3142
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\Plugin\Core\Transformer\Writer\Xml;
13
14
use Mockery as m;
15
use phpDocumentor\Descriptor\TagDescriptor;
16
use phpDocumentor\Reflection\Fqsen;
17
use phpDocumentor\Reflection\Types\Compound;
18
use phpDocumentor\Reflection\Types\Integer;
19
use phpDocumentor\Reflection\Types\Object_;
20
use phpDocumentor\Reflection\Types\String_;
21
22
/**
23
 * Test class for \phpDocumentor\Plugin\Core\Transformer\Writer\Xml\TagConverter.
24
 *
25
 * @coversDefaultClass \phpDocumentor\Plugin\Core\Transformer\Writer\Xml\TagConverter
26
 */
27
class TagConverterTest extends \Mockery\Adapter\Phpunit\MockeryTestCase
28
{
29
    const TEST_LINENUMBER = 100;
30
31
    /**
32
     * Tests whether the information common to all tags is stored on an XML element.
33
     *
34
     * @param string $name              Name of the tag as provided by the Descriptor.
35
     * @param string $description       Description for the tag as provided by the Descriptor.
36
     * @param string $resultName        Expected resulting name in the XML Element.
37
     * @param string $resultDescription Expected resulting description in the XML Element.
38
     *
39
     * @dataProvider provideTestGenericTag
40
     * @covers ::convert
41
     * @covers ::getDescription
42
     *
43
     * @return void
44
     */
45
    public function testConvertGenericTag($name, $description, $resultName, $resultDescription)
46
    {
47
        // Arrange
48
        $tagConverter = new TagConverter();
49
        $parent       = $this->prepareDocBlockXMLElement();
50
        $tag          = $this->createTagDescriptorMock($name, $description);
51
52
        // Act
53
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript...ck($name, $description) on line 50 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
54
55
        // Assert
56
        $this->assertSame($resultName, $convertedElement->getAttribute('name'));
57
        $this->assertSame($resultDescription, $convertedElement->getAttribute('description'));
58
        $this->assertSame((string) self::TEST_LINENUMBER, $convertedElement->getAttribute('line'));
59
    }
60
61
    /**
62
     * Tests whether type information is stored when a tag is processed with compound type information.
63
     *
64
     * @covers ::convert
65
     * @covers ::addTypes
66
     *
67
     * @return void
68
     */
69
    public function testWhetherTypesAreAddedWhenPresentAndTypeIsCompound()
70
    {
71
        // Arrange
72
        $tagConverter = new TagConverter();
73
        $parent       = $this->prepareDocBlockXMLElement();
74
        $tag          = $this->createTagDescriptorMock('name', 'description', 'Tag\VarDescriptor');
75
        $tag->shouldReceive('getTypes')->andReturn(
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in phpDocumentor\Descriptor\TagDescriptor.

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...
76
            new Compound(array(new String_(), new Integer(), new Object_(new Fqsen('\DateTime'))))
77
        );
78
79
        // Act
80
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript..., 'Tag\\VarDescriptor') on line 74 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
81
82
        // Assert
83
        $types = $convertedElement->getElementsByTagName('type');
84
        $this->assertSame(3, $types->length);
85
        $this->assertSame('string', $types->item(0)->nodeValue);
86
        $this->assertSame('int', $types->item(1)->nodeValue);
87
        $this->assertSame('\DateTime', $types->item(2)->nodeValue);
88
        $this->assertSame('string|int|\DateTime', $convertedElement->getAttribute('type'));
89
    }
90
91
    /**
92
     * Tests whether type information is stored when a tag is processed with information of a single type.
93
     *
94
     * @covers ::convert
95
     * @covers ::addTypes
96
     *
97
     * @return void
98
     */
99
    public function testWhetherTypesAreAddedWhenPresentAndTypeIsSingular()
100
    {
101
        // Arrange
102
        $tagConverter = new TagConverter();
103
        $parent       = $this->prepareDocBlockXMLElement();
104
        $tag          = $this->createTagDescriptorMock('name', 'description', 'Tag\VarDescriptor');
105
        $tag->shouldReceive('getTypes')->andReturn(new String_());
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in phpDocumentor\Descriptor\TagDescriptor.

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...
106
107
        // Act
108
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript..., 'Tag\\VarDescriptor') on line 104 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
109
110
        // Assert
111
        $types = $convertedElement->getElementsByTagName('type');
112
        $this->assertSame(1, $types->length);
113
        $this->assertSame('string', $convertedElement->getAttribute('type'));
114
    }
115
116
    /**
117
     * Tests whether the variable name is stored for tags containing variable names.
118
     *
119
     * @covers ::convert
120
     * @covers ::addTypes
121
     *
122
     * @return void
123
     */
124
    public function testWhetherVariableNamesAreAddedWhenPresent()
125
    {
126
        // Arrange
127
        $tagConverter = new TagConverter();
128
        $parent       = $this->prepareDocBlockXMLElement();
129
        $tag          = $this->createTagDescriptorMock('name', 'description', 'Tag\VarDescriptor');
130
        $tag->shouldReceive('getTypes')->andReturn(null);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in phpDocumentor\Descriptor\TagDescriptor.

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...
131
        $tag->shouldReceive('getVariableName')->andReturn('varName');
132
133
        // Act
134
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript..., 'Tag\\VarDescriptor') on line 129 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
135
136
        // Assert
137
        $this->assertSame('varName', $convertedElement->getAttribute('variable'));
138
    }
139
140
    /**
141
     * Tests whether the version number is prepended to the description when version information is available.
142
     *
143
     * @covers ::convert
144
     * @covers ::getDescription
145
     *
146
     * @todo this should be dealt with in a template and not in the code! This activity should be removed and the
147
     * templates updated.
148
     *
149
     * @return void
150
     */
151
    public function testWhetherTheVersionIsPrependedToTheDescription()
152
    {
153
        // Arrange
154
        $tagConverter = new TagConverter();
155
        $parent       = $this->prepareDocBlockXMLElement();
156
        $tag          = $this->createTagDescriptorMock('name', 'description', 'Tag\VersionDescriptor');
157
        $tag->shouldReceive('getVersion')->andReturn('1.0');
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in phpDocumentor\Descriptor\TagDescriptor.

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...
158
159
        // Act
160
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript...ag\\VersionDescriptor') on line 156 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
161
162
        // Assert
163
        $this->assertSame('1.0 description', $convertedElement->getAttribute('description'));
164
    }
165
166
    /**
167
     * Tests whether a reference to another element is stored with the tag when such is present.
168
     *
169
     * @covers ::convert
170
     *
171
     * @return void
172
     */
173
    public function testWhetherReferencesAreAddedWhenPresent()
174
    {
175
        // Arrange
176
        $reference = '\DateTime::add()';
177
        $tagConverter = new TagConverter();
178
        $parent       = $this->prepareDocBlockXMLElement();
179
        $tag          = $this->createTagDescriptorMock('name', 'description', 'Tag\UsesDescriptor');
180
        $tag->shouldReceive('getReference')->andReturn($reference);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in phpDocumentor\Descriptor\TagDescriptor.

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...
181
182
        // Act
183
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript... 'Tag\\UsesDescriptor') on line 179 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
184
185
        // Assert
186
        $this->assertSame($reference, $convertedElement->getAttribute('link'));
187
    }
188
189
    /**
190
     * Tests whether a link to a URL is stored with the tag when such is present.
191
     *
192
     * @covers ::convert
193
     *
194
     * @return void
195
     */
196
    public function testWhetherLinksAreAddedWhenPresent()
197
    {
198
        // Arrange
199
        $link         = 'http://www.phpdoc.org';
200
        $tagConverter = new TagConverter();
201
        $parent       = $this->prepareDocBlockXMLElement();
202
        $tag          = $this->createTagDescriptorMock('name', 'description', 'Tag\LinkDescriptor');
203
        $tag->shouldReceive('getLink')->andReturn($link);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in phpDocumentor\Descriptor\TagDescriptor.

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...
204
205
        // Act
206
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript... 'Tag\\LinkDescriptor') on line 202 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
207
208
        // Assert
209
        $this->assertSame($link, $convertedElement->getAttribute('link'));
210
    }
211
212
    /**
213
     * Tests whether a method name to another element is stored with the tag when such is present.
214
     *
215
     * @covers ::convert
216
     *
217
     * @return void
218
     */
219
    public function testWhetherMethodNamesAreAddedWhenPresent()
220
    {
221
        // Arrange
222
        $methodName   = 'getMethod';
223
        $tagConverter = new TagConverter();
224
        $parent       = $this->prepareDocBlockXMLElement();
225
        $tag          = $this->createTagDescriptorMock('name', 'description', 'Tag\MethodDescriptor');
226
        $tag->shouldReceive('getMethodName')->andReturn($methodName);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in phpDocumentor\Descriptor\TagDescriptor.

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...
227
228
        // Act
229
        $convertedElement = $tagConverter->convert($parent, $tag);
0 ignored issues
show
Bug introduced by
It seems like $tag defined by $this->createTagDescript...Tag\\MethodDescriptor') on line 225 can also be of type object<Mockery\MockInterface>; however, phpDocumentor\Plugin\Cor...TagConverter::convert() does only seem to accept object<phpDocumentor\Descriptor\TagDescriptor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
230
231
        // Assert
232
        $this->assertSame($methodName, $convertedElement->getAttribute('method_name'));
233
    }
234
235
    /**
236
     * Provides a test name and description for the generic test.
237
     *
238
     * @see testConvertGenericTag
239
     *
240
     * @return string[][]
241
     */
242
    public function provideTestGenericTag()
243
    {
244
        return array(
245
            array('name', 'description', 'name', 'description'),
246
            array('name&test', 'description&test', 'name&amp;test', 'description&amp;test')
247
        );
248
    }
249
250
    /**
251
     * Creates an XML Element that can serve as parent.
252
     *
253
     * @return \DOMElement
254
     */
255
    protected function prepareDocBlockXMLElement()
256
    {
257
        $document = new \DOMDocument();
258
        $parent   = new \DOMElement('parent');
259
        $document->appendChild($parent);
260
        $parent->setAttribute('line', self::TEST_LINENUMBER);
261
262
        return $parent;
263
    }
264
265
    /**
266
     * Creates a mock for the TagDescriptor class.
267
     *
268
     * @param string $name        The name of the tag.
269
     * @param string $description The description that is present in the tag.
270
     * @param string $class       The descriptor class that is to be mocked
271
     *
272
     * @return m\MockInterface|TagDescriptor
273
     */
274
    protected function createTagDescriptorMock($name, $description, $class = 'TagDescriptor')
275
    {
276
        $tag = m::mock('phpDocumentor\\Descriptor\\' . $class);
277
        $tag->shouldReceive('getName')->andReturn($name);
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...
278
        $tag->shouldReceive('getDescription')->andReturn($description);
279
        $tag->shouldIgnoreMissing();
280
281
        return $tag;
282
    }
283
}
284