Completed
Push — master ( f1e5e5...9f8061 )
by Marco
07:19
created

MethodGeneratorTest::testGenerateFromReflection()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 29
rs 8.8571
cc 1
eloc 19
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
        self::assertNull($method->getSourceContent(), 'The source content ignored');
73
        self::assertTrue($method->isSourceDirty(), 'Dirty because the source cannot just be re-used when generating');
74
75
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
76
            BaseClass::class,
77
            'protectedMethod'
78
        ));
79
80
        self::assertSame(MethodGenerator::VISIBILITY_PROTECTED, $method->getVisibility());
81
82
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
83
            BaseClass::class,
84
            'privateMethod'
85
        ));
86
87
        self::assertSame(MethodGenerator::VISIBILITY_PRIVATE, $method->getVisibility());
88
    }
89
90
    public function testGeneratedParametersFromReflection() : void
91
    {
92
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
93
            BaseClass::class,
94
            'publicTypeHintedMethod'
95
        ));
96
97
        self::assertSame('publicTypeHintedMethod', $method->getName());
98
99
        $parameters = $method->getParameters();
100
101
        self::assertCount(1, $parameters);
102
103
        $param = $parameters['param'];
104
105
        self::assertSame(stdClass::class, $param->getType());
106
    }
107
108
    /**
109
     * @param string $methodName
110
     * @param string $type
111
     *
112
     * @dataProvider scalarTypeHintedMethods
113
     */
114
    public function testGenerateMethodWithScalarTypeHinting(string $methodName, string $type) : void
115
    {
116
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
117
            ScalarTypeHintedClass::class,
118
            $methodName
119
        ));
120
121
        self::assertSame($methodName, $method->getName());
122
123
        $parameters = $method->getParameters();
124
125
        self::assertCount(1, $parameters);
126
127
        $param = $parameters['param'];
128
129
        self::assertSame($type, $param->getType());
130
    }
131
132
    public function scalarTypeHintedMethods()
133
    {
134
        return [
135
            ['acceptString', 'string'],
136
            ['acceptInteger', 'int'],
137
            ['acceptBoolean', 'bool'],
138
            ['acceptFloat', 'float'],
139
        ];
140
    }
141
142
    public function testGenerateMethodWithVoidReturnTypeHinting() : void
143
    {
144
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
145
            VoidMethodTypeHintedInterface::class,
146
            'returnVoid'
147
        ));
148
149
        self::assertSame('returnVoid', $method->getName());
150
        self::assertStringMatchesFormat('%a : void%a', $method->generate());
151
    }
152
153
    /**
154
     * @dataProvider returnTypeHintsProvider
155
     *
156
     * @param string $methodName
157
     * @param string $expectedType
158
     */
159
    public function testReturnTypeHintGeneration(string $methodName, string $expectedType) : void
160
    {
161
        $method = MethodGenerator::fromReflectionWithoutBodyAndDocBlock(new MethodReflection(
162
            ReturnTypeHintedClass::class,
163
            $methodName
164
        ));
165
166
        self::assertSame($methodName, $method->getName());
167
        self::assertStringMatchesFormat('%a : ' . $expectedType . '%a', $method->generate());
168
    }
169
170
    /**
171
     * @return string[][]
172
     */
173
    public function returnTypeHintsProvider() : array
174
    {
175
        return [
176
            ['returnString', 'string'],
177
            ['returnInteger', 'int'],
178
            ['returnBool', 'bool'],
179
            ['returnArray', 'array'],
180
            ['returnCallable', 'callable'],
181
            ['returnSelf', '\\' . ReturnTypeHintedClass::class],
182
            ['returnParent', '\\' . EmptyClass::class],
183
            ['returnVoid', 'void'],
184
            ['returnIterable', 'iterable'],
185
            ['returnSameClass', '\\' . ReturnTypeHintedClass::class],
186
            ['returnOtherClass', '\\' . EmptyClass::class],
187
        ];
188
    }
189
}
190