Completed
Pull Request — master (#393)
by
unknown
07:02
created

MethodGeneratorTest::testGenerateFromReflection()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 17
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ProxyManagerTest\Generator;
6
7
use PHPUnit\Framework\TestCase;
8
use ProxyManager\Generator\MethodGenerator;
9
use ProxyManagerTestAsset\BaseClass;
10
use ProxyManagerTestAsset\ClassWithAbstractPublicMethod;
11
use ProxyManagerTestAsset\EmptyClass;
12
use ProxyManagerTestAsset\ReturnTypeHintedClass;
13
use ProxyManagerTestAsset\ScalarTypeHintedClass;
14
use ProxyManagerTestAsset\VoidMethodTypeHintedInterface;
15
use stdClass;
16
use Zend\Code\Generator\ParameterGenerator;
17
use Zend\Code\Reflection\MethodReflection;
18
19
/**
20
 * Tests for {@see \ProxyManager\Generator\MethodGenerator}
21
 *
22
 * @author Marco Pivetta <[email protected]>
23
 * @license MIT
24
 *
25
 * @covers \ProxyManager\Generator\MethodGenerator
26
 * @group Coverage
27
 */
28
class MethodGeneratorTest extends TestCase
29
{
30
    public function testGeneratedMethodsAreAllConcrete() : void
31
    {
32
        $methodGenerator = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
33
            ClassWithAbstractPublicMethod::class,
34
            'publicAbstractMethod'
35
        ));
36
37
        self::assertFalse($methodGenerator->isInterface());
38
    }
39
40
    public function testGenerateSimpleMethod() : void
41
    {
42
        $methodGenerator = new MethodGenerator();
43
44
        $methodGenerator->setReturnsReference(true);
45
        $methodGenerator->setName('methodName');
46
        $methodGenerator->setVisibility('protected');
47
        $methodGenerator->setBody('/* body */');
48
        $methodGenerator->setDocBlock('docBlock');
49
        $methodGenerator->setParameter(new ParameterGenerator('foo'));
50
51
        self::assertStringMatchesFormat(
52
            '%a/**%adocBlock%a*/%aprotected function & methodName($foo)%a{%a/* body */%a}',
53
            $methodGenerator->generate()
54
        );
55
    }
56
57
    /**
58
     * Verify that building from reflection works
59
     */
60
    public function testGenerateFromReflection() : void
61
    {
62
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
63
            __CLASS__,
64
            __FUNCTION__
65
        ));
66
67
        self::assertSame(__FUNCTION__, $method->getName());
68
        self::assertSame(MethodGenerator::VISIBILITY_PUBLIC, $method->getVisibility());
69
        self::assertFalse($method->isStatic());
70
        self::assertNull($method->getDocBlock(), 'The docblock is ignored');
71
        self::assertNull($method->getBody(), 'The body is ignored');
72
73
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
74
            BaseClass::class,
75
            'protectedMethod'
76
        ));
77
78
        self::assertSame(MethodGenerator::VISIBILITY_PROTECTED, $method->getVisibility());
79
80
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
81
            BaseClass::class,
82
            'privateMethod'
83
        ));
84
85
        self::assertSame(MethodGenerator::VISIBILITY_PRIVATE, $method->getVisibility());
86
    }
87
88
    public function testGeneratedParametersFromReflection() : void
89
    {
90
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
91
            BaseClass::class,
92
            'publicTypeHintedMethod'
93
        ));
94
95
        self::assertSame('publicTypeHintedMethod', $method->getName());
96
97
        $parameters = $method->getParameters();
98
99
        self::assertCount(1, $parameters);
100
101
        $param = $parameters['param'];
102
103
        self::assertSame(stdClass::class, $param->getType());
104
    }
105
106
    /**
107
     * @param string $methodName
108
     * @param string $type
109
     *
110
     * @dataProvider scalarTypeHintedMethods
111
     */
112
    public function testGenerateMethodWithScalarTypeHinting(string $methodName, string $type) : void
113
    {
114
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
115
            ScalarTypeHintedClass::class,
116
            $methodName
117
        ));
118
119
        self::assertSame($methodName, $method->getName());
120
121
        $parameters = $method->getParameters();
122
123
        self::assertCount(1, $parameters);
124
125
        $param = $parameters['param'];
126
127
        self::assertSame($type, $param->getType());
128
    }
129
130
    public function scalarTypeHintedMethods()
131
    {
132
        return [
133
            ['acceptString', 'string'],
134
            ['acceptInteger', 'int'],
135
            ['acceptBoolean', 'bool'],
136
            ['acceptFloat', 'float'],
137
        ];
138
    }
139
140
    public function testGenerateMethodWithVoidReturnTypeHinting() : void
141
    {
142
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
143
            VoidMethodTypeHintedInterface::class,
144
            'returnVoid'
145
        ));
146
147
        self::assertSame('returnVoid', $method->getName());
148
        self::assertStringMatchesFormat('%a : void%a', $method->generate());
149
    }
150
151
    /**
152
     * @dataProvider returnTypeHintsProvider
153
     *
154
     * @param string $methodName
155
     * @param string $expectedType
156
     */
157
    public function testReturnTypeHintGeneration(string $methodName, string $expectedType) : void
158
    {
159
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
160
            ReturnTypeHintedClass::class,
161
            $methodName
162
        ));
163
164
        self::assertSame($methodName, $method->getName());
165
        self::assertStringMatchesFormat('%a : ' . $expectedType . '%a', $method->generate());
166
    }
167
168
    /**
169
     * @return string[][]
170
     */
171
    public function returnTypeHintsProvider() : array
172
    {
173
        return [
174
            ['returnString', 'string'],
175
            ['returnInteger', 'int'],
176
            ['returnBool', 'bool'],
177
            ['returnArray', 'array'],
178
            ['returnCallable', 'callable'],
179
            ['returnSelf', '\\' . ReturnTypeHintedClass::class],
180
            ['returnParent', '\\' . EmptyClass::class],
181
            ['returnVoid', 'void'],
182
            ['returnIterable', 'iterable'],
183
            ['returnSameClass', '\\' . ReturnTypeHintedClass::class],
184
            ['returnOtherClass', '\\' . EmptyClass::class],
185
        ];
186
    }
187
}
188