Passed
Push — master ( 45de3b...609c6b )
by Marc
07:50 queued 04:15
created

TooManyPublicMethodsTest::testRuleIgnoresHassers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 8
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 8
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of PHP Mess Detector.
4
 *
5
 * Copyright (c) Manuel Pichler <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * Licensed under BSD License
9
 * For full copyright and license information, please see the LICENSE file.
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @author Manuel Pichler <[email protected]>
13
 * @copyright Manuel Pichler. All rights reserved.
14
 * @license https://opensource.org/licenses/bsd-license.php BSD License
15
 * @link http://phpmd.org/
16
 */
17
18
namespace PHPMD\Rule\Design;
19
20
use PDepend\Source\AST\ASTMethod;
21
use PDepend\Source\AST\State;
22
use PHPMD\AbstractTest;
23
use PHPMD\Node\MethodNode;
24
25
/**
26
 * Test case for the too many public methods rule.
27
 *
28
 * @covers \PHPMD\Rule\Design\TooManyPublicMethods
29
 */
30
class TooManyPublicMethodsTest extends AbstractTest
31
{
32
    /**
33
     * @return void
34
     */
35
    public function testRuleDoesNotApplyToClassesWithLessMethodsThanThreshold()
36
    {
37
        $rule = new TooManyPublicMethods();
38
        $rule->setReport($this->getReportMock(0));
39
        $rule->addProperty('maxmethods', '42');
40
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
41
        $rule->apply($this->createClassMock(23));
42
    }
43
44
    /**
45
     * @return void
46
     */
47
    public function testRuleDoesNotApplyToClassesWithSameNumberOfMethodsAsThreshold()
48
    {
49
        $rule = new TooManyPublicMethods();
50
        $rule->setReport($this->getReportMock(0));
51
        $rule->addProperty('maxmethods', '42');
52
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
53
        $rule->apply($this->createClassMock(42));
54
    }
55
56
    /**
57
     * @return void
58
     */
59
    public function testRuleAppliesToClassesWithMoreMethodsThanThreshold()
60
    {
61
        $rule = new TooManyPublicMethods();
62
        $rule->setReport($this->getReportMock(1));
63
        $rule->addProperty('maxmethods', '23');
64
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
65
        $rule->apply($this->createClassMock(42, array_fill(0, 42, __FUNCTION__)));
66
    }
67
68
    /**
69
     * @return void
70
     */
71 View Code Duplication
    public function testRuleIgnoresGetterMethodsInTest()
72
    {
73
        $rule = new TooManyPublicMethods();
74
        $rule->setReport($this->getReportMock(0));
75
        $rule->addProperty('maxmethods', '1');
76
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
77
        $rule->apply($this->createClassMock(2, array('invoke', 'getClass')));
78
    }
79
80
    /**
81
     * @return void
82
     */
83 View Code Duplication
    public function testRuleIgnoresSetterMethodsInTest()
84
    {
85
        $rule = new TooManyPublicMethods();
86
        $rule->setReport($this->getReportMock(0));
87
        $rule->addProperty('maxmethods', '1');
88
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
89
        $rule->apply($this->createClassMock(2, array('invoke', 'setClass')));
90
    }
91
92
    /**
93
     * @return void
94
     */
95 View Code Duplication
    public function testRuleIgnoresCustomMethodsWhenRegexPropertyIsGiven()
96
    {
97
        $rule = new TooManyPublicMethods();
98
        $rule->setReport($this->getReportMock(0));
99
        $rule->addProperty('maxmethods', '1');
100
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
101
        $rule->apply($this->createClassMock(2, array('invoke', 'injectClass')));
102
    }
103
104
    /**
105
     * @return void
106
     */
107 View Code Duplication
    public function testRuleIgnoresGetterAndSetterMethodsInTest()
108
    {
109
        $rule = new TooManyPublicMethods();
110
        $rule->setReport($this->getReportMock(0));
111
        $rule->addProperty('maxmethods', '2');
112
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
113
        $rule->apply($this->createClassMock(3, array('foo', 'bar'), array('baz', 'bah')));
114
    }
115
116
    /**
117
     * @return void
118
     */
119 View Code Duplication
    public function testRuleIgnoresPrivateMethods()
120
    {
121
        $rule = new TooManyPublicMethods();
122
        $rule->setReport($this->getReportMock(0));
123
        $rule->addProperty('maxmethods', '2');
124
        $rule->addProperty('ignorepattern', '(^(set|get|inject))i');
125
        $rule->apply($this->createClassMock(2, array('invoke', 'getClass', 'setClass')));
126
    }
127
128
    /**
129
     * @return void
130
     */
131 View Code Duplication
    public function testRuleIgnoresHassers()
132
    {
133
        $rule = new TooManyPublicMethods();
134
        $rule->setReport($this->getReportMock(0));
135
        $rule->addProperty('maxmethods', '1');
136
        $rule->addProperty('ignorepattern', '(^(set|get|is|has|with))i');
137
        $rule->apply($this->createClassMock(2, array('invoke', 'hasClass')));
138
    }
139
140
    /**
141
     * @return void
142
     */
143 View Code Duplication
    public function testRuleIgnoresIssers()
144
    {
145
        $rule = new TooManyPublicMethods();
146
        $rule->setReport($this->getReportMock(0));
147
        $rule->addProperty('maxmethods', '1');
148
        $rule->addProperty('ignorepattern', '(^(set|get|is|has|with))i');
149
        $rule->apply($this->createClassMock(2, array('invoke', 'isClass')));
150
    }
151
152
    /**
153
     * @return void
154
     */
155 View Code Duplication
    public function testRuleIgnoresWithers()
156
    {
157
        $rule = new TooManyPublicMethods();
158
        $rule->setReport($this->getReportMock(0));
159
        $rule->addProperty('maxmethods', '1');
160
        $rule->addProperty('ignorepattern', '(^(set|get|is|has|with))i');
161
        $rule->apply($this->createClassMock(2, array('invoke', 'withClass')));
162
    }
163
164
    /**
165
     * Creates a prepared class node mock
166
     *
167
     * @param integer $numberOfMethods
168
     * @param array|null $publicMethods
169
     * @param array|null $privateMethods
170
     * @return \PHPMD\Node\ClassNode
171
     */
172
    private function createClassMock($numberOfMethods, array $publicMethods = array(), array $privateMethods = array())
173
    {
174
        $class = $this->getClassMock('npm', $numberOfMethods);
175
176
        $class->expects($this->any())
0 ignored issues
show
Documentation Bug introduced by
The method expects does not exist on object<PHPMD\Node\ClassNode>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
177
            ->method('getMethods')
178
            ->will($this->returnValue(array_merge(
179
                array_map(array($this, 'createPublicMethod'), $publicMethods),
180
                array_map(array($this, 'createPrivateMethod'), $privateMethods)
181
            )));
182
183
        return $class;
184
    }
185
186
    private function createPublicMethod($methodName)
187
    {
188
        $astMethod = new ASTMethod($methodName);
189
        $astMethod->setModifiers(State::IS_PUBLIC);
190
        return new MethodNode($astMethod);
191
    }
192
193
    private function createPrivateMethod($methodName)
194
    {
195
        $astMethod = new ASTMethod($methodName);
196
        return new MethodNode($astMethod);
197
    }
198
}
199