Completed
Push — master ( 3be072...ba2d3a )
by Marco
231:32 queued 209:55
created

LazyLoadingValueHolderFactoryTest   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 4
lcom 1
cbo 4
dl 0
loc 153
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ProxyManagerTest\Factory;
6
7
use PHPUnit\Framework\MockObject\MockObject;
8
use PHPUnit\Framework\TestCase;
9
use ProxyManager\Autoloader\AutoloaderInterface;
10
use ProxyManager\Configuration;
11
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
12
use ProxyManager\Generator\ClassGenerator;
13
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
14
use ProxyManager\GeneratorStrategy\GeneratorStrategyInterface;
15
use ProxyManager\Inflector\ClassNameInflectorInterface;
16
use ProxyManager\Signature\ClassSignatureGeneratorInterface;
17
use ProxyManager\Signature\SignatureCheckerInterface;
18
use ProxyManagerTest\Assert;
19
use ProxyManagerTestAsset\EmptyClass;
20
use ProxyManagerTestAsset\LazyLoadingMock;
21
use function get_class;
22
23
/**
24
 * Tests for {@see \ProxyManager\Factory\LazyLoadingValueHolderFactory}
25
 *
26
 * @group Coverage
27
 */
28
final class LazyLoadingValueHolderFactoryTest extends TestCase
29
{
30
    /** @var ClassNameInflectorInterface&MockObject */
31
    private ClassNameInflectorInterface $inflector;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
32
33
    /** @var SignatureCheckerInterface&MockObject */
34
    private SignatureCheckerInterface $signatureChecker;
35
36
    /** @var ClassSignatureGeneratorInterface&MockObject */
37
    private ClassSignatureGeneratorInterface $classSignatureGenerator;
38
39
    /** @var Configuration&MockObject */
40
    private Configuration $config;
41
42
    /**
43
     * {@inheritDoc}
44
     */
45
    protected function setUp() : void
46
    {
47
        $this->config                  = $this->createMock(Configuration::class);
48
        $this->inflector               = $this->createMock(ClassNameInflectorInterface::class);
49
        $this->signatureChecker        = $this->createMock(SignatureCheckerInterface::class);
50
        $this->classSignatureGenerator = $this->createMock(ClassSignatureGeneratorInterface::class);
51
52
        $this
53
            ->config
54
            ->method('getClassNameInflector')
55
            ->willReturn($this->inflector);
56
57
        $this
58
            ->config
59
            ->method('getSignatureChecker')
60
            ->willReturn($this->signatureChecker);
61
62
        $this
63
            ->config
64
            ->method('getClassSignatureGenerator')
65
            ->willReturn($this->classSignatureGenerator);
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     *
71
     * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::__construct
72
     */
73
    public static function testWithOptionalFactory() : void
74
    {
75
        $factory = new LazyLoadingValueHolderFactory();
76
77
        $configuration = Assert::readAttribute($factory, 'configuration');
78
79
        self::assertNotEmpty($configuration);
80
        self::assertInstanceOf(Configuration::class, $configuration);
81
    }
82
83
    /**
84
     * {@inheritDoc}
85
     *
86
     * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::__construct
87
     * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::createProxy
88
     */
89
    public function testWillSkipAutoGeneration() : void
90
    {
91
        $className = UniqueIdentifierGenerator::getIdentifier('foo');
92
93
        $this
94
            ->inflector
95
            ->expects(self::once())
96
            ->method('getProxyClassName')
97
            ->with($className)
98
            ->willReturn(LazyLoadingMock::class);
99
100
        $factory     = new LazyLoadingValueHolderFactory($this->config);
101
        $initializer = static function () : void {
102
        };
103
        /** @var LazyLoadingMock $proxy */
104
        $proxy = $factory->createProxy($className, $initializer);
105
106
        self::assertInstanceOf(LazyLoadingMock::class, $proxy);
107
        self::assertSame($initializer, $proxy->initializer);
108
    }
109
110
    /**
111
     * {@inheritDoc}
112
     *
113
     * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::__construct
114
     * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::createProxy
115
     * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::getGenerator
116
     *
117
     * NOTE: serious mocking going on in here (a class is generated on-the-fly) - careful
118
     */
119
    public function testWillTryAutoGeneration() : void
120
    {
121
        $className      = UniqueIdentifierGenerator::getIdentifier('foo');
122
        $proxyClassName = UniqueIdentifierGenerator::getIdentifier('bar');
123
        $generator      = $this->createMock(GeneratorStrategyInterface::class);
124
        $autoloader     = $this->createMock(AutoloaderInterface::class);
125
126
        $this->config->method('getGeneratorStrategy')->will(self::returnValue($generator));
127
        $this->config->method('getProxyAutoloader')->will(self::returnValue($autoloader));
128
129
        $generator
130
            ->expects(self::once())
131
            ->method('generate')
132
            ->with(
133
                self::callback(
134
                    static function (ClassGenerator $targetClass) use ($proxyClassName) : bool {
135
                        return $targetClass->getName() === $proxyClassName;
136
                    }
137
                )
138
            );
139
140
        // simulate autoloading
141
        $autoloader
142
            ->expects(self::once())
143
            ->method('__invoke')
144
            ->with($proxyClassName)
145
            ->willReturnCallback(static function () use ($proxyClassName) : bool {
146
                eval('class ' . $proxyClassName . ' extends \\ProxyManagerTestAsset\\LazyLoadingMock {}');
147
148
                return true;
149
            });
150
151
        $this
152
            ->inflector
153
            ->expects(self::once())
154
            ->method('getProxyClassName')
155
            ->with($className)
156
            ->willReturn($proxyClassName);
157
158
        $this
159
            ->inflector
160
            ->expects(self::once())
161
            ->method('getUserClassName')
162
            ->with($className)
163
            ->willReturn(EmptyClass::class);
164
165
        $this->signatureChecker->expects(self::atLeastOnce())->method('checkSignature');
166
        $this->classSignatureGenerator->expects(self::once())->method('addSignature')->will(self::returnArgument(0));
167
168
        $factory     = new LazyLoadingValueHolderFactory($this->config);
169
        $initializer = static function () : void {
170
        };
171
        /** @var LazyLoadingMock $proxy */
172
        $proxy = $factory->createProxy($className, $initializer);
173
174
        /** @noinspection UnnecessaryAssertionInspection */
175
        self::assertInstanceOf($proxyClassName, $proxy);
176
177
        self::assertSame($proxyClassName, get_class($proxy));
178
        self::assertSame($initializer, $proxy->initializer);
179
    }
180
}
181