Completed
Push — master ( c89193...79c6c8 )
by Kyle
11:15 queued 10s
created

getFirstPreIncrementExpressionInClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of PDepend.
4
 *
5
 * PHP Version 5
6
 *
7
 * Copyright (c) 2008-2017 Manuel Pichler <[email protected]>.
8
 * All rights reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 *
14
 *   * Redistributions of source code must retain the above copyright
15
 *     notice, this list of conditions and the following disclaimer.
16
 *
17
 *   * Redistributions in binary form must reproduce the above copyright
18
 *     notice, this list of conditions and the following disclaimer in
19
 *     the documentation and/or other materials provided with the
20
 *     distribution.
21
 *
22
 *   * Neither the name of Manuel Pichler nor the names of his
23
 *     contributors may be used to endorse or promote products derived
24
 *     from this software without specific prior written permission.
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
 * POSSIBILITY OF SUCH DAMAGE.
38
 *
39
 * @copyright 2008-2017 Manuel Pichler. All rights reserved.
40
 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
41
 */
42
43
namespace PDepend\Source\AST;
44
45
/**
46
 * Test case for the {@link \PDepend\Source\AST\ASTPreIncrementExpression} class.
47
 *
48
 * @copyright 2008-2017 Manuel Pichler. All rights reserved.
49
 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
50
 *
51
 * @covers \PDepend\Source\Language\PHP\AbstractPHPParser
52
 * @covers \PDepend\Source\Language\PHP\PHPBuilder
53
 * @covers \PDepend\Source\AST\ASTPreIncrementExpression
54
 * @group unittest
55
 */
56
class ASTPreIncrementExpressionTest extends ASTNodeTest
57
{
58
    /**
59
     * testPreIncrementExpressionOnStaticClassMember
60
     *
61
     * @return void
62
     */
63 View Code Duplication
    public function testPreIncrementExpressionOnStaticClassMember()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
    {
65
        $expr = $this->getFirstPreIncrementExpressionInFunction(__METHOD__);
66
        $this->assertGraphEquals(
67
            $expr,
68
            array(
69
                'PDepend\\Source\\AST\\ASTMemberPrimaryPrefix',
70
                'PDepend\\Source\\AST\\ASTClassOrInterfaceReference',
71
                'PDepend\\Source\\AST\\ASTPropertyPostfix',
72
                'PDepend\\Source\\AST\\ASTVariable'
73
            )
74
        );
75
    }
76
77
    /**
78
     * testPreIncrementExpressionOnSelfClassMember
79
     *
80
     * @return void
81
     */
82 View Code Duplication
    public function testPreIncrementExpressionOnSelfClassMember()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
    {
84
        $expr = $this->getFirstPreIncrementExpressionInClass(__METHOD__);
85
        $this->assertGraphEquals(
86
            $expr,
87
            array(
88
                'PDepend\\Source\\AST\\ASTMemberPrimaryPrefix',
89
                'PDepend\\Source\\AST\\ASTSelfReference',
90
                'PDepend\\Source\\AST\\ASTPropertyPostfix',
91
                'PDepend\\Source\\AST\\ASTVariable'
92
            )
93
        );
94
    }
95
96
    /**
97
     * testPreIncrementExpressionOnParentClassMember
98
     *
99
     * @return void
100
     */
101 View Code Duplication
    public function testPreIncrementExpressionOnParentClassMember()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
    {
103
        $expr = $this->getFirstPreIncrementExpressionInClass(__METHOD__);
104
        $this->assertGraphEquals(
105
            $expr,
106
            array(
107
                'PDepend\\Source\\AST\\ASTMemberPrimaryPrefix',
108
                'PDepend\\Source\\AST\\ASTParentReference',
109
                'PDepend\\Source\\AST\\ASTPropertyPostfix',
110
                'PDepend\\Source\\AST\\ASTVariable'
111
            )
112
        );
113
    }
114
115
    /**
116
     * testPreIncrementExpressionOnFunctionPostfix
117
     *
118
     * @return void
119
     */
120
    public function testPreIncrementExpressionOnFunctionPostfix()
121
    {
122
        $expr = $this->getFirstPreIncrementExpressionInFunction(__METHOD__);
123
        $this->assertGraphEquals(
124
            $expr,
125
            array(
126
                'PDepend\\Source\\AST\\ASTFunctionPostfix',
127
                'PDepend\\Source\\AST\\ASTIdentifier',
128
                'PDepend\\Source\\AST\\ASTArguments'
129
            )
130
        );
131
    }
132
133
    /**
134
     * testPreIncrementExpressionOnStaticVariableMember
135
     *
136
     * @return void
137
     */
138 View Code Duplication
    public function testPreIncrementExpressionOnStaticVariableMember()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
    {
140
        $expr = $this->getFirstPreIncrementExpressionInFunction(__METHOD__);
141
        $this->assertGraphEquals(
142
            $expr,
143
            array(
144
                'PDepend\\Source\\AST\\ASTMemberPrimaryPrefix',
145
                'PDepend\\Source\\AST\\ASTVariable',
146
                'PDepend\\Source\\AST\\ASTPropertyPostfix',
147
                'PDepend\\Source\\AST\\ASTVariable'
148
            )
149
        );
150
    }
151
152
    /**
153
     * testPreIncrementExpressionsInArithmeticOperation
154
     *
155
     * @return void
156
     */
157
    public function testPreIncrementExpressionsInArithmeticOperation()
158
    {
159
        $exprs = $this->getFirstClassForTestCase()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PDepend\Source\AST\ASTArtifact as the method findChildrenOfType() does only exist in the following implementations of said interface: PDepend\Source\AST\ASTAnonymousClass, PDepend\Source\AST\ASTClass, PDepend\Source\AST\ASTFunction, PDepend\Source\AST\ASTInterface, PDepend\Source\AST\ASTMethod, PDepend\Source\AST\ASTTrait, PDepend\Source\AST\AbstractASTCallable, PDepend\Source\AST\AbstractASTClassOrInterface, PDepend\Source\AST\AbstractASTType.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
160
            ->getMethods()
161
            ->current()
162
            ->findChildrenOfType('PDepend\\Source\\AST\\ASTPreIncrementExpression');
163
164
        $this->assertEquals(2, count($exprs));
165
    }
166
167
    /**
168
     * testPreIncrementExpressionHasExpectedStartLine
169
     *
170
     * @return void
171
     */
172
    public function testPreIncrementExpressionHasExpectedStartLine()
173
    {
174
        $expr = $this->getFirstPreIncrementExpressionInFunction(__METHOD__);
175
        $this->assertEquals(4, $expr->getStartLine());
176
    }
177
178
    /**
179
     * testPreIncrementExpressionHasExpectedStartColumn
180
     *
181
     * @return void
182
     */
183
    public function testPreIncrementExpressionHasExpectedStartColumn()
184
    {
185
        $expr = $this->getFirstPreIncrementExpressionInFunction(__METHOD__);
186
        $this->assertEquals(13, $expr->getStartColumn());
187
    }
188
189
    /**
190
     * testPreIncrementExpressionHasExpectedEndLine
191
     *
192
     * @return void
193
     */
194
    public function testPreIncrementExpressionHasExpectedEndLine()
195
    {
196
        $expr = $this->getFirstPreIncrementExpressionInFunction(__METHOD__);
197
        $this->assertEquals(4, $expr->getEndLine());
198
    }
199
200
    /**
201
     * testPreIncrementExpressionHasExpectedEndColumn
202
     *
203
     * @return void
204
     */
205
    public function testPreIncrementExpressionHasExpectedEndColumn()
206
    {
207
        $expr = $this->getFirstPreIncrementExpressionInFunction(__METHOD__);
208
        $this->assertEquals(20, $expr->getEndColumn());
209
    }
210
211
    /**
212
     * Returns a node instance for the currently executed test case.
213
     *
214
     * @param string $testCase Name of the calling test case.
215
     * @return \PDepend\Source\AST\ASTPreIncrementExpression
216
     */
217
    private function getFirstPreIncrementExpressionInClass($testCase)
218
    {
219
        return $this->getFirstNodeOfTypeInClass(
220
            $testCase,
221
            'PDepend\\Source\\AST\\ASTPreIncrementExpression'
222
        );
223
    }
224
225
    /**
226
     * Returns a node instance for the currently executed test case.
227
     *
228
     * @param string $testCase Name of the calling test case.
229
     * @return \PDepend\Source\AST\ASTPreIncrementExpression
230
     */
231
    private function getFirstPreIncrementExpressionInFunction($testCase)
232
    {
233
        return $this->getFirstNodeOfTypeInFunction(
234
            $testCase,
235
            'PDepend\\Source\\AST\\ASTPreIncrementExpression'
236
        );
237
    }
238
}
239