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

LazyLoadingGhostFactoryTest   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

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